soo_article_filter
Summary:
like adding selection attributes to article
or article_custom
(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
soo_article_filter
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).
Requirements
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).
Overview
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.
Usage
soo_article_filter
is a container tag, intended as a wrapper for article
or article_custom
.
<txp:soo_article_filter> <txp:article /> </txp:soo_article_filter>
Note: the filter will not be applied to search results.
Attributes
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 anExpires
value. If set to “0”, only include articles without anExpires
value. (Default isnull
; no filter onExpires
.)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.article_image
(boolean) If1
, only show articles with an article image. If0
, 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 withindex_field
(Default “A,An,The”)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 anUPDATE
query on the temporary table.update_where
(SQL clause) default “1=1”. Use this in conjunction withupdate_where
to run anUPDATE
query on the temporary table.where
(SQL clause) default empty. Any text here will be added to the end of the array ofWHERE
expressions 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.
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.
Examples
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
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 /> </txp:soo_article_filter>
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 /> </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.)
Use 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 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> </txp:article> </txp:soo_article_filter>
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 /> </txp:soo_article_filter>
Technical notes
Safety
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.
Troubleshooting
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:
- In Multidoc prefs (click soo_multidoc’s “Options” link in the plugin list) set the “Show all” preference to “yes”.
- As needed, use
soo_article_filter
, withmultidoc="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.)
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)