player one proudly presents

Meta-OS: For Developers

A quick walkthrough, from client to server

The usual work for developers is taken care of.
There are no new syntax rules or languages to learn. Although simple and small, Meta-OS handles multi-site, inheritance, templating, mobile & platform-specifics, and multi-user fileserving.
Using Meta-OS, you can provide visitors with instantaneous navigation and a native app feel, all in a tiny footprint.
Here's an example page with source code.


There are 4 main folders in the distro.
html HTML templates (which can contain JS and CSS), shell.html (the skeleton for templates) and vital.css (global rules)
source JavaScript libraries.
media images, fonts and other binary files.
data typeahead lookups, error logs, and such.

config.json contains oft-changed global variables, globeVar and shareVar being also available to the client.
server.js fires up the Meta-OS stack.

Tiny Templating

HTML5 was designed to be extensible, and is widely understood. TiTe overloads it for component creation, templating shortcuts and also to supercharge widgets.
Traditionally, server-side templating was used to insert variables and iterators, and it includes logic:
and client-side methods were used to progressively enchance elements:
Instead of combining the two methods, JSX takes templates away from HTML-only coders and forces them to learn a hybrid scripting language.
Angular stamps its ugly "ng" tags over templates instead of extending HTML, and encourages the use of three more hybrid scripting languages.
Neither of them are useable on the client!
TiTe is smarter:

So we use one or two familiar languages (HTML and optionally JavaScript) instead of four MORE alien ones! (JSX, TypeScript, Dart & Angular)

Markup ▼

Tags like <doctype> and <meta> are taken care of by html/shell.html

Homepage <html> attributes become site-wide accessible constants. Special attributes include noscript (render server-side for noscript users & SEO), tmpl_require (load additional JS modules), tmpl_style_buts (set page theme), inherit (override inheritance), api_both (2-way API data injection)

Headers, sidebars and footers are automatically inherited from parent folders.

Certain shortcuts are available <SCRIPT> and <STYLE> can be placed in templates without concern - they are magically extracted, combined, minified and served in the right order.
Originally, Web pages were a mix of HTML, CSS and Javascript. Now they can be again!

The overloaded <tt> tag allows for unbeatable UI flexibility...

Extending HTML5 with TiTe

Certain tags are extracted or transformed into standard HTML.
<TOP> is where the navigation goes.
<SIDE> is where sidebar (desktop) or additional (mobile) content goes.
<MAIN> is for the main page content.
<BOT> contains the footer.

<STYLE> is where CSS specific to the page goes - but it will go into the global stylesheet.
<SCRIPT> is where JavaScript specific to the page goes.
*NB* this MUST be UPPERCASE (so that one can, if needed, add scripts to a template which are not extracted, by using lowercase)

Super Tags ▼
<tt> is used for buttons, sliders, dropdowns, textareas and other widgets.
<rollup> is a universal implementation of HTML5's <details> & <summary> tags. Thou activated a rollup in order to read these words!
<list> is a way of iterating through an object or array.
<area> generates scroll-areas that can switch between drag, hover-scroll, and traditional scrollbar modes.
<group> injects its properties into child buttons.


If a className contains "vardim", these attributes determine that element's dimensions:
weq (width), heq (height), xeq (left), yeq (top), ceq (className) eg:

TiTe Buttons

To eliminate labourious recoding of UI elements and attaching events, <tt> is used. Here's the code for the button below:
TT ▼
<tt> buttons can have the following attributes:
genus [radio / text / slider / multi / springup...]
sliders can also have attributes min, max
links - <a href> for buttons
help - verbose explanation of button's function too big to go next to button (displayed as notification or popup)
on (no value required) - indicate a button is on
group - for related buttons
label - adds a label above the button
options - for radios, dropdowns etc: list of options
labels - for radios, dropdowns etc: list of labels
key - keyboard shortcut for button
(hard), target - the variable to sync with this button's value (hard attribute saves to localStorage also)
sigil - use canvas vectorgraphic instead of text
The id attribute you know and love; rollup makes it target the ru_tt rollup, and genus is set to make the button behave like a checkbox.

