Virtual tagalizer

n: smd_macro | v: 0.41 | f: /

Documentation for the Textpattern plugin smd_macro by Stef Dawson follows this short message from our sponsor ;-)

Plugin list button Plugin download button Compressed plugin download button


Build your own virtual Textpattern tags from combinations of built-in tags and plugins — even PHP. Thus you can ease your workflow or offer your clients simpler syntax for doing powerful things in their Pages, Forms, and Articles.


  • Define macros — custom, virtual Txp tags — with any number of attributes
  • Construct a definition block — like a Txp Form — that contains the tags / code that make up your macro
  • Inject replacement values (read from your attributes) into macro definitions at runtime
  • Import / export macros for archive / sharing with the community
  • Macros can be single or containers

Installation / uninstallation

Requires Textpattern 4.5.2+

Download the plugin from either, or the software page, paste the code into the Txp Admin -> Plugins pane, install and enable the plugin. To uninstall, delete from the Admin -> Plugins page.

Visit the forum thread for more info or to report on the success or otherwise of the plugin.


Visit the Content -> Macros tab. When there are macros defined, the dropdown at the top-right of the panel contains a list of all macros that have been defined. Choose one to load it into the boxes below for editing.

The boxes are:

  • Name : name of your macro/virtual tag1. Click the adjacent [x] button to delete it.
  • Description : optional description for your own documentation — not used anywhere else at present.
  • Attributes : specify up to three values for each attribute2. Click the [+] button to create more. Clear the name box before Saving to delete that attribute. The three values are:
    • Name : the name of your attribute that clients will use in your tag. Must be a valid ASCII name.
    • Default : the default value that this attribute will take on if not supplied. Leave empty for "".
    • Replacement : the name of the {replacement} that this attribute will occupy in your definitions. Specify it without the {} brackets. If this entry is omitted, the attribute’s Name will be used.
  • Macro definition : your tag code here. At any point you can insert the name of any of your defined attribute replacement values inside {} marks to have the plugin inject the attribute into your markup when the client uses the tag. See examples for more.

1 IMPORTANT: your tag MUST adhere to the following conventions:

  • an ASCII name — no foreign characters, hyphens or anything other than alphanumeric characters and underscores. In addition it may not begin with a number.
  • double check before saving that your tag does not have the same name as an existing Txp or PHP function. If it does, your site WILL blow up with nasty errors. The best way to avoid this is to make sure you prefix your tags with a three-letter prefix, just as you would if this was your own plugin.

The plugin tries to shield you from invalid names as far as possible and will usually detect internal PHP/Txp function name clashes, admin-side plugin clashes as well as invalid/previously defined macro names. But it cannot legislate for functions that are going to become available on your public site, i.e. tags/functions added by public-side plugins. Please exercise caution when naming your macros.

2 Make sure you avoid the pipe symbol | in your attribute names / defaults / replacements as this character is used internally by the plugin.

Container macros

You may use your new macros as container tags. In your macro definition, specify the special replacement tag {smd_container} where you want the contained content to go. If the container is empty, nothing is output unless you define an attribute named smd_container and give it some Default content. In that case, your {smd_container} replacement tag will take on the default value assigned to that attribute. Note that the Replacement name doesn’t matter and can be omitted: the replacement is always going to be {smd_container}.

Note this means that if you add an attribute smd_container="some value" to your macro when it’s used in your page, it does the same thing as using the container. This could be construed a feature.

Importing macros

You can import macros that have been previously exported from the plugin. Click the Import link and choose the smd_macros.ini file that you have been given (the file name itself doesn’t actually matter). If you want to overwrite any macros of the same name that already exist in your system, check the Force overwrite box. Otherwise, any macros in the import file that already exist will be skipped.

Note that the plugin makes some checks on your system and will try and bail out gracefully if the necessary permissions are not set (it temporarily uploads files to Txp’s temp directory, as defined in Advanced Prefs). It also imposes a soft limit of roughly 15KB on the size of the imported file, mostly for reasons of speed. If you find yourself requiring to import large numbers of macros in one file, you can increase this limit by creating the following global system preference (smd_prefalizer can help):

  • Pref name: smd_macro_import_filesize
  • Value : maximum file size (in bytes)
  • Visibility : Hidden
  • Event : smd_macro

Alternatively, split your macros into a few smaller files and import them separately.

Exporting macros

At any time you can export one or more macros to a file for distribution or backup. Just click the Export link and choose one or more macros from the list that appears. Click Go and then save the resulting file to your filesystem. The current macro that is being edited (if any) is selected by default.

Cloning macros

While a macro is loaded into the edit boxes you can clone it. Click the Clone button, supply a name for the clone and hit Go. Provided the name isn’t invalid or in use, your new clone will be created and brought into the edit area for immediate editing.

Note that the clone will be created from the chosen macro as it was last saved to the database. If you have made unsaved edits to the macro in the edit boxes at the time you clone the macro, they will be lost.


Example 1: image gallery

  • Macro name : my_gallery
  • Attributes (default / replacement) : category (empty / img_cat)
<txp:images category="{img_cat}">
   <txp:image />
   <div class="img_info"><txp:image_info /> by <txp:image_author /></div>

Thus, <txp:my_gallery category="animals" /> will render an image gallery from the given category, complete with caption and author info. Note that no default value is given so if the category attribute is not supplied, no gallery will be produced.

Example 2: interface to smd_query

  • Macro name : my_col_from_table
  • Attributes (default / replacement) : column (ID / col), table (textpattern)
<p>The contents of the {col} column
from the {table} table is:</p>
<txp:smd_query column="{col}" table="{table}"
     wraptag="ul" break="li">

Anybody using <txp:my_col_from_table column="Title" /> would see a list of all article titles. If they added table="txp_file" they’d see all titles from all uploaded files. Things to note:

  • No replacement variable specified for the table attribute, therefore it takes on the name of the attribute itself.
  • The double set of {{}} in the smd_query container is required because you first want the macro to replace {col} with the value from your macro’s column attribute, i.e. if you’d chosen column="Posted" then {{col}} becomes {Posted}. After that, smd_query searches for {Posted} and replaces it with the contents of the ‘Posted’ column for each row in the table.

Author / credits

Written by Stef Dawson. Spawned from an idea by jpdupont, with thanks. Also big props to the beta test team: primarily jpdupont, pieman, mrdale, maverick, maruchan and jakob.

Source code

If you’d rather spend time with the bytes, you’ll need to step into the view source page.

Legacy software

If, for some inexplicable reason, you need an ancient version of a plugin, it can probably be found on the plugin archive page.

Experimental software

If you’re feeling brave, or fancy going bareback, you can test out some of my beta code. It can be found on the plugin beta page.