like adding selection attributes to article or article_custom

soo_article_filter version 0.3.3, 4.1 KB
(If it won’t install try the compressed version)

Source files and archived releases available on GitHub.

As usual there’s a discussion thread on the Textpattern forum.

Full plugin help text

Including detailed tag attribute descriptions, and additional usage examples.

Courtesy soo_plugin_display


This is a plugin for Textpattern.

Code preview and compiled (ready-to-install) downloads available on the author’s website (latest release only) and on GitHub (all release versions).



This plugin relies on the trick of creating a temporary database table in memory. So the MySQL user you have assigned to Textpattern (indicated in config.php) must have CREATE privileges. If table creation fails, the plugin will return blank (as of version 0.2.5).


Contains one tag, soo_article_filter. It allows you to pre-select articles to limit the scope of an article or article_custom tag, using selection criteria not offered by those tags. In short, it’s like adding selection attributes to one of those tags.

As of version 0.2.4 there is also the option to add index-style titles to a custom field. E.g., “The First Article” becomes “First Article, The”. You can then access that custom field with the usual Txp custom field tags, allowing you to create alphabetical indexes.

As of version 0.2.6 you can do an additional UPDATE query on the temporary table, by using the update_set and update_where attributes. One use for this is to change article status from “Draft” to “Live” or “Sticky”, allowing you to display draft articles publicly.

Thanks to net-carver for clueing me in to MySQL temporary tables.


soo_article_filter is a container tag, intended as a wrapper for article or article_custom.

<txp:article />

Note: the filter will not be applied to search results.


None required, but without attributes the tag doesn’t do anything useful.

Complex selection

The selection attributes (expires, customfieldname, article_image, multidoc, and where) may be used in combination. The result is a conjunctive (AND) search, i.e., each additional attribute makes the filter more restrictive.

The where attribute allows you to enter MySQL expressions and functions for even greater power.


Only show expired articles

You must set “Publish expired articles” to “Yes” in advanced site preferences.

<txp:soo_article_filter expires="past">
<txp:article />

Only show articles with “my-custom-field” set

Note the value, ".+". This will match any character. Note also that you can accomplish the same thing without a plugin, using the technique discussed in this Txp forum thread.

<txp:soo_article_filter my-custom-field=".+">
<txp:article />

Only show articles with “my-custom-field” not set

<txp:soo_article_filter my-custom-field="">
<txp:article />

Only show articles where “my-custom-field” includes “blue”

Note: this is not case sensitive. Would match “Blues”, “true blue”, etc. article and article_custom already work this way if you add the wildcard character % (e.g., my-custom-field="%blue%"), so you don’t need this plugin just to do this.

<txp:soo_article_filter my-custom-field="blue">
<txp:article />

Only show articles where “my-custom-field” contains only digits

Note the value, "^[[:digit:]]+$". This is a MySQL regexp pattern, not a PCRE pattern.

<txp:soo_article_filter my-custom-field="^[[:digit:]]+$">
<txp:article />

Only show articles that have an article image

<txp:soo_article_filter article_image="1">
<txp:permlink><txp:article_image thumbnail="1" /></txp:permlink>

Only show the most recent article with an article image

<txp:soo_article_filter article_image="1" limit="1" sort="Posted desc">
<txp:permlink><txp:article_image thumbnail="1" /></txp:permlink>

(Note: while you could declare the limit in the article tag, this method uses less memory.)

Use where to select on a numeric range

<txp:soo_article_filter where="image BETWEEN 4 AND 27">
<txp:article />

An alphabetical index using index_ignore and index_field

<txp:soo_article_filter index_field="index_title">
<txp:article sort="custom_3 asc" wraptag="ul" break="li">
<txp:permlink><txp:custom_field name="index_title" /></txp:permlink>

When index_field is set to the name of an existing custom field, this field will receive an index-style version of the article title, e.g. “The Title” becomes “Title, The”. You can then sort on and/or display the index-style title with standard Textpattern custom field tags and attributes, as shown.

Leading words getting special treatment are those listed in index_ignore. This defaults to English articles, i.e. “A,An,The”.

The custom field has to be one you have actually created in site prefs. In the example it is called “index_title”, and it is custom field #3. When saving articles leave this field blank, otherwise soo_article_filter will leave it unchanged.

The index-style title is created only within the soo_article_filter container — corresponding custom field in the database remains blank.

