In Moya, a library, is a bundle of files for handling a particular component of your website. All functionality for handing URLs is contained within a library, whether unique to your project or something you would like to distribute. This chapter covers how to create a new library.
You can use the moya start library
command to create a library within your project. This will create a fully functioning library which you can use as a starting point.
Here's how you might create a new library called "Sushi Finder":
$ moya start library --title "Sushi Finder" -a
Alternatively, you can create the directory and files manually. This chapter will describe the structure and contents of a library.
By convention a library directory should be named after the long name of the library, so the directory name won't conflict with a library from another organization. An example long name would be acme.shop
. As long as no other organization uses the name acme
, there is no risk of creating a library name used by someone else.
Immediately inside the project directory should be the following files:
A library will contain a number of directories that Moya will read from, depending on the features enabled in lib.ini
. The next section describes the contents of lib.ini
.
Like the main project, a library is initialized form an INI file which defines a few settings and tells Moya what files to load. This settings file should be called lib.ini
. This INI file may define the following sections:
The author section contains information about the library and author, which is used when distributing the library. Here's an example of an author section:
[author]name = Mr T Authoremail = author@example.orgorganization = Example Incurl = http://example.org
name = <author's name>
The name of the author or – if you prefer – the organization.
email = <email address>
A contact email the library author. You can leave this blank if you wish.
organization = <organization name>
The author's organization, i.e. the company you work for or some other group you belong to. You can leave this blank if you wish.
url = <homepage URL>
This should be a URL with information regarding the author; which could be an homepage, blog, company website etc. You may leave this blank if you wish.
This section contains information Moya needs to read the library's code. All libraries must contain a [lib] section. The following is en example of a lib section:
[lib]location = ./logictitle = Sushi Finderurl = http://www.example.orgnamespace = http://moyaproject.com/sushifinderlongname = moyaproject.sushifinderversion = 0.1.0-dev
location = <path>
This should be a relative path to a directory in the library which contains Moya code. This should be ./logic
according to convention, but could be another directory. When Moya imports the library it will read all the xml files in this directory, and sub-directories.
Note that the names of the xml files are irrelevant as far as Moya is concerned, but should probably reflect what they contain. The moya start library
command will create a few example files, but the names are only a suggestion.
title = <project title>
This is the human readable title of the project. For example, "Sushi Finder".
url = <library homepage>
This setting should be the URL for the library, i.e. documentation. Leave blank if the library has no URL.
namespace = <xml namespace>
This should be an XML namespace which will be used for any tags defined in the library. If your library doesn't define any tags, you may leave this blank.
name = <library's long name>
This should be the library long name (a name used to identify the library in code). A library long name consists of lower-case characters with no spaces, separated by periods (.
). The first token should identify the organization, other tokens should identify the library. Library long names should be globally unique, so try and pick a long name that isn't likely to clash with a library from another author.
version = <library version>
Libraries should be tagged with a version number in Semantic Versioning format. Essentially this consists of MAJOR.MINOR.PATCH. Start at 0.1.0 for a first pre-release version, then increment PATCH when you make backwards-compatible fixes, increment MINOR when you add new functionality, and increment MAJOR when there is a new version.
A MAJOR value of 0 is for initial development. When you are ready to distribute your library, reset the version to 1.0.0. You can also add -dev to indicate a version in development. It is a good idea to bump your version number immediately after publishing the library and add -dev. Drop the -dev suffix when you publish the next version.
Moya can be extended with Python code that defines new tags and adds functionality.
location = <path>
This setting should be a relative path to a directory containing Python (.py) files. By convention, this should be ./py
.
This section defines the initial settings for the library. These can be overridden in the project settings once installed. There are no particular requirements for the setting, you may define as many as you need to configure an application with the library. As a guideline though, it is recommended to chose sensible defaults so that a library may be installed with little or no configuration.
This section initializes templates used in the library. This section isn't required if the library doesn't have any templates.
location = <path to templates>
This setting should be a relative path to template files. By convention, this setting should be ./templates
.
priority = <integer priority>
This setting defines the template directory priority which is used to resolve conflicting template paths. Moya will select the template with the highest priority. The priority defaults to 0 if this setting isn't present.
The template priority may be overridden when the library is imported (see <import>).
Generally this setting should be left as the default, as most libraries contain templates for their own use that will not conflict with other libraries. Set it to 10 if the library was designed to replace template in another library.
Moya libraries may bundle media files (images, CSS, Javascript etc.) with the code, which will be served statically. To add media to your library add a named section, called media:
and give it a name to be used as an identifier. Most libraries will only have one media directory, and the convention is to name it simply 'media'
, so the section will be [media:media]
.
The media section takes one setting, location
, which should be a relative path to the directory containing the media. By convention, this will be ./media
. For example:
[media:media]location = ./media
When the library is installed, Moya adds media directories to a virtual filesytem called media
, under a sub-directory called <application name>-<media name>
.
Let's work through an example to illustrate this. Assume we have a library called moya.sushifinder
, with a media section as follows:
[media:media]location = ./media
And the library contains the following files (some directories omitted for brevity):
moyaproject.sushifinder/|-- lib.ini|-- logic| |-- views.xml| `-- widgets.xml`-- media|-- css| `-- sushi.css`-- images`-- logo.png
When we install this library with the application name of sushi
, Moya adds a directory to the media
filesystem called sushi-media
. If we were to list the contents of the media
filesystem, with moya fs media --tree
, we would see something like the following (along with media from other libraries):
|-- sushi-media| |-- css| | `-- sushi.css| `-- images| `-- logo.png
You can serve this media filesystem with the moya.static
library. To use it, add the following to your <server>:
<import py="moya.libs.static" />
Then install it with something like the following:
<install name="media" lib="moya.static" mount="/static/" />
Finally, add the following section to your project settings:
[settings:media]fs = mediadirlist = yes
Your project should now be serving media from all applications. If you visit the /static/
url, you should see a directory listing of the media files you are serving.
See Overriding Media for ways of customizing media for a project.
This section defines additional data files (json, text etc) that may be read from your project code. Moya combines any directories defined in this section, in to a single filesystem called "data"
. You can see what data files are exposed by Moya with the following command line:
$ moya fs data --tree
You can read a data file with the <read-data> tag, which supports a variety of standard formats.
Data follows the same convention as templates; the data files should be within a directory named after the library. This allows a library to over-ride the data files from another library, and is another way of customizing behavior.
location = <path to data>
This setting should be a relative path to a directory containing data files by convention this should be ./data
priority = <integer priority>
The priority is used to resolve which path should be used when there are conflicting paths within data directories. The library with the highest priority is used. This setting may be blank, to use a default priority of 0.
This section defines documentation for the library. Moya can extract tag documentation automatically for your library, and you can add supplementary documentation in a dialog of bbcode.
location = <path to documentation>
This value should be a relative path to the documentation. By convention, documentation is stored in ./docs
.
This section defines tests for your library. Tests consists of Moya code that checks the code in your library is working as expected. Well written tests ensure that you can catch bugs early, before they make it in to production.
location = <path to tests>
This setting should be a relative path to the directory containing tests, by convention this is ./tests
.
projects = <path to projects directory>
This setting should be a relative path to a directory containing projects. Your tests can load these projects on the fly and test that they are generating the expected responses.
import = <list of imports>
This setting should be a list of libraries to import when testing (i.e. dependencies of the library). An entry in this list can be a path, or a Python module if a line is prefixes with py:
.
Moya supports internationalization of text in to any language. If you intend to supply text translations for your library, then add this section.
location = <path to translations>
This should be a relative path to the directory containing message catalogs. By convention, this should be ./translations
.
default_language = <language code>
This setting defines the language used in the library. Moya needs this information when extracting text. Typically this will be 'en'
for English, but could be any language code.
languages = <comma separated list of language codes>
This should be a comma separated list of language codes, for each of the languages the library contains translations for. This language doesn't have to include the default language, which is implied. For example, a value of fr, es
would indicate the library supports French and Spanish in addition to the default language.
Moya's media system allows you to either replace individual files in the media directories, or completely swap out a media directory for another – depending on the level of customization you would like.
To override individual files, first add the following section to your project settings:
[media]location = ./static
This combines the /static
directory in your project with the files in media, so that any files in this directory take priority over the files stored in library directries. For example, lets say we want to completely replace the image logo.png
in the Sushi Finder library with our own logo. To do this, we can add the custom logo.png
to the project's static directory. So ./static
will look something like this:
`-- static`-- sushi-media`-- images`-- logo.png
Now when the browser requests /static/sushi-sushimedia/images/logo.png
it will receive the version stored in the project directory, rather than the version in the library.
The second way to customize media is to replace a media directory entirely. This can be done by creating a filesystem called <app name>_<media name>
. In the Sushi Finder application, it would be called sushi_media
. The contents of this filesystem will be used in preference to the media contained in the library.
The following section, when added to project settings, creates a media directory that completely replaces the media from then Sushi Finder library:
[fs:sushi_media]location = ./replace_sushimedia
Now, when you request any file under /static/sushi-sushimedia/
it will look for it in the ./replace_sushimedia
directory in the project.
Note that if you use this method you will probably have to replace or copy all the media files the library uses. As a starting point you can copy a library's media with the following:
$ moya fs sushi_media --copy ./replace_sushimedia
This copies all the media files from the sushi library to the replace_sushimedia
directory. You can now modify any files you wish to customize.