Anatomy of a Textpattern Plugin, part 3

A PHP developer’s guide to writing Textpattern plugins.

Turning Attributes into Variables

Textpattern provides a handy function that can help manage the $atts array. You’ll see a block of code at the beginning of most tag handlers — including zem_hello_world — that looks like this:

extract(lAtts(array(
   'name'  => 'Alice',
),$atts));

The lAtts function — short for local attributes — takes two arguments (you’ll find it in textpattern/lib/txplib_misc.php if you’d like to see for yourself). The first is an array of pairs that define attribute names and their default values. In the above example, it specifies an attribute named name, with the default value of Alice. The second parameter is the $atts array itself. lAtts will step through the $atts array, fill in any missing attributes with the defaults, and return the combined result.

In typical use, shown above, the output of lAtts is fed into PHP’s extract function, which transforms each array element into a local variable, using the array key as the variable name.

In short, the extract(lAtts(...)) idiom turns tag attributes into local PHP variables. If any of the listed attributes aren’t supplied in the template tag code, the default values will be used.

zem_hello_world specifies only a single attribute, name, which — after the extract(lAtts(...)) call – becomes a local variable called $name. You can see it used in the next block of code:

return 'Hello, '.$name;

So, the following tag code:

<txp:zem_hello_world name="Carol" />

..sets $name = "Carol", producing this:

Hello, Carol

When the name attribute isn’t supplied:

<txp:zem_hello_world />

.. the default $name = "Alice" is used instead:

Hello, Alice

If an attribute is used that isn’t named in the lAtts call:

<txp:zem_hello_world flurb="bunt" />

lAtts will ignore it, so a $flurb local variable will not be created. This prevents misnamed attributes from creating unwanted local variables, and potentially overwriting important data. (Unnamed attributes will be available in the $atts array itself, however. The Textpattern parser doesn’t know which attributes your tag handler is expecting, so it includes all of them)

An easy way to experiment with attributes is to make a simple tag handler function that simply displays its attributes. Here’s an example, which introduces Textpattern’s handy dmp function:

function zem_dump_atts($atts) {
   dmp('complete atts:');
   dmp($atts);
   dmp('lAtts:');
   dmp(lAtts(array(
      'foo' => 'default foo',
      'bar' => 'default bar',
   ),$atts));
}

If you have a copy of the zem_example plugin installed, you can edit it now and paste the above code at the bottom, then try it out on a page template.

The dmp function displays a message or array on a Textpattern page, surrounded by <pre>..</pre> tags for easy viewing2. It’s your best friend for exploring and debugging Textpattern code. For example:

<txp:zem_dump_atts foo="bar" baz="bing" />
complete atts:
array (
   'foo' => 'bar',
   'baz' => 'bing',
)
lAtts:
array (
   'foo' => 'bar',
   'bar' => 'default bar',
)

Notice the difference before and after lAtts. The baz attribute is included in $atts, but not lAtts, since it’s not one of our listed attributes. And bar, which isn’t specified in the tag code, is filled in by lAtts using the default value we specified.

Previous: Textpattern Tags Next: Output

In this series


Thank you for this series. It is clearly written and extremely informative.

A fantastic resource for present and future plugin authors.

hakjoon    Mar 24, 01:51 pm    #

Great series! I’ve been hacking around with other people’s plugins – a lot of trial and mostly errors.

This series of articles is exactly what I needed in the first place.

— Anura    Mar 25, 08:57 pm    #

Commenting is closed for this article.