FML Overview - AppDaddy-Software-Solutions-Inc/framework-markup-language GitHub Wiki
Welcome to AppDaddy Software Inc.'s Flutter Markup Language
Overview! Here you will find an in depth overview detailing the features and uses of the FML
package, an all-in-one solution to rapid cross-platform application development!
The FML
package is built on 3 fundamental tiers that address a gap in function with current markup languages:
1) A simple and highly-customizable framework for all platforms.
2) An easy-to-use databinding system with high-level functionality.
3) A singular interface for accessing, manipulating, displaying, and storing data in real time.
These tiers are encompassed by FML's
fundamental building blocks called Widgets. Widgets have been meticulously designed and chosen to allow a user to build any application they need, while maintaining simplicity and ease of use. These widgets are defined by an easy-to-understand language called Flutter Markup Language
using xml syntax, which is interpreted on any platform desired, and can be connected to any existing backend to tie it all together. FML
templates can be built on any text editor or IDE for rapid deployment.
Flutter Markup Language
is a custom language interpreted by the FML Interpreter
. FML
files use the popular .xml syntax for familiarity and ease of use. The language is then interpreted by the FML-Engine
to be used across all platforms with a single template, requiring no repeated work for each platform of deployment. For users that are comfortable with FML
, they can create individual templates to be used on specific platforms, or create reactive components within a single template, displaying differently to the end-user based on the platform of choice.
The structure of Flutter Markup Language
is broken down into Widgets. Each widget then can have its own PARENT
and/or CHILD
widget, which make up the widget tree. The highest level of each tree or "page" as the user will see it, is the TEMPLATE
. The Widget tree defines both the Layout of the page, as well as the SCOPE of the Databinding. If a user defines a block of TEXT
within a BOX
, the TEXT
is the child of the BOX
, and therefore will be displayed within the card during layout. If the TEXT
has no children, it will also be the end of the widget tree's branch. This system allows for a few lines of FML
to replace pages of traditional languages, all while maintaining a visual structure that is consistent with the rendered UI.
Flutter Markup Language
uses xml syntax with custom elements to maintain familiarity. A widget in FML
is created as an Xml Element, which can have attributes/properties, and other widgets as children. Allowing the customized widget to be manipulatable, interactive, and stylized. These widgets can be used to display anything, from layouts of aesthetic elements, custom 'forms' to be saved by a user, to complex Charts and Tables with thousands of data points. These data points, as well as the attributes of each widget can be bound to and manipulated using our Databinding system to handle both the data and the UI responses.
One of the most powerful aspects of Flutter Markup Language
is its ability to manipulate and bind to all data sources. Data sources can include any Widget's attribute, property, returned data from a Datasources, and custom defined data using VARs
, evals, and events. Databinding is a simple solution allowing two way flow of data. Bindings use a defined scope to access and broadcast data defined by widgets, to then bind or notify other widgets of changes. This ease-of-use system can define, retrieve, evaluate, and manipulate its bound data using FML
's event driven methods and evaluation function in both upstream and downstream bindings.
The system central to FML's reactive UI and live data manipulation is FML's event driven system. Events are trigger-based, and execute in the order in which they are defined. Events such as set() can set any attribute to a users choice when it is triggered. This can allow for manipulation such as changing the color of a button when clicked, sizing a widget based on an interaction, or altering data to be saved via a POST
datasource. Other events like alert() allow for custom alerts to be shown to a user based on a triggers such as incoming data, invalid fields, user interactions and more. In all there are over 24 EVENTS that serve a multitude of common and case-specific scenarios, encompassing nearly every situation a user could run into. For a full list of events, please visit the EVENT page.
To further extend FML's
data manipulation capabilities, Flutter Markup Language
uses an evaluation function, or eval, to allow a user to perform complex functions, if/if else statements using ternary expressions, and mathematical operations. Evals, along with custom defined variables (or VAR widgets), can be strung together and bound to. This allows a user to preform near endless data and UI manipulation in real time. Eval also contains its own custom functions such as round()
, contains()
, truncate()
to name a few. A full list of these functions including how to use eval can be found here.
The final tier that Flutter Markup Language
is built on is the display of complex data sources in only a few lines of FML
. Returned data and Posted data in FML
are defined by the Datasource widgets. These sources can function both online or offline, allowing data to persist and save regardless of connectivity. The Datasource widget returns data from an input source. These sources include both network, local and hardware data such as: API CRUD operations GET
, PATCH
, POST
, PUT
, DELETE
, and other sources such as MQTT
, GPS
, NFC
, CAMERA
and more! Retrieving and utilizing these sources can be done in a single line of code <GET id="my_id" url="MY URL HERE"/>
and interpreted in multiple formats, the default being xml. To further extend Datasources, operations can be performed on incoming data sets before they are bound such as FILTER, PIVOT, SORT, and CALC. The Datasources will then listen to its source, updating as the data changes in real time!
Datasources data can also be dynamically displayed using our interactive Data UI widgets such as CHART
, TABLE
, and LIST
. These specialized widgets will allow for a user to define a prototype "widget" such as an ITEM
for a LIST
, or row for a TABLE
. This item can then be bound to the field name, and will iterate through every row of data until the widget has been populated to the users specifications. For example a paged datatable with 1000 rows can be produced in 15 lines of Flutter Markup Lanuage
, while maintaining its ability to sort, resize, interact, display, and update data to the user. This is the power and efficiency Flutter Markup Lanuage
brings and it works for all devices and platforms from a single template!
Conversely for saving data, we use the POST widget as easily as we use the other Datasources. The POST
will automatically create a posting body based on FORM
widgets within a FORM
. These widgets can also be used to populate a form from a Datasources for both editing and displaying in the same page! POST
widgets can build a posting body automatically using .json
or .xml
format, as well as building user-defined posting bodies for complex interactions between fields and multiple brokers. The body can be built and form saved using all-encompassing events such as onclick="complete()"
, or more targeted events such as start()
. When a device is offline, POST can save data locally with little to no extra work!
For examples of the languages simplicity, as well as screenshots of its expected output, continue reading! For more in depth information on each piece of the CORE
package, as well as descriptions of each widget and functional examples of CORE-Lang
, please refer tp the side menu for links to each item.
Of course, we have to start with displaying 'Hello World'. But lets make it look a bit better... Remember, TEMPLATE
tags need to surround everything within your template!
<FML>
<TEXT value="Hello World" size="20" color="blue" bold="true"/>
</FML>
Lets go a lot further, but not much in terms of workload. Lets create scrollable list returned from a Datasource? It's as easy as 4 widgets! The LIST
, The ITEM
, the TEXT
, and of course, the GET
.
<FML>
<GET id="getsource" url="api/sample"/>
<LIST data="getsource">
<ITEM>
<TEXT value="{data.country}" size="15" color="blue"/>
<ITEM/>
</LIST>
</FML>
Now lets say we want to make sure Canada is always red, we just have to add an inline Eval. Lets give it an icon as well!
<FML>
<GET id="getsource" url="api/sample"/>
<LIST data="getsource">
<ITEM>
<ICON icon="globe" visible="={data.country}=='Canada'">
<TEXT value="{data.country}" size="15" color="={data.country}=='Canada'?'red':'blue'"/>
<ITEM/>
</LIST>
</FML>
Now we can make this example interactive, taking the user to the page that each country is on. There are many interaction widgets, but we can do it simply with a LINK
. Here we introduce our first event, as well as our first event attribute.
<FML>
<GET id="getsource" url="api/sample"/>
<LIST data="getsource">
<ITEM>
<LINK onclick="open('mycountryurl/{data.country}', 'true')">
<ICON icon="globe" visible="={data.country}=='Canada'">
<TEXT value="{data.country}" size="15" color="={data.country}=='Canada'?'red':'blue'"/>
<LINK>
<ITEM/>
</LIST>
</FML>
We can even change some items to allow the user to save their own country automatically on a FORM page:
<FML>
<POST id="postdata" url="api/sample" body="ROW"/>
<FORM post="postdata">
<INPUT value="" size="15" onchange="complete()"/>
</FORM>
</FML>
It's that simple! The aesthetics and complexity of each page can be scaled nearly infinitely to meet each users needs and preferences.!