Interface description for Aneamal modules

For programmers who develop modules for Aneamal

Content

Introduction

A module is a program which adds a feature that the Aneamal Translator itself does not provide. There are currently three kinds of modules:

Users can install a module easily by uploading the module folder into the aneamal directory. The name of the folder must be math for math modules and start with t- for t-modules or x- for x-modules.

In order for the Aneamal Translator to recognize the module, its folder must contain a PHP file index.php. This file should return an anonymous function which accepts an array argument. That function is the module’s main function. Here is an example index.php file:

<?php
// Avoid naming conflicts with other modules:
namespace my\own\name\space;

// Include additional php files, classes, functions,
// constants and so forth here.

// Finally, return an anonymous function to the Aneamal
// Translator. It is the entry point of the module, its
// main function. It is called whenever an author invokes
// the module. The Aneamal Translator passes data to the
// module via its first argument, an array.
return function (array $_): string {
	// Do the main processing here and return the result.
	// The return value of this function is the output of
	// the module that is integrated in the webpage.
};
// Mind the semicolon to end the return statement.

Data passed from Aneamal to modules

You can find all the data that the Aneamal Translator passes to your module in the first argument of your main function, an array. You could name the array freely, but it is recommended to name it $_ like in the code above and in the explanations below.

The array contains some values with integer indices for backwards compatibility with older modules. Please access data only using the string indices outlined below. They are available from version 28 of the Animal Translator onwards except otherwise noted.

Data passed to all modules

$_['base'], string
The URL path component to the directory where the Aneamal file which invoked the module resides.
$_['clue'], string or null
The clue from the file token in the Aneamal file which invoked the module. It is always null for math modules which are invoked without file token and null for t- and x-modules in cases where the author did not provide a clue.
$_['here'], string
The URL path component to the module’s directory. Use this, if you need to link to stylesheets, JavaScript or media files supplied with your module.
$_['home'], string
The URL path component to the Aneamal root directory.
$_['lang'], string
A language code such as en for English that applies to where the module was invoked. Use this for localization.
$_['meta'], string
The metadata value assigned to the module’s name in the Aneamal file which invoked the module. This is the recommended way to accept settings from authors for your module.
$_['name'], string
The name of the module folder. This does not include a submodule’s subfolder name. Available since version 29.
$_['pixl'], string
The setting for the size of automatically generated preview images. See @pixels metadata for an explanation and examples on how this setting is to be interpreted.
$_['root'], string
The path of the Aneamal root directory in the server file system.
$_['type'], string
The full type from the file token in the Aneamal file which invoked the module. This is equal to the module folder name and, in case of a submodule, a slash and the submodule’s subfolder name. Available since version 29.
$_['uniq'], string
A short value that can be used as HTML id or form field name for example, since it is not used elsewhere by the Aneamal Translator. Though unique in the webpage at any given time, it is not guaranteed to be permanent: it can change when Aneamal files are changed. Available since version 30.

Example

Consider that Aneamal is installed for https://example.org/ and the directory on the server which corresponds to that address and inside which the aneamal folder is located is /usr/eve/public/. Also consider that the following Aneamal text is inside a file https://example.org/test/quick.nml:

@lang: en
@t-poetry: initials

[t-poetry:funny little rhyme]
|The quick brown hog jumps over the foxy dog.

The data provided by the Aneamal Translator will be:

$_['base'] = '/test';
$_['clue'] = 'funny little rhyme';
$_['here'] = '/aneamal/t-poetry';
$_['home'] = '';
$_['lang'] = 'en';
$_['meta'] = 'initials';
$_['name'] = 't-poetry';
$_['pixl'] = '-640,-640'; // default value
$_['root'] = '/usr/eve/public';
$_['type'] = 't-poetry';
$_['uniq'] = '_tm1';

The Aneamal Translator will also supply data that is exclusive to t-modules for this example – see the section on t-modules.

Data passed to math modules only

