📜 ⬆️ ⬇️

NemerleWeb - Unique Web Framework

NemerleWeb NemerleWeb is a framework for creating single-page web applications (Single Page Application - SPA), which translates Nemerle code into a mix of JavaScript and HTML, and also provides two-way data binding, transparent duplex communication with the server, static typing with real tips and many more what else.

How it works?


The developer describes the logic of the models in the Nemerle compiled language.
Thanks to macros, the code in this language is very concise, in fact, we only describe the logic of the application. This distinguishes our solution from libraries in pure JavaScript.

Most models contain one or more HTML templates with which two-way data binding is performed. Binding, like the rest of the code, looks very simple:

<input value=”$Name” /> 

It is enough to put the first $ in the attribute, and the attribute will be calculated automatically, based on the following code.
In this code, by the way, almost any expressions are allowed - the main thing is that these expressions fit in the resulting HTML.
')
Further, from the created model, * .js files and templates are generated, and the whole thing is inserted into your static page.

Model description is a single file inside an ordinary ASP.NET MVC project.

Show me the code!


The code for the simplest model looks like this:

 [Unit] public class Page { Name : string = "world"; [Html] public View() : string { <# <input value=”$Name” /> <div>Hello, $Name</div> #> } } 

Watch: Result , Source Code

This will generate a JavaScript “class” Page and an HTML Page_View template, which includes primitives for automatic two-way data binding.

The [Unit] attribute marks the classes from which the client side code should be created, and the [Html] methods that we want to turn into templates.

I already have a ready site on C #


If you have a ready site to which you do not want to drag Nemerle, you can create a separate project on Nemerle, the model from which you insert into the main site in C # in this way:

 public ActionResult PageWithModel() { return View("Index", (object)NemerleProject.MyModel.Render()); } 

The static Render method will be automatically generated by the compiler for any model you create. In this method, by the way, you can pass parameters with which the client-side constructor will be called later.

Why Nemerle and NemerleWeb?


The fact is that Nemerle has a very developed infrastructure for creating macros. The developer is allowed to intervene in many stages of the compilation and, if necessary, make his own changes.
It was metaprogramming that made it possible to create a framework with a very laconic structure and with almost unlimited possibilities. And since Nemerle is also statically typed, we get intelligence and a basic check for typos for free.

Task list


To demonstrate the possibilities, I chose a typical ToDo list, but with advanced features. Our list will automatically save changes to the server, while notifying other clients about the update via SignalR.

Tasks will be sorted by priority using LINQ. By the way, they can be used directly from the template.

To communicate the server with the client, we use SignalR, which is already the standard for this kind of solutions in ASP.NET.

 //       [Unit]    JavaScript, //    Server,     // ASP.NET MVC Controller [Unit] public class ReactiveToDo { //  [Dto]     public mutable. //    [Record],   , //     [Dto] public class Task { Name : string; IsDone : bool; Priority : string; } //       [Unit]        Server,    . //  Nemerle         C#. //    ,      mutable. mutable _tasks = List.[Task](); mutable _todoName = "New task"; mutable _todoPriority = "high"; public this() { //  server  ,    Unit //   Server (. ) //    Load()  callback, //   . //     Load ,  callback -   . //      XMLHttpRequest //         . _ = server.Load(tasks => SetTasks(tasks)); } //          SignalR, //         SetTasks(tasks : List[Task]) : void { _tasks = tasks; } Add() : void { _tasks.Add(Task(_todoName, false, _todoPriority)); SaveToServer(); _todoName = "Task #" + _tasks.Count; _todoPriority = "high"; } SaveToServer() : void { //  Save   List[Task],     //     . //         , //      ,   //  window.console.log    JavaScript . _ = server.Save(_tasks, status => window.console.log(status)) } //         . //   ,     LINQ, //     linq.js // <# #> -  C#   @””,     . //     : <# <# a #> #> . [Html] public View() : string { <# <table class="reactive-todo-table"> <tr> <th>Priority</th><th>Task</th><th>Status</th> </tr> <tr $foreach(task in _tasks.OrderBy(t => t.Priority))> <td>$(task.Priority)</td> <td>$(task.Name)</td> <td><input type="checkbox" event-change="$SaveToServer" checked="$(task.IsDone)" /></td> </tr> </table> <div> <input value="$_todoName" /> <select value="$_todoPriority"> <option>high</option> <option>low</option> </select> <button click="$Add">Add</button> </div> #> } //       ASP.NET MVC //        , //         ,  //     . //  [SignalR]    Server, //       broadcast  signal (. ) [SignalR] public class Server { //     . //          . static mutable _db : List[Task] = List(); static this() { _db.Add(Task("Write article", false, "high")); _db.Add(Task("Fix website bugs", false, "high")); _db.Add(Task("Add new functionality", false, "low")); } public Load() : List[Task] { // Nemerle    return    //      "  " _db } //     . //        'void'. public Save(tasks : List[Task]) : string { _db = tasks; //    SignalR.  ,    //    .      //  client,        //  . //    . //  broadcast   SetTasks   . //      signal,   //           broadcast client.SetTasks(_db); //  ,   : "ok" } } } 

Watch: Result , Source Code
An example cleared of comments: gist

Note: Open the page in two tabs at the same time to see how the data is updated automatically.

Retreat


The purpose of this publication is not to encourage people to use NemerleWeb in production, but rather to tell about the project and, perhaps, find like-minded people. In our humble opinion, the Nemerle macrosystem allows you to do things that were simply not available in web development before, so we got carried away with this venture. We hope very much that in the end it will be possible to make a slender reliable framework out of this.

Conclusion


On this first time to complete the article.

In the following parts we will tell about:


Links


Project website: www.nemerleweb.com
Repository: https://github.com/NemerleWeb/NemerleWeb

Source: https://habr.com/ru/post/239421/


All Articles