How to build a Textpattern plugin

This is an excerpt of a multimedia course, given to students 17 years here in Belgium, which will be at university next year. They learn computer science for 10 hours per week, to discover all the facets of this matter and make a good choice for further study, not to become professionals. In multimedia, in 2 years, they learn XHTML, CSS, some PHP, a bit of jQuery. Everything ends up together at the end in Textpattern. Each year, as a final project study, they realize Textpattern sites for real non profit clients. The last part of the projet, customer training, is sometimes difficult!

When a site is limited to introduce articles and place them in one section, no problem! Inserting an image request to navigate from one tab to another, to generate a textile link then copy/paste. A little more difficult for some people.

But … inserting a photo gallery, a slideshow, some effects on FancyBox thumbnails, often requires the insertion of several lines of code that the customer does not understand and where he can easily make mistakes.

Idea: Create a very simple plugin that behaves like a “macro”, which uses other plugins, which simplifies the code to be introduced by the site editor. A single tag (to configure or not) to insert an image with FancyBox effect, or a full gallery !

I used this idea to explain my students how to build a plugin. Then I suggested as a challenge to improve it!

Here is the course …

Before you start

  • You must have downloaded and installed the FancyBox jQuery plugin.
  • You must have installed the plugin smd_thumbnail. For each image uploaded, generate one or more thumbnails using this plugin.
  • Our plugin will simplify the integration of images, smd_thumbnails and Fancybox effects in articles.

What is a plugin in Textpattern?

This is a tag that can accept attributes (parameters), to be replaced by the XHTML it generates.

Example: <txp:image id="6" /> generates the correct XHTML code to insert the image “6” (uploaded to the server) from the data present in the Textpattern database.

Why create our own plugin here ?

Our goal : Creating a plugin that will simplify the lives of writers in Textpattern. To insert a gallery or an image with zoom effect FancyBox, they will simply introduce a Textpattern tag with one or the other attribute. No need to memorize and type in many lines of tags and configuration.

So, in an article :

<txp:fbox id="6" />


<a class="img_fancybox" href=""> 
<img src=" "width ="330" alt ="" class="fbox"/>

This simplifies the editing work for the client:

- Who does not know the full XHTML code – Who should know only a single tag syntax, together with the number (id) of the image.

If the plugin is private (reserved to the owner of one site), we can afford to encode the minimum, and place the variants in the code. If the plugin is intended to be published (posted on, we need to do a more user-friendly setup, and allow more attributes.

How to start?

1. Check the help devoted to the creation of plugins, starting from page, particularly the text annexed: the foundations of a Textpattern plugin.

2. Install the plugin ied_plugin_composer adopted by our txp dev Stef Dawson Working in ied_plugin_composer allows us to see our plugin directly integrated / compiled in our site, and so, available to test.

3. Master the basics of PHP.

Anatomy of a Plugin

1. A Textpattern tag (and thus a Textpattern plugin tag) is a PHP function!

The following function is the tag <txp:fbox />

fbox function () {

2. The function should take input arguments (parameters, attributes of the tag), then do something in a series of instructions, then return a value. The return value is a valid XHTML string.

a. The number of arguments / attributes is variable: These attributes are in fact represented here by the PHP associative array $atts where each line is an argument.

fbox function ($atts) {
    extract (lAtts (array (
       'id' =>'',
       'type' =>''),$atts));

The first step is to extract simple variables in the table rows, with the PHP extract(). Textpattern lAtts() function verifies that the parameters entered by the user are expected and listed behind array().
Between the quotes behind the names of attributes, one can place a default value.

b. Because function must return a string containing an XHTML link on a specific class and type label , leading to the big picture related to the thumbnail image … we must collect this information before building the string in one or more instructions.


First using an existing Textpattern tag (<txp:image_url />) and the corresponding plugin smd_thumbnail used on the site to generate thumbnails of various sizes (<txp:smd_thumbnail />).

A Textpattern tag is a PHP function!

Just understand how to call the function for the two tags, and how to pass the parameters expected in the form of an associative array (see here with the tag <txp:image_url />:

$img_url=image_url(array ('id' => '6 '));

And for the plugins, it’s the same thing!

It suffices that the plugin is installed. It calls the functions corresponding to the tag without the txp: initial. <txp:smd_thumbnail /> become smd_thumbnail();

$thumb_url=smd_thumbnail(array ('id' => '6 ',' type '=>' vignettes_340 ',' class' => 'fbox'));

In both examples above, the XHTML string generated is saved in a variable that will be used later.

c. At the end, we must build the string to return, in a conventional manner:

$xhtml = '<a class="img_fancybox" href="'.$img_url.'">' .$thumb_url. '</ a>';

Then ensure that the function returns this string, using the return statement. When the function encounters the return keyword, it evaluates the following value and returns to the calling program. Finally, the function ends.

return $xhtml;

Full version (almost) final

fbox function ($ atts) {
    extract (lAtts (array (
            'id' =>'',
            'type' =>''
            ), $atts));
    $img_url = image_url (array ('id' => $ id));
    $thumb_url = smd_thumbnail (array ('id' => $id,
                 'type' => $type, 'class' => 'fbox'));
    $xhtml = '<a class = "img_fancybox"
                 href ="'.$img_url .'">'.$thumb_url. '</ a>';
    return $xhtml;

Note that this tag takes two attributes (the function expects two arguments): id and type. We also note that several elements in the instructions may vary and could be passed as arguments: the two classes. The function might therefore become:

fbox function ($atts) {
    extract (lAtts (array (
            'id' =>'',
            'type' => 'vignette_340'
            'thumb_class' => 'fbox'
            'fancybox_class' => 'img_fancybox'
                  ), $atts));
    $img_url = image_url (array ('id' => $ id));
    $thumb_url = smd_thumbnail = (array ('id' => $ id,
                 'type' => $type, 'class' => $thumb_class));
    $xhtml = '<a class ="'.$ fancybox_class. "
                 href ="'.$ img_url .'">'.$ thumb_url. '</ a>';
    return $xhtml;

It thus becomes flexible, accepting at least one argument (the id of the image, if the defaults are OK), and up to 4 settings if you change the type of thumbnail (created in smd_thumbnail), the class of the hyperlink that acts FancyBox, the class of the image (thumbnail) to style its appearance on the page.

Naming your plugin

If your plugin is for private use, his name should not be the same as that of a PHP / existing Textpattern function.

If you are looking for fame, you can publish your plugin ( You will have to precede your plugin a prefix of three letters, like smd_, adi_, zem_, etc.
The plugin above could be called jpd_fbox example.

What resources are available for plugin authors?

1. In addition to what was cited above, an interesting resource is the interactive navigation in the source code of Textpattern. PHPxref Interactive means you can navigate through a hyperlink to the functions created in TXP, and to the native PHP functions.

2. Since all the functions created in TXP can be used in plugins, do not reinvent the wheel, and use that exists, particularly the management functions of databases:
Documentation on Database Functions

3. Extending Textpattern is the entry point of the essential documentation regarding this.

comments powered by Disqus