$_['kind'], string
Either block or string, corresponding to whether the module was invoked to process a math block or a math string.
$_['math'], string
The text of the mathematical formula. Math modules should support AMS-LaTeX.

Example

Consider the following Aneamal text:

If $c$ is the longest side in a right triangle, \
its length can be calculated as

$$c=\sqrt{a^2+b^2}$$ #(1)

The math module will be invoked once when the first line is processed and again when the last line is processed. The exclusively math-related data provided by the Aneamal Translator will be

$_['kind'] = 'string';
$_['math'] = 'c';

in the first case and

$_['kind'] = 'block';
$_['math'] = 'c=\sqrt{a^2+b^2}';

in the second case.

Data passed to t-modules only

$_['text'], string
The content of the linked or embedded text file.

Example

Consider the following Aneamal text:

[t-poetry]
|The quick brown hog jumps over the foxy dog.

The data provided by the Aneamal Translator that is exclusive to t-modules will be:

$_['text'] = 'The quick brown hog jumps over the foxy dog.';

Data passed to x-modules only

$_['files'], array of string/null items
The links turned into paths in the server file system. The items will be null in cases where an interpretation as local file system paths does not make sense, for example when the provided link is a data URI or an absolute URL.
$_['hrefs'], array of string items
The links interpreted as URLs that can be used in the webpage. Mind that you should still convert characters that would otherwise have a special meaning in HTML with a function such as PHP's htmlspecialchars before using these URLs in HTML output.
$_['links'], array of string items
The links as they were provided by the author.

Example

Consider that Aneamal is installed for https://example.org/ and the directory on the server which corresponds to that address and inside which the aneamal folder is located is /usr/eve/public/. Also consider that the following Aneamal text is inside https://example.org/test/index.nml:

[x-ample]->foo->https://aneamal.org/markup/->/bar

The data provided by the Aneamal Translator that is exclusive to x-modules will be:

$_['files'] = [
	'/usr/eve/public/test/foo',
	null,
	'/usr/eve/public/bar',
];
$_['hrefs'] = [
	'/test/foo',
	'https://aneamal.org/markup/',
	'/bar',
];
$_['links'] = [
	'foo',
	'https://aneamal.org/markup/',
	'/bar',
];

Data passed to modules that use the form API

If you use the form API, the following data will also be passed to your module’s main function. Available since version 30:

$_['form'], string
ID of the HTML form element provided by the Aneamal Translator. The module must add this value in a form attribute to its HTML form fields to associate them with the form.
$_['cron'], int
A negative value means that a posted form was outdated – so its HTML code was generated before the Aneamal file was most recently edited – and could hence be incorrectly interpreted. Zero is an undefined state. A positive value means that the posted form was up-to-date.
$_['post'], array
Empty, if the form has not been submitted by the user. During a submission this array contains arrays, each of which contains data from an Aneamal block with form fields that came before the module. The composition of these block arrays varies, but each has an index block whose value is an array as well.

Example

Consider this form:

How old are you?
[_] years

Check what you have ridden!
{horse} 🐎
{bike} 🚲
{bus} 🚌
{wave} 🌊
{rooster} 🐓

[x-submit:Send!]->mailto:poll@example.org

Here is what is supplied to the x-submit module when the form has not been submitted by a user:

$_['form'] = '_fm';
$_['cron'] = 0;
$_['post'] = [];

And this is what could be supplied to the module, if a user had filled out the form with an age of 39 and checked that she had ridden a horse, a bike and a bus before:

$_['form'] = '_fm';
$_['cron'] = 1;
$_['post'] = [
    [
        'topic' => 'How old are you?',
        'block' => [
            [
                'input' => '39',
                'label' => 'years',
            ],
        ],
    ],
    [
        'topic' => 'Check what you have ridden!',
        'block' => [
            [
                'input' => 'horse',
                'label' => '🐎',
            ],
            [
                'input' => 'bike',
                'label' => '🚲',
            ],
            [
                'input' => 'bus',
                'label' => '🚌',
            ],
        ],
    ],
];