Another example:
Last one!
tite.but ▼
In Javascript, buttons are made with tite.but.
The templater uses tite.but to transform tt tags into standard HTML.
Button states are not stored in data-whatever attributes; instead they live in window.opz
why opz? ▼
Apps are made of ops, and opz are easier to grep than ops. opz are not always buttons, but buttons are always opz.
You did click on the question...

There's a lot more going on - examine browser/tite/buts.js


Meta-OS libraries are inside three folders:
source/browser/ es3*
source/common/ isomorphic
source/server/ es6
3-party plug-ins have an isomorphic home too:
*arrow functions and for-as loops are allowed, but most clientside ES6 is restricted to keep the transpiler small.
For full clientside ES6, disable uglify-js implosion or swap it out for the billion-times-slower uglify2.
More ▼

source/common/bios.js is the first lib loaded by both server and client. It contains many methods used throughout the codebase.
server.js is the node.js server and lives in the main folder with config.json.

To run code just on a specific page, add that <SCRIPT> to the template. It will run after the rest of the page (and associated code) has initialized. It works with pushState too :)
Add site-wide code inside <SCRIPT scope="sitewide"> tags. This will run before page-specific code.
Run code before the page renders with <SCRIPT scope="asap"> tags. This is useful for injecting data into the templator.

Scripts that outgrow their templates should be moved into source/

In package.json, be aware that enabling SQUISH may introduce errors, because uglify-js is imperfect.


Add to sitewide CSS by adding <STYLE> tags to any page.

If a page is deleted, CSS specific to it will be deleted too, so there will be no orphan CSS on the site.

Prefixes & Minifying ▼
Browser prefixes like -moz- and -webkit- are added automatically.
Ditto with alternative rule names for eg. display:flex - just use the W3C syntax in your code.
You can prepend CSS selectors to all rules within blocks - eg. <STYLE prefix=".super-class">.
Mark CSS to be minified by giving it an ID - eg. <STYLE id="MinMe">. Minified CSS is around 6 times smaller than normal - but it can only be delivered to JavaScript-enabled clients.

Since all CSS is loaded together, you can instantly see if you have CSS conflicts that would normally go undetected.

Add a css.html template containing a suite of the elements the site uses to test all the CSS in one place. The STYLE tags in this file will be extracted and added to the global CSS, but the HTML will not be visible in production environments.

html/vanilla/css.html is inherited by all sites.


The same APIs can run in 3 scenarios:
█ before server-side rendering.
█ before client-side rendering.
█ on the client, as an update.

2 arguments are passed: the object to populate and a callback function. eg: Clever use of closures means the callback function is aware of the sob object and does not need it passed.

Server-Side ▼
As in the previous example, per-request server objects keep most of their properties private and only pass public vars objects to templates.

Client-Side ▼
Ensure a page has API-supplied vars for template rendering, clientside OR serverside, by adding an attribute to the HTML element:

To save CPU, server-side rendering starts off disabled. You should enable it for all searchable pages by adding a noscript attribute to the HTML element.


server.js + source/server/clerk.js form the bulk of the server.
To simplify bouncing objects around callbacks, eg: req and res are not usually passed as separate arguments. A single temporary per-request object is used, with ask (req) and give (res) properties.

Other useful properties of this object include:
vars - variables to be passed to the templater
file - the filename of the response, used to determine Content-Type, and ensure downloadable files are sensibly named.
mysite - the domain name of the site being visited.
mod - the Last-Modified date.

Already intelligently-handled:

Caching + Gzipping
Partial downloads
Etag + Content-Length
Proxying (source/server/proxy.js) + Cookies
Minifying (source/server/imploder.js)
binary file uploads (source/server/fylz.js)
API calls (source/server/api/api.js)

Media Content

Files in the media folder are split by type into subfolders.
Images go in the Image subfolder, fonts in the Font subfolder etc.
Unrecognized files go in the Mixed subfolder.
These subfolders need not form part of the URL.
So the server will look for <a href="/Sprites/bub.png">awesome</a> inside the media/Image/Sprites/ folder.