Add an UPDATE query to change article status

The update_set attribute allows you to run an UPDATE query on the temporary table. For example, to temporarily change the status of all “draft” articles in the “News” section to “live” (Textpattern’s status code for “live” is 4 and for “draft” is 1):

<txp:soo_article_filter update_set="Status=4" update_where="Status=1 AND Section='News'">
<txp:article />

Technical notes


This plugin attempts to run CREATE, DROP, and, optionally, UPDATE queries. There is a safety check: if the initial CREATE TEMPORARY TABLE query fails, the plugin exits immediately, without parsing the tag contents. However, the plugin has not been tested extensively, and you should certainly keep regular database backups if you are doing anything especially interesting with this plugin. Of course, you should keep regular database backups in any event.

One thing you should absolutely NOT do is assume that it is safe to do anything you like within the tag contents. The main issue is that if the page context is search results (i.e., the q query parameter is set), the tag will simply parse its contents and return them as is. If you stuck a raw query into the tag contents on the assumption the query would only run when the temporary textpattern table exists, you’d regret it. Maybe not today, maybe not tomorrow, but soon, and for the rest of your life.


You might get an error like this: Textpattern Warning: Not unique table/alias: 'textpattern'. It seems that some configurations allow the shortcut of creating the temporary table and selecting from the actual table of the same name in the same statement, but some don’t. Performance-wise it is certainly better to use a single statement, but if this doesn’t work for you, use the alternate version of the plugin, included in the download please contact me.

If you use Multidoc and see an error message including Table 'textpattern' already exists, see the note on Multidoc compatibility, below.

Performance considerations

Most plugins that give you a souped-up equivalent of article or article_custom have to duplicate and modify doArticles() plus a couple of other core Txp functions. Less than ideal, at least in terms of ease of plugin authoring, because doArticles() is quite a lot of code to duplicate and edit in a plugin.

This plugin takes a very different approach—it creates a temporary table holding a filtered set of articles, thus allowing you to use article and/or article_custom normally. Code-wise this is very simple; performance-wise it might be inferior (I don’t know). In my limited and informal testing the extra time required for dealing with the temporary table is a non-issue. This could change with a very large textpattern (articles) table. But as long as you set soo_article_filter’s attributes so as to produce a relatively small number of articles, there shouldn’t be a problem in most cases. (Version 0.3.1 adds limit, offset, and sort attributes to make it easier to target the exact articles you want.)

Might be another story on a highly-optimized, large, high-traffic website where maximum performance is a major concern.

Multidoc compatibility

The soo_multidoc plugin also uses the temporary table trick to filter articles, which can only be done once per page load. To achieve compatibility between soo_article_filter and soo_multidoc, follow these steps:

Note that, unlike Multidoc’s built-in filter, soo_article_filter does not distinguish between list and individual article context, so if your Multidoc setup uses the same article tag for lists and individual articles you will have change this. (This is deliberate; it allows you to use soo_article_filter for an article_custom list on an individual article page.)

Version history

0.3.3 (2017/02/15)

Textpattern 4.6 compatibility update

0.3.2 (Jan 3, 2011)

Multidoc compatibility update

0.3.1 (Dec 9, 2010)

Added limit, offset, and sort attributes.

0.3.0 (Jul 11, 2010)

New attribute: where, allows you to add a raw WHERE expression to the selection criteria. (Thanks to Victor for the idea.)

0.2.7 (Jun 6, 2010)

Fixed bug in index_ignore attribute. (Thanks to th3lonius for spotting it.)

0.2.6 (Mar 8, 2010)

New attributes, update_set and update_where, allowing an additional UPDATE query on the temporary table.

0.2.5 (Feb 19, 2010)

Checks that temporary table creation was successful, else returns nothing.

0.2.4 (Feb 19, 2010)

Create properly-alphabetized indexes with the new index_ignore and index_field attributes.

0.2.3 (Jan 20, 2010)

Fixed custom field bug

0.2.2 (Sept 28, 2009)

New article_image attribute

0.2.1 (July 7, 2009)

soo_multidoc compatibility.

0.2 (July 4, 2009)

Fixed behavior of expires attribute.

0.1 (July 3, 2009)

Initial release. Allows filtering on the Expires field, and regexp pattern matching on any custom field.

Posted 2009-07-03 (last modified 2017-03-13)