Data passed to post handlers

A module’s post handler is called before the module’s main function when a reader submits the form that the module belongs to. The data provided to the post handler and to the main function is almost identical.

The only difference is that content returned by the post handler is added to $_['post'] before that is passed to the module’s main function.


without trailing slash

Data passed from modules to Aneamal

The main way to pass data from your module to the Aneamal Translator is via the return value of the main function.

By all modules

The return value of your main function will be integrated in the webpage at the place which corresponds to where your module was invoked in the Aneamal file.

// Your module's main function:
return function (array $_): string {
	// Do your main processing here.

	// Return the result: you do not have to use a
	// variable named $output, it is just an example.
	return $output;
};

If the author of an Aneamal file made an error such as pointing your module at an invalid internet address, the module can abort in a controlled manner by throwing a ModuleMessage:

throw new \prlbr\aneamal\ModuleMessage ('The error message.');

By x-modules only

x-modules can communicate to the the Aneamal Translator how many links they expect authors to provide when using the module. This is done by adding the arguments $min and $max with default values to the argument list of your main function:

// Your module's main function:
return function (array $_, $min = 1, $max = 3): string {
	// Do your main processing here and return the result.
};
$max
A non-negative integer default value tells the Aneamal Translator to accept at most that many file links. If you do not set $max, the Aneamal Translator will only allow one link. The Aneamal Translator will not accept more than 64206 links at once, even if you set a higher value.
$min
A non-negative integer default value tells the Aneamal Translator to require at least that many file links. If you do not set $min, the Aneamal Translator will require one link.

By modules that use the form API

The form API passes data about a form and user input to modules and enables modules to contribute data from a module’s own form fields. To use the form API, add an argument $post to the argument list of your main function.

The $post argument must have a default value of type string which is either empty or the name of a function, the post handler. A function name must be supplied as it would be called from the global space. So prepend your namespace, if the post handler is defined in your namespace.

// Your module's main function:
return function (array $_, $post = __NAMESPACE__ . "\\postman"): string {
	// Do your main processing here and return the result.
};

// Your module's post handler:
function postman (array $_): array {
	// Read data from PHP's $_POST superglobal here, process
	// and return it.
}

Some modules need to receive posted data from the form API, but do not need to contribute data to the form API. You can set the $post argument to the empty string in that case:

// Your module's main function:
return function ($_, $post = ''): string {
	// Do your main processing here and return the result.
};

By post handlers

Post handlers of modules with own form fields are supposed to read user input in their responsibility from PHP’s $_POST variable, validate and process it as necessary and return it as array to be added to the Aneamal Translator’s form API.

The array returned by a post handler should contain one item for each form field that the module provides and this item should itself be an array. In it, the user input should have the index input. If a label is available for the form field, it should be provided with an index label. Example:

[
	[
		'input' => 'foolish',
		'label' => 'an adjective',
	],
	[
		'input' => 'barely interesting',
		'label' => 'an adjective phrase',
	],
]

File storage

If your module generates files, you probably do not want to store them in the module’s folder that gets overwritten when a new version of your module is uploaded. You can create a subfolder for files generated by your module in these two directories instead:

/aneamal/private
for files that are for internal use of your module only
/aneamal/public
for files that are supposed to be publicly accessible, for example generated image files or news feeds

Please name the subfolders you use within these directories identical to your module folder. You can refer to these subfolders in your PHP code using the data passed from Aneamal to modules as

$private = "$_[root]/aneamal/private/$_[name]";
$public = "$_[root]/aneamal/public/$_[name]";

The address of the public subfolder to be used in the HTML output of your module can be created in PHP like this:

$public_url = "$_[home]/aneamal/public/$_[name]";

Add a slash and your filename to this to create a link to a file in this folder. Do not forget to convert characters that would otherwise have a special meaning in HTML with a function such as PHP's htmlspecialchars before using the address in HTML output.