📜 ⬆️ ⬇️

WidLib - declarative js framework for building widgets

Today I would like to announce a js framework that allows you to create interactive micro-applications with several lines of js-code shared between the client and the server.

Unfortunately, the author of the project did not have the courage to bring it to mind. Sorry.


')
The idea of ​​a simple, convenient and specialized for interactive solutions framework was born after several years of our team working with interactive applications. We wanted to create a simple constructor of interactive widgets, not overloaded with complex functions and sharpened as much as possible for a specific task. As a result, we came to the decision to reshape our achievements and slightly change the concept of the product.

Unlike most frameworks, WidLib does not claim to be universal: it is designed to quickly create multi-page interactive applications.

Range of tasks
  1. Delivery order widgets
  2. Wi-Fi applications (shopping center guide or interactive menu when connected to local Wi-Fi)
  3. Calculators (loans, plastic windows and doors)
  4. Subscription forms on the site
  5. Quizzes (games, as well as for marketing campaigns and practical jokes)
  6. Tests (competency check, training, work with personnel)
  7. Online helpers (for example, choosing a tourist route or call center assistant)
  8. Embedding widgets in mobile apps (here it looks like PhoneGap)
  9. Interactive applications for social networks (again, quizzes, non-linear surveys)
  10. Booking (plane tickets, hotel room or time at the dentist)
  11. etc.

To create DSL, we asked ourselves how we want to see an extremely simple, but at the same time flexible language for describing (and, to a lesser extent, programming) these interactive applications. We used the convention over configuration approach familiar to Ruby on Rails. Simple applications are written in three lines, complex - a little more.
Let's look at the example of a widget for ordering pizza on the site:
(DSL is still being finalized, so suggestions are welcome.)
Coffeescript
widlib=require("widlib-server") server=widlib.init #     (index_template=Handlebars.compile("...")), #     ,    @app.template template: index_template pages: type: #         template: type_template # @app.pages["type"].template body: " " #       submit,      (   ) #       onLeave, onEnter inputs: [ { value: "", type: "link", name: "type", price: 350 }, { value: "", type: "link", name: "type", price: 360 }, { value: "", type: "link", name: "type", price: 370 }, { value: " ", type: "link", name: "type", price: 380 }, ] size: body: " " #      -    inputs: -> price = @session.input("type").price # session -    . @session.input("type")     type. [ { value: "30", type: "link", name: "size", price: price }, { value: "40", type: "link", name: "size", price: price*1.2 }, { value: "50", type: "link", name: "size", price: price*1.5 }, ] #           onSubmit: "address" address: body: " " inputs: [ { name: "address", type: "text", placeholder: ", , , " }, { type: "submit", value: "" } ] phone: body: " " inputs: [ { name: "phone", type: "text", placeholder: "+7 xxx xx xx" }, { type: "submit", value: "" }] onSubmit: -> #     onLoad, on @data("orders").push @session.values() #      @data("email").push email_template(@session.values()) "success" #     success: body: "     " image: -> "/images/#{@session.value("type")}.jpg" #    ,    image  view data: orders: type: "spreadsheet" #     API         url: "https://docs.google.com/spreadsheet/ccc?key=0Au4e-jj1-69ZdEloMW03UExKLXIZFSUE" email: type: "email" to: "1@interactiff.net" server.listen "3000" 

Code without comment
 widlib=require("widlib-server") server=widlib.init template: index_template pages: type: template: type_template body: " " inputs: [ { value: "", type: "link", name: "type", price: 350 }, { value: "", type: "link", name: "type", price: 360 }, { value: "", type: "link", name: "type", price: 370 }, { value: " ", type: "link", name: "type", price: 380 }, ] size: body: " " inputs: -> price = @session.value("type").price [ { value: "30", type: "link", name: "size", price: price }, { value: "40", type: "link", name: "size", price: price*1.2 }, { value: "50", type: "link", name: "size", price: price*1.5 }, ] onSubmit: "address" address: body: " " inputs: [ { name: "address", type: "text", placeholder: ", , , " }, { type: "submit", value: "" } ] phone: body: " " inputs: [ { name: "phone", type: "text", placeholder: "+7 xxx xx xx" }, { type: "submit", value: "" }] onSubmit: -> #     onLoad, on @data("orders").push @session.values() @data("email").push email_template(@session.values()) "success" success: body: "     " image: -> "/images/#{@session.value("type")}.jpg" data: orders: type: "spreadsheet" url: "https://docs.google.com/spreadsheet/ccc?key=0Au4e-jj1-69ZdEloMW03UExKLXIZFSUE" email: type: "email" to: "1@interactiff.net" server.listen "3000" 
Translated into JS
 var client, server, widlib; widlib = require("widlib-server"); server = widlib.init({ template: index_template, pages: { type: { template: type_template, body: " ", inputs: [ { value: "", type: "link", name: "type", price: 350 }, { value: "", type: "link", name: "type", price: 360 }, { value: "", type: "link", name: "type", price: 370 }, { value: " ", type: "link", name: "type", price: 380 }, ] }, size: { body: " ", inputs: function() { var price; price = this.session.input("type").price; return [ { value: "30", type: "link", name: "size", price: price }, { value: "40", type: "link", name: "size", price: price*1.2 }, { value: "50", type: "link", name: "size", price: price*1.5 }, ]; }, onSubmit: "address" }, address: { body: " ", inputs: [ { name: "address", type: "text", placeholder: ", , , " }, { type: "submit", value: "" } ] }, phone: { body: " ", inputs: [ { name: "phone", type: "text", placeholder: "+7 xxx xx xx" }, { type: "submit", value: "" }], onSubmit: function() { this.data("orders").push(this.session.values()); this.data("email").push(email_template(this.session.values())); return "success"; } }, success: { body: "     ", image: function() { return "/images/" + (this.session.value("type")) + ".jpg"; } } }, data: { orders: { type: "spreadsheet", url: "https://docs.google.com/spreadsheet/ccc?key=0Au4e-jj1-69ZdEloMW03UExKLXI3cGRlbkJteGZFSUE#gid=0" }, email: { type: "email", to: "1@interactiff.net" } } }); server.listen("3000"); 

In the first line, we create a widget object and load the script into it.
The script object consists of pages and data. Each page is a separate screen that the user will see in this widget.

Each object with data corresponds to an adapter for storing or transmitting it. In the simplest case, it is just an array; in complex cases, it is the REST interface, MongoDB, Google Spreadsheet, and others.

We can use the same script, both on the client (including standalone), and on the node.js server. Using the server allows you to hide the script or its part from the user, which can be useful for a loan calculator or a quiz with a prize draw, as well as providing access to dynamic data and API, aggregation and processing of user information.
The client side of the pizza delivery widget, in this case empty:

 client=new Widlib.Client #       ,     . # pages: ... # data: ... server: "/" container: "#container" 




The developer does not even need to care about how to transfer information, and in which case to exchange data with the server. The library automatically checks for the presence of pages or data in the local script, and then, invisibly to the author, requests them from the server (or sends) using RPC. The server version has more complete functionality, and the client version is faster and independent, which allows it to be used in mobile applications, and does not disturb the server for nothing.

Features


I urge you to describe in comments where you would like to use a similar framework.

PS Comprehensive documentation will be available for the project, a library of examples and wizards is planned, as well as ultra-fine hosting of widgets with buns in the form of simple access to various APIs.

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


All Articles