Building a Project

This chapter explores the files required to launch a server. If you have an example project created with moya start, you can compare the settings and other files discussed here.

Settings Format

The following is en example of an file in Moya's INI format:

# This line is a comment, and is ignored
# The next line tells Moya to extend this ini file with another.
extends = ./common.ini

# This is a section
[section]
key = value
# This is a named section
[ship:moya]
# a multi-line list (note the indentation)
crew = Aeryn
    John
    Scorpius

Moya reads ini files line by line. If the line begins with a # character, the rest of the line is ignored. A line with text enclosed in square brackets introduces a section. A line with an = defines a settings in the section, where the text before the = is the key (name of the settings), and the text after the = is the value. A value may contain multiple lines (treated as a list by Moya) if they are indented.

Some section names may contain a single colon. Such sections are known as named sections. A named section generally creates an object in Moya with the given name. In the example above, the section, ship:moya, would create a ship called moya.

You may have noticed in the example INI above, there is a key / value pair at the top of the file and not in a section. This is the extends directive which tells Moya to first load the settings from another INI file, before merging the settings in the current file. There is no limit to the number of times an INI file may be extended, but be careful not to include the same file more than once in the chain, as this will be flagged as an error.

Project Settings

The project settings file creates the initial environment to run a server.

The convention for Moya settings files is to have a file called settings.ini which contains development settings, and a file called production.ini which contains settings required for a production environment (running live). Both these INI files extend basesettings, which contains settings common to both.

When you run the server, you can specify which settings file to run with the --ini file. For example, the following command will run the production settings:

$ moya runserver --ini production.ini

[console] Section

This section configures the console (text written by the <echo> tag).

color = yes/no

If yes (the default) Moya will write colored output to the console. Set to no for monochrome output.

width = <INTEGER>

Set's the width of the console. Leave blank to auto-detect the terminal size.

logger = <LOGGER>

If not blank, Moya will re-direct all console output to a logger (e.g. "moya.console"). Use this in a production environment, where you don't have a terminal.

[media] Section

This section defines where media (static images / css etc) should be stored and served. See Creating a Library for more information on media.

location = <path>

This should be a path to the static media for the project, by convention this is typically ./media.

url = <media base url>

This should be the base url for media, which be fully qualified (include https:// etc), or an absolute URL path. If you leave this value blank, Moya will use the app setting to detect the media url.

app = <app name>

If a base URL isn't supplied (url setting above), this should contain an application name. Moya will set the media url to be wherever this application is mounted. If not specified, the default will be 'media' so the media url will be wherever the application named media is installed.

[settings] Section

The settings section sets project wide settings, which may be used to customize project behaviour. Here's an example of settings section:

[settings]
project_title = Sushi Finder

Values set here are copied to a root object called .settings at the beginning of a request. For example, you can refer the value .settings.project_title, which will contain the string "Sushi Finder".

[project] Section

The project section contains a few settings required to start up a project.

debug = yes/no

Set to yes to enable a flag in Moya code (.debug) which can be used to enable debug features. Set to no to disable debug features.

preflight = yes/no

Moya can run preflight checks on startup which will alert you to any potential problems via the logs. Set to yes to enable preflight checks, or no to disable. You should probably enable this for development, but disable in a production environment.

log_signals = yes/no

If set to yes, Moya will log any signal fired in the project. This is disabled by default as it can generate a lot of log messages. Enable if you are debugging signal related code.

location = <path>

This setting lets Moya know the path to the logic code that will be used to create a server. This is typically set to ./logic, but can be any valid directory.

startup = <filename>

This setting defines the first file that Moya will run, it should be set to the name of a file within directory defined in location. Typically, this will be server.xml which contains a server definition.

[autoreload] Section

When developing a project, Moya can watch the project files for changes, and when it notices a file was modified, added or removed, it will rebuild the project. This means that you may edit your project without having to restart the server.

enabled = yes/no

Set to yes to enable auto-reload. Set to no to disable auto-reload (in a production environment for example).

extensions = <list of extensions>

This should be set to a list of file extensions which should be monitored. Changes to file types not in this list will not cause a reload. This setting will typically be set to the following:

extensions = .xml
             .ini
             .py
             .html

location = <path>

This section should be set to the directory to be monitored for auto-reload, typically ./ which will including the entire project (including sub-directories).

[site] Section

This section contains settings regarding the site that will be served. Moya uses this information internally, but you may access these settings during runtime, in the values .sys.site. See also Site Data.

base_content = <element>

A reference to a base content definition. This is the content element that other content elements will be extended from, if they don't explicitly set an extends attribute.

timezone = <timezone>

This setting should be set to a timezone, which will be used when displaying dates to the user. An example of a timezone would be US/Eastern for Eastern Standard Time, and Europe/London for the time in the UK.

user_timezone = yes/no

A single timezone for all visitors to your site may be enough for many sites, but if your site has users from various parts of the globe, they might appreciate dates appearing in there own timezone. If this value is set to yes Moya will use the timezone associated with the user in the database. If there is no user logged in, then the timezone will default to the timezone setting.

append_slash = yes/no

If this setting is set to yes, Moya will redirect to a URL ending with a forward slash (/) if the current URL doesn't already end with a slash. Set to no to disable this features.

Site Data

You can add arbitrary data to the site section by prefixing it with data-. When Moya sees such a setting, it drops the data- part and stores the key and value in a dictionary in .site. You can then use these settings in your code to configure various site level features. Here's an example of setting site data:

[site]
data-theme = css/themes/default.ini
data-title = Sushi Finder

You could then use these values in Moya code or a template. Here's an example:

{% if .site.theme %}<link href="${.site.theme}" rel="stylesheet" />{% endif %}

[templates] Section

A project may define a templates directory which can override library templates, in order to customize the look and feel of a site.

location = <relative path to settings>

Sets the path to a directory containing templates. This should be ./templates by convention.

priority = <template priority>

This sets the priority of for the project templates. Templates with a higher priority will be selected over templates with a lower priority. The default priority for templates is 0, so this setting should be set to something higher than that to ensure they override the templates (I suggest 10).

Caches

A cache in Moya is an object which stores temporary data. Caches are typically used to speed up your application by saving data that may otherwise have to be re-calculated. There are a few caches that are used internally by Moya, but you may also define additional caches for use in your project code.

A new cache object is creates with a named section called cache:, which takes a name for the cache (used as an identifier in code). A cache section should contain some of the following settings:

type = dict / file / memcache

Moya supports a few different methods of storing cache data, this setting defined which type to use. The available cache types are as follows:

dict
A dict cache stores cache data in memory, within the same process as the server. Dict caches are fast, but non-permentant. They are best used for development, or where you can be sure the cache will not grow very large.
file
A file cache stores cache data on disk. File caches are permanent, and have the advantage that data will still be cached when the server re-starts. In theory, they are not as fast as a dict cache, but modern operating systems are so good at optimizing file access that the difference may not be noticeable.
memcache
The memcache cache type stores data in a memcached server, which is an industrial strength distributed cache server. This is the best choice for a production environment – it is very fast and can share cache data across multiple servers.

A cache section may take the following settings:

enabled = yes/no

A cache may be disabled by setting enabled to no. A disabled cache is still present, and may be used, but it will not store any data. This is a good way of testing scenarios where the memcache server is unreachable (for example). Written properly, your web application should be able to function with disabled / broken caches – albeit at a performance cost.

debug = yes/no

If debug is set to yes then any operations on the cache will be logged. This is useful for debugging, but can result in a lot of log entries when enabled.

location = <path>

This is the directory where cache files will be stored. Only required for caches that write data to disk (i.e. the file cache type).

namespace = <identifier>

Caches may have an associated namespace which keeps cache data separate if they share the same resource. For example, you may have more than one file cache that shares the same location if they have different namespaces. Ditto with the memcache cache, which can share cache data on the same server.

hosts = <memcache server IPs>

Used by the memcache cache type, this setting defines the IP address(es) of the server(s). For example, a local memcache server would require:

hosts = 127.0.0.1

compress = yes/no

If set to yes then data will be compressed before it is stored in the cache, which will reduce the size of cache required, at a slight performance cost.

compress_min = <size in bytes>

This is the minimum required size of a value (in bytes), before compression is enabled. If a cache value is small, compression is probably not worth the effort. A default of 1024 (1KB) is used, which should be adequate for most purposes. You can set this value to 0 to always compress.

Standard Caches

Moya uses some caches for internal data. You can configure these caches in the same with as any other.

[cache:templates]

The cache object named templates is used to store compiled templates. When Moya loads a new template, it first has to compile it in to a form that is faster to render. This compile stage only needs to be done once per template, so Moya will cache the compiled template in templates to avoid re-compiling. This is one of the reasons why pages are slower to render the first time they are requested.

A file cache is probably the best type for templates. The default location created by moya start is in ./__moyacache__. In a production environment, you would probably put it somewhere not in the project directory (/tmp/__moyacache__ for example).

[cache:fragment]

The fragment cache stores pieces of html (generated from templates) that don't change often and may be expensive to generate. In a production environment, memcache or file is the best type for this cache object. Stick to dict for development.

Application Settings

In addition to site-wide settings, you can also modify settings for individual applications installed in your project. These override the default settings set by the library itself. To modify application settings, add a named section called settings:, which takes the name of application you wish to configure. For example, the following sets values for the fictitious sushifinder application:

[settings:sushifinder]
open_for_business = yes
currencies = USD
             GBP
             BTC

You can use the settings subcommand to review settings. For example, the following command line will list the default settings for the moya.static library (assuming it is installed in your project):

$ moya settings moya.static

You can also use this command to show you the settings configured for an application. For example, if the moya.static has been installed as an application called static, then you can review its settings with the following:

$ moya settings static

And if you want to see all settings for both libraries and applications installed in a project, you can use the following:

$ moya settings

Customizing Applications

Moya selects some sensible defaults when installing application, but occasionally you may want to customize some of these internal settings. To customize an application, add a named section called application with the name of the application you would like to customize. The following is an example of a section to customize an application:

[application:help_pages]
templates_directory = /custom_help_pages/
data_directory = /custom_data/

Note, that if you don't want to modify any of these settings, you may omit the app section entirely.

templates_directory = <path>

This sets the root directory for templates in the templates filesystem. This is usually the library's long name, but you can set any directory here. The most common use for this is so that you can have have custom templates for each application, even if they share the same library.

data_directory = <path>

Similar to the templates_directory, this setting defines the root directory (in the data filesystem) for the application's data files. The default is to use the library's long name. This setting is typically used if you have more than application from a single library, and you want to provide different data files to each application.

Supporting Multiple Sites

It is not uncommon for a web application to need to respond to requests from multiple domains, often with slight differences in the content or look and feel. You can implement this in Moya with a custom site definition, which overrides any of the settings present in the [site] section.

To define a custom site, add a named section that starts with site: followed by a domain (or IP) you want to customize. The domain may also contain a wildcard character (*) which will match a partial domain. If the domain of the request matches the domain in the site definition then its settings will override the defaults in [site].

Here's an example of a site definition for a subdomain:

[site:admin.example.org]
data-admin = yes

This will match the exact domain, admin.example.org. It will also set the value .site.admin to "yes".

Here's an example of a site section that matches all subdomains of example.org:

[site:*.example.org]

This will match foo.example.org, or any domain that ends with .example.org. It won't match example.org or any other domain.

You can store the part of the domain that matches the wildcard with the following syntax:

[site:{subdomain}.example.org]

This matches any subdomain of example.org as before, but also save the value subdomain in the site data. So if the request comes from gromits.example.org, then the value of .site.subdomain will be "gromits".

The above code will match only a single component (separated by a period) of the subdomain. so widgets.gromits.example.org will not match. If you want to match anything, including the period, then you can use the following syntax:

[site:{*subdomain}.example.org]

The asterisk means 'match anything'. For the above site definition, widgets.gromits.example.org will match, and the value of .site.subdomain will be widgets.gromit.

A single site definition may also match multiple domains, by seprating the domains (or wildcards) with a comma. For example, the following will match the IP 127.0.0.1 and the domain localhost.

[site:127.0.0.1,localhost]

Moya checks each site definition in the order they appear in the settings file, until a match is found. So put the domains you want to match first at the beginning of your settings. If no settings definitions match then Moya will return a 404 (not found) response for the request. If you want Moya to serve a response to all requests, add a catch all site definition to the end of your sites. Here's how to use a wildcard to match any domain:

[site:*]

Mailservers

This section defines the mail (smtp) servers which will be used to send email in the project. Most projects will only require a single mail server, but it is possible to specify more than one. To configure a mail server, add a named section called smtp, with a short name to be used as an identifier. Here's an example of a typical smtp section which assumes one server running on the same host as the project:

[smtp:default]
host = 127.0.0.1
default = yes

You can review the mail servers in a project with the following command:

$ moya email list

You can check the mail server settings with the following command:

$ moya email check

This will attempt to connect to each server, and report any errors. You can also send a test email with the following command:

$ moya email send

An smtp section, takes the following settings:

host = <mail domain / ip>

Sets the mail server url or IP. Use 127.0.0.1 for a local server.

port = <port number>

Set the port number of the email server (default is 25).

username = <mail server username>

Sets the username for the mail server, if it required authentication.

password = <mail server password>

Sets the password for the mail server, if it requires authentication.

default = <yes / no>

If yes, this mail server will be the default, i.e. if you don't specify the mail server to use when sending a mail, Moya will use this server. If you don't set a server as default, Moya will make the first server in settings the default.

Filesystems

Moya code may only access files (other than its own code) if they are within a filesystem. Moya creates a few filesystems by default, such as a filesystem for templates, and static media, but you may also define your own. Creating a filesystem is necessary if you want to statically serve additional files, write files (for uploads) or read data from your Moya code.

You can list the filesystems configured for your project with the following command:

$ moya fs

The above command will display a table of all filesystems and their location. You can inspect an individual filesystem with its name. For example, the following command will show you information regarding template locations:

$ moya fs templates

The templates filesystem is a MultiFS filesystem, which merges several directories in to a single filesystem. You can see information regarding any other filesystem in this way. You can also see the directory structure of a filesystem with the following command line:

$ moya fs templates --tree

There are other switches in the fs sub-command for managine files in Moya filesystems. See the command help (moya fs --help) for the details.

You may create a filesystem with a named section called fs, which takes an identifier to refer to the filesystem in code. Here's an example that creates an uploads filesystem:

[fs:uploads]
location = ./uploads

Currently, only one setting is required to create a filesystem:

location = <path>

This setting should be the directory that should be exposed. If it is relative, then the path will be assumed to be relative to the project root.

Settings Interface

There are two places you can access settings when handling a request in a Moya project; .settings which contains project-wide settings, and app.settings which contains individual settings for an application. Both settings objects are essentially a dictionary containing strings, but Moya adds an additional attributes to interpret those strings.

You can treat a setting as a boolean with the .bool attribute, which will be set to True if the value is yes. For example, in the following code, the condition will be True only if the open_for_businbess application setting is set to yes. The .bool is important because otherwise any non-empty string would be considered True in a boolean expression.

<if test="app.settings.sushifinder.open_for_business.bool">
    <echo>You can haz Sushi</echo>
</if>

You can also convert a setting in to a list with the .list attribute.

<for src="app.settings.sushifinder.currencies.list" dst="currency">
    <echo>You can buy sushi in with ${currency}</echo>
</for>

You may also use the attributes .int which returns an integer version of the setting, and .float which returns the string as a floating point number. If the setting isn't a valid integer or float, then a value of None will be returned.