Moya Thumbnail

Moya Thumbnail is a solution for generate thumbnails (smaller versions of a image). Although it could be used for a variety of image processing purposes.

Installation

Moya Thumbnail is built in to Moya and may be imported via its Python path as follows:

<import py="moya.libs.thumbnail" />

It can then be installed with the following:

<install name="thumbnail" lib="moya.thumbnail"/>

No views are required for this library, but there is a test view which processes upload images in to thumbnails. You can mount this with the following:

<mount app="thumbnail" mountpoint="tests" url="/thumbtest/" />

Namespace

Tags in this library use the namespace http://moyaproject.com/thumbnail. The test view and the examples here use the prefix tn for brevity.

Settings

Moya Thumbnail supports the following settings:

fs = <FS NAME>

This sets the filesystem where the images and generated thumbnails should be stored. By default this is uploads which should be a writable filesytem.

app_serve = uploads

This should be the application which serves the thumbnail filesystem. It is used to retrieve a named url called serve. This will typically be an instance of moya.static, installed as follows:

<!-- in your server.xml -->
<install name="uploads" lib="moya.static" mount="/uploads/" />

And the follow settings in your basesettings.ini:

[settings:uploads]
fs = uploads

thumb_dir = <NAME OF THUMBNAIL DIRECTOR>

This should be the name to use for the directory containing the thumbnails. Moya Thumbnail creates a directory of this name to hold the thumbnails. The default is thumbnails.

Generate Thumbnails

The purpose of Moya Thumbnail is to process an image in to different versions; so that you have flexibility on how the image is displayed. For example, you might have a small 80x80 pixel version to go in a table, or a larger 640x480 version to embed in an article, etc.

To create image processors, define a <thumbnails> which is a container for the various image formats you wish to supply. Inside <thumbnails> should be a <processor> tag for each format. Here's an example:

<tn:thumbnails libname="thumbnails.tests">

    <tn:processor name="small">
        <image:resize-to-fit width="80" height="80" />
    </tn:processor>

</tn:thumbnails>

The code above defines a single thumbnail processor called small. Moya calls the code inside the <processor> with the value image containing the image to be processed. The <resize-to-fit> tag resized the image.

Note, that if you don't specify the image to process, the <resize-to-fit> tag (and other image tags) will use a value called image from the local scope – which is why we don't need to specify it above.

To generate the thumbnails, use the <generate> tag, which takes the element reference of the <thumbnails> you which to use, and the path of the image file. Here's an example:

<tn:generate thumbnails="#thumbnails.tests" test="profile.jpg"/>

When the above code runs, it will create a sub-directory (called thumbnails by default) used to store the thumbnails. The filename of the thumbnail is generate from the name and version attribute of the <processor>. The version number is so that a new image can be generated if you update the processor. Simply increment the version number when you make a change to the processor.

Processing Uploads

The most common use of the Moya Thumbnail library is to process images uploaded by the user. The thumbnails can be generates in the same view that generates the form. Here's an example

<!-- a form containing a file upload field -->
<form xmlns="http://moyaproject.com/forms" docname="form.upload" style="horizontal"
    legend="Thumbnail Test">
    <upload name="upload_image" label="Image" required="yes"/>
    <submit-button name="submit"/>
</form>

<!-- the view to handle the form -->
<view docname="view.upload" content="content.upload">
    <forms:get form="form.upload" dst="form" />
    <forms:validate src="form">
        <let filename="form.data.upload_image.filename" />
        <fs:set-contents fs="uploads" path="${filename}" contents="form.data.upload_image" />
        <tn:generate thumbnails="#thumbnails.tests" path="${filename}" />
        <let success="yes" />
    </forms:validate>
</view>

When the form validates successfully, the upload field will be stored in form.data.upload_image. File fields have two parameters; filename contains the filename from the user's computer (minus the path), and file is a file object, which may be copied to a filesystem (see <set-contents>).

Once the file has been copied to the uploads filesystem, the <generate> tag can create the thumbnails.

Managing Filenames

Note that Moya Thumbnail doesn't manage image filenames for you. You will need to come up with a scheme to ensure that your image filenames are unique, or risk overwriting a previous upload. Probably the simplest way to do this would be to incorporate the primary key of a database object in to the filename or path. For example the image for a profile with a primary key of 5 would be profile.5.jpg.

Generate Command

Moya Thumbnail supplies a command to generate new thumbnails in a filesystem. This might be necessary if you have updated / added thumbnail formats and you want to generate the thumbnails for previously uploaded images.

The following command will generate new thumbnails for all <thumbnails> tags.

$ moya moya.thumbnail#cmd.generate

You may also specify one or more <thumbnails> tags on the command line to only generate thumbnails for those tags. For example:

$ moya moya.thumbnail#cmd.generate sushifinder#thumbnails.products

Thumbnails in Templates

To display a thumbnail in a template, use the thumbnail_url filter, which takes the filename of the image and returns its url. Here's an example:

<img src="${'profile.jpg' | "thumbnail_url from moya.thumbnail"(processor=small)}">

The thumbnail filter takes the name of the processor as a parameter, and will return a URL for that thumbnail.