The nity-gritty (develop…)

This manual is a pre-release preview. Please follow Moonstalk on Twitter or Facebook to be notified of a public release.


These data-structures are universal providing access to the Moonstalk environment, the request, the response, and in many cases also database queries and their results (see next). You may check and change the values in these tables to determine how to handle a request—and to generate a page for response.

All tables exist in either a global or ephemeral (per-request) scope. The latter are discarded after each request is completed and may be modified freely, whilst the prior exist across all requests and should not be modified. Additional reference (pointer) tables are provided in the ephemeral scope for convenient access to some global tables.

Global tables should not be changed during a request, and are intended to only be modified by application load-time functions. Failure to adhere to this will result in random results when using more than a single backend instance. Whilst reference tables change with each request, they are dynamic pointers, or aliases, to the contents of global tables and therefore should also not be changed. No tables are persisted (use a database such as the Teller).

Typically if a controller has many references to, or a view consumes many instances of values in these tables, it is advisable for both cleaner code and better performance to assign them to a local at the top of these files. e.g. local data = local form = request.form


This predominantly contains details of the HTTP headers, with parsing into a more Lua-friendly format where appropriate. Use of this table is discouraged as its format and structure is dependant upon the web server API. See form and page instead.

request.get and are not conditional, instead use request.method=="GET" (case sensisitive).

Ephemeral table


Contains attributes that lead to authentication, and some present irrespective, providing a place to find both browser and user dervived values.

Ephemeral table


Contains values encoded in the request.body such as in an HTML form; is always present regardless of method.

In OpenResty when not urlencoded post={maxsize=bytes} must be set on an address for the form to be populated, with maxsize generally only being required for files.

Ephemeral table


Reference table


Defines the page to be rendered as a response.

Ephemeral table

Do not set new keys in this table — use only the data key.

Reserved name

Always declare variables as local else use


Global table


The global Moonstalk environment for each server (node). Settings are configured in the data/configuration/Host.lua file, and may also be changed at launch time by the .Elevator


Table (global)

scribe. (global)


Each database application provides its own interface and behaviours. The OpenResty application bundles drivers for MySQL, Redis, and Memcached. Some Moonstalk database applications (e.g. Databin and Tarantool) offer a standardised interface and configuration using a schema.lua file in the application as follows.

schema files can also define = keyed{} constants the same as in settings files.


To define a new database table (as opposed extend another application's tables, e.g. users or tenants), declare it in an application's schema.

The recommended naming is a plural for a table e.g. users = {…}.

The following keys in each database table declaration are supported for each table. See the database application documentation for additional configuration such as field declarations.


For application-specific functions see the applications page.



Appends the passed value to the current output section. Values may only be strings, numbers or nil (which is ignored).

Expressions evaluated by write or ?(expression) tags may only provide string or number values, nil and false values are ignored.

A table or function value will invoke an error as they cannot be represented as text in a response, for debugging you may however output them with tostring().

In views, do not call write instead use an ?(expression) tag.


Returns the given language key's value from a translated vocabulary, in its original case. Use L.key for an initial capital.

This is a proxy table—a function with table.key syntax. (Achieved using a metatable __call overload.)


Replace defined ?(key) macros in the specified text, with their correspondingly specified values.

Whilst macros in views (expression tags) accept expressions (thus, function calls) for replacement, text macros do not, and where no corresponding key is specified a macro is not replaced.

Text macros are typically used for customising strings, such as translated language keys from vocabularies, where pre-defined grammar is customised using embedded variables.



Changes the current output to a new container, as named. (The default page response output is named content.) See also Cut.


Marks the current position in a view to later Insert a section or other value.


Inserts a previously defined section into the current view/section. Takes an optional mark_name parameter to insert at the specified Mark instead of the current location. See also Paste.


Run a specified controller and/or associated view and append it's output to the current page. Name is normalised (lower-case).


Run a specified view only and append it's output to the page. If the view provides versions for different cultures a matching translation/localisation will be served. Name is normalised (lower-case).


Run a specified controller only. Name is normalised (lower-case).


Sets a cookie in the user's browser.


The following functions abandon page processing in some way, to display an alternate view or response.

The current function from which these functions are called, and any chaining from it, will continue to run but their output will be surpressed. No further functions will run except for the default template (if any). To prevent the current function from continuing, follow the function call with a return termination.


Abandons the page processing to instead returns a 302 redirect response to the user's browser. The address may be a path or URL.


Checks that the current user has one of the specified keys, otherwise abandons the page processing. If not signed-in the generic/signin view is displayed, or if signed-in but without a specified key, the generic/unauthorised view is displayed.

For a conditional termination use if not scribe.Authorised{"name"} then return end. For conditional content check user.keychain directly.


Abandons the page processing with the generic/error view using the specified details.


Abandons the page processing with the generic/not-found view. Accepts an optional user-friendly name to be displayed instead of the page.address.


The following functions abandon page processing in some way, to display an alternate view or response.

Lua Modules

All standard Lua libraries are available, with the following, and some other less commonly used libraries that are documented on the credits page.

You may use load other libraries (.lua or .so) saved in the same folder as a view or controller, or within an application folder by using the full path.

Moonstalk uses its own package.path and cpath, therefore if you wish to use other libraries elsewhere on your system (such as from LuaRocks), you must append those paths to Moonstalk's values. Applications may do this in the settings or functions files.


Web server

Moonstalk uses the data/configuration/lighttpd.conf as its base configuration, with which its own configuration is combined at launch-time, and then saved to the temporary/lighttpd.conf file to launch Lighttpd.





Contains named and translated terms, phrases and blocks by language. These values are used in the Scribe by referencing l.term_name (or L. to capitalise) for the language corresponding to request.client.language. Using the macro function these terms may contain placeholders for other values.

en.term_name = "Value to use in English"

Language and term IDs/names should not contain special characters nor be reserved words, if they are they must be declared as ['special-name'].

With the exception of page vocabularies (see below), all application vocabularies are merged, therefore if more than one application declares a term, the value may not be as expected. Term names should be unique and prefoxed with a suitable identifier, unless for generic use..



Other files




A bundle whose table exists in the global environment, and having handlers that run at launch-time.








Enabling applications has no per-request performance overhead except where the following are defined by the application, where the overhead will be specific to the functionality provided. Memory overhead for applications with multiple sites is minimal (sites are populated only with references to the application).


Sites are defined by the sites() function of applications. See the Sites Folder or Tenants applications, or any other application with a sites function, for details on how sites may be defined and configured outside the Scribe environment.

Within the Scribe environment, sites are stored in the node.sites table, with references from the global domains table (used to lookup a site for each request) and ephemeral (per-request) site table.



These values may be specified in the site's settings.lua file.














Defines how to match a request. Only one may be used.


Defines what to do with the request. One or more may be specified per address. You need only specify both controller and view if they are different.


Addresses may specify any of the attributes of a page, such as template or title or type.


Represents the anonymous visitor that made the request, a profiled visitor (cookie-tracked but anonymous), or a registered user. Managed by the built-in authentication mechanism but may be extended by applications.




To learn how you can extend moonstalk, and make use of pre-packaged functionality, read the applications page, or to understand the Moonstalk's design jump to the architecture page.