This is a plugin for Textpattern.
- Technical notes
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_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_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
<txp:soo_article_filter> <txp:article /> </txp:soo_article_filter>
Note: the filter will not be applied to search results.
None required, but without attributes the tag doesn’t do anything useful.
expires(“past”, “future”, “any”, or 0)
If set to “past”, “future”, or “any”, only include articles with an
Expiresvalue. If set to “0”, only include articles without an
Expiresvalue. (%(default)Default% is
null; no filter on
customfieldname(empty or regexp pattern) replace “customfieldname” with any custom field name as set in site preferences. If the attribute value is empty, only articles with an empty value for this custom field will be included. Otherwise the attribute value will be treated as a MySQL regular expression pattern.
1, only show articles with an article image. If
0, only show articles without an article image. If not set (the default), article image has no effect.
multidoc(boolean) default false
For use with the soo_multidoc plugin. See note below.
index_ignore(list) Comma-separated list of leading articles to transpose, when used in combination with
index_field(custom field name) Set this to the name of an existing custom field to hold index-style titles (e.g. “The Title” becomes “Title, The”). Default empty.
update_set(SQL clause) default empty. Set this (and, optionally,
update_where) to run an
UPDATEquery on the temporary table.
update_where(SQL clause) default “1=1”. Use this in conjunction with
update_whereto run an
UPDATEquery on the temporary table.
where(SQL clause) default empty. Any text here will be added to the end of the array of
WHEREexpressions used for article selection.
limit(integer) Number of articles to select. default unset, no limit.
offset(integer) Number of articles to skip. default unset, no offset.
sort(Column [direction]) Sort column (and optional sort direction), e.g.
Posted asc. default unset.
The selection attributes (
where) may be used in combination. The result is a conjunctive (
AND) search, i.e., each additional attribute makes the filter more restrictive.
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 /> </txp:soo_article_filter>
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 /> </txp:soo_article_filter>
Only show articles with “my-custom-field” not set
<txp:soo_article_filter my-custom-field=""> <txp:article /> </txp:soo_article_filter>
Only show articles where “my-custom-field” includes “blue”
Note: this is not case sensitive. Would match “Blues”, “true blue”, etc.
article_custom already work this way if you add the wildcard character
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 /> </txp:soo_article_filter>
Only show articles where “my-custom-field” contains only digits
<txp:soo_article_filter my-custom-field="^[[:digit:]]+$"> <txp:article /> </txp:soo_article_filter>
Only show articles that have an article image
<txp:soo_article_filter article_image="1"> <txp:article> <txp:permlink><txp:article_image thumbnail="1" /></txp:permlink> </txp:article> </txp:soo_article_filter>
Only show the most recent article with an article image
<txp:soo_article_filter article_image="1" limit="1" sort="Posted desc"> <txp:article> <txp:permlink><txp:article_image thumbnail="1" /></txp:permlink> </txp:article> </txp:soo_article_filter>
(Note: while you could declare the
limit in the
article tag, this method uses less memory.)
where to select on a numeric range
<txp:soo_article_filter where="image BETWEEN 4 AND 27"> <txp:article /> </txp:soo_article_filter>
An alphabetical index using
<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> </txp:article> </txp:soo_article_filter>
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.
UPDATE query to change article status
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 /> </txp:soo_article_filter>
This plugin attempts to run
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.
Most plugins that give you a souped-up equivalent of
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_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
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.
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:
- In Multidoc prefs (click *soo_multidoc*’s “Options” link in the plugin list) set the “Show all” preference to “yes”.
- As needed, use
multidoc="1", to filter Multidoc interior pages.
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.)
Textpattern 4.6 compatibility update
0.3.2 (Jan 3, 2011)
Multidoc compatibility update
0.3.1 (Dec 9, 2010)
0.3.0 (Jul 11, 2010)
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)
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
0.2.3 (Jan 20, 2010)
Fixed custom field bug
0.2.2 (Sept 28, 2009)
0.2.1 (July 7, 2009)
0.2 (July 4, 2009)
Fixed behavior of
0.1 (July 3, 2009)
Initial release. Allows filtering on the
Expires field, and regexp pattern matching on any custom field.