Creating a Server

Once Moya has read the initial settings file, it runs the Moya Code file specified in the startup setting in the [project] section. This file (typically called server.xml) contains one or more <server> tags which are responsible for importing libraries and installing applications.

By default, Moya runs the <server> tag which has its docname attribute set to main. Most projects will only define this single server, but it is possible to have multiple servers defined. You can run an alternative <server> by specifying it on the command line. For example, the following would run a server with a docname of "alternative":

$ moya runserver --server alternative

Server Definition

Let's look at a server definition. The following is taken from a project created with moya start:

<moya xmlns="http://moyaproject.com">

    <!-- Initialize a server -->
    <server docname="main">

        <log>Starting up!</log>

        <!-- Import libraries for use in your project -->
        <import py="moya.libs.debug" if=".debug"/>
        <import py="moya.libs.auth" />
        <import py="moya.libs.session" />
        <import py="moya.libs.admin" />
        <import py="moya.libs.static" />
        <import py="moya.libs.favicon" />
        <import py="moya.libs.welcome" />
        <import py="moya.libs.links" />
        <import py="moya.libs.bootstrap" />
        <import py="moya.libs.forms" />
        <import py="moya.libs.widgets" />
        <import py="moya.libs.comments" />
        <import py="moya.libs.pages" />
        <import py="moya.libs.blog" />
        <import py="moya.libs.feedback" />
        <import py="moya.libs.jsonrpc" />
        <import py="moya.libs.wysihtml5" />

        <!-- The 'site' library, for non reusable content -->
        <import location="./site" priority="10" />
        <install name="site" lib="site.intended-for-humans" mount="/" />

        <!-- Install applications (instances of a library) -->
        <install name="forms" lib="moya.forms" />
        <install name="auth" lib="moya.auth" mount="/" />
        <install name="session" lib="moya.session" mount="/" />
        <install name="admin" lib="moya.admin" mount="/admin/" />
        <install name="media" lib="moya.static" mount="/static/" />
        <install name="debug" lib="moya.debug" mount="/debug/" if=".debug"/>
        <install name="bootstrap" lib="moya.twitter.bootstrap" />
        <install name="welcome" lib="moya.welcome" mount="/" />
        <install name="links" lib="moya.links" />
        <install name="favicon" lib="moya.favicon" mount="/" />
        <install name="comments" lib="moya.comments" mount="/comments/" />
        <install name="pages" lib="moya.pages" mount="/" />
        <install name="blog" lib="moya.blog" mount="/blog/" />
        <install name="feedback" lib="moya.feedback" mount="/feedback/" />
        <install name="jsonrpc" lib="moya.jsonrpc" mount="/jsonrpc/" />
        <install name="wysihtml5" lib="moya.wysihtml5" />

    </server>

</moya>

A server definition is executable Moya code. Moya runs each tag, line by line. If you have logging enable you should see the effect of each of these statements in the logs.

You can also step through the startup process in the debugger with the following:

$ moya runserver --breakpoint-startup

Importing Libraries

The first line in the above server definition is a <log> tag which simply writes some text to the logs. Not strictly necessary, but this may be helpful if you have more than one server. What follows are a number of <import> tags, which load the code associated with each library that will be used in the project. A library must be imported before it can serve content. Let's look at the first <import> tag:

<import py="moya.libs.debug" if=".debug"/>

This loads the library in Python module moya.libs.debug, which is a Moya built in library that provides error pages and other helpful content for development. There is also an if attribute which tests the value of .debug – so moya.debug is only imported if Moya is in debug mode (set in settings).

The py attribute is required only if the library is distributed as a Python module. Moya's built in libraries are distributed in this way, but more typically libraries are simply stored in the project source. By convention, the location for libraries is local/ for libraries you have built yourself, and external/ for other libraries. To load libraries from the project directory, use the location attribute, rather than py. Here's an example:

<import location="./local/sushifinder.shop"/>

An <import> tag may also contain a priority attribute, which should be an integer value. It is possible to override tags in one library from another (in order to customize content). You might want to add a field to a form defined in an external library, for example. The priority attribute is used to determine which tag is used – the library with highest priority wins. This feature is used in the server definition above to import the site library, with the following line:

<import location="./site" priority="10" />

Here the site library is imported from ./site and assigned a priority of 10. The default priority is 0, so the site library can override tags from all other libraries.

The site library should contain non-reusable content and is generally used to customize the look and feel of a web-site. By convention, it is stored in the /site. Moya doesn't require a site library; so if you find you don't have any use for it, you may delete it from the project.

Once a library is been imported, it may be installed. Installing allows you the library code to respond to URLs and generate responses. To install a library you need to refer to it by its long name, which is a period separated list of tokens. The first token identifies the author or organization, subsequent tokens are used to create a simple namespace to identify the library. Generally though, long names will be in the form of <organization>.<name of library>. For example, moya.auth is the Moya authorization library.

Installing Libraries

The <install> tag installs libraries. It requires an attribute, lib, containing the long name of the library, and and attribute called name, which should be a name to identify the application (installed library). An application name should be short and descriptive, and contain no periods. It may be refereed to as a short name.

Immediately following on from the site library import is the following line:

<install name="site" lib="site.intended-for-humans" mount="/" />

This installs the library site.intended-for-humans as an application called site. There is also an additional attribute, mount, which takes a URL segment where the application will be mounted. In this case, the application is mounted on / which means that it can handle all URLs in the project. Other applications will be mounted in different locations. For example the library moya.admin is mounted on /admin/ – so the admin site may accessed from /admin/.

Note that if an application doesn't produce a response for the requested URL, Moya will check the next mounted application until a response can be generated.

Mounting Applications

The mount attribute in the <install> tag is a convenient shortcut which is adequate for most libraries, but applications may also be mounted with the <mount> tag. It is possible for libraries to contain multiple mountpoints, which handle a number of related URLs. These can be mounted individually in different locations; so you can decide to access them from different top level urls, or even pick and choose which mountpoints you want to enable.

The <mount> tag takes three required attributes; app is the name for the new application, mountpoint is the name of the mountpoint you want to mount, and url is the url segment where you want to mount the application. For example, we could have installed and mounted the site application with the following:

<install name="site" lib="site.intended-for-humans" />
<mount app="site" url="/" mountpoint="main" />

Most libraries will contain a single mountpoint with a name of "main", which is also the default value for mountpoint in the <mount> tag; so you can omit the mountpoint attribute in most cases.