A Textpattern switch... case

n: smd_multi_choice | v: 0.1 | d: 469 | f: /

Plugin documentation follows this short message from our sponsor ;-)

If you like my code and deem it worthy, feel free to show your appreciation with something from my Amazon wish lists (UK or US) or donate to the Stef Dawson community coding pot by following the Donate button below to PayPal. Thanks!

Plugin list buttonDownload buttonCompressed download button

smd_multi_choice

A generic ‘if condition’ tester that can take action if some article, file, link, URL, <txp:variable /> or global PHP variable matches one or more tests. The difference between this and smd_if is that you do not need to nest successive tests because it performs comparisons using a switch... case construct.

Features

  • Supports all major article, file, and link variables such as section, category, custom fields, id, query string, author, body, excerpt, yahde yahde, plus checking url vars, server vars, txp and PHP vars
  • Tests include equality, less than, greater than, divisible by, begins, ends, contains, and ‘character’ tests such is isalpha, isnum, etc
  • Tests can either terminate when a match is found, or “fall through” to the next test (“AND” logic)
  • Multiple tests can have the same outcome (“OR” logic)
  • The tested field & matched value are available to the case container so you can display them
  • Default condition in the event no test cases match

Author

Stef Dawson.

Installation / Uninstallation

Download the plugin from either textpattern.org, or the software page, paste the code into the TXP Admin -> Plugins pane, install and enable the plugin. Visit the forum thread for more info or to report on the success or otherwise of the plugin.

To uninstall, simply delete from the Admin -> Plugins page.

Usage

The plugin gives two tags which must be used in tandem. Use <txp:smd_switch /> to tell the plugin which item you are interested in comparing against and then use one or more <txp:smd_case /> tags inside the switch to take action depending on the value.

Use the tags in any page, form or article context. Can also be used inside file, image (in the future) or link lists to take action depending on attributes of the current item.

smd_switch

At the place you wish to compare a field with a set of values, put this container tag.

Attributes

  • item : the thing you are interested in. It could be the result of another tag-in-tag, a fixed string(!), or a variable if you prefix the item with ?. Example variables are ?article_image, ?url_title, ?my_txp_var, ?my_url_var, and so on
  • look_in : list of places to look for the item. Default: SMD_ALL which checks all items in the following list, in order. You should never need to change this, but you may choose from any of the following and comma-separate each one you wish to consider:
    • txpvar : a <txp:variable />
    • svrvar : something in $_SERVER
    • file : variable from the current file in a file_download_list
    • link : variable from the current link in a linklist
    • gbl : variable from the global article context (a.k.a. $pretext)
    • article : variable from the current article
    • urlvar : something in $_GET or $_POST
    • phpvar : something in the global scope
  • leave_empty : in most cases if a variable is not set you will want it to remain that way so your switch will do nothing. But you may decide that you want the variable name itself to become the item, i.e. if you used item="?quantity" and there was no ‘quantity’ variable anywhere, it would compare against the actual word ‘quantity’. This may be useful when specifying defaults
  • debug : set to 1 to turn on diagnostic info for all contained smd_case tags

smd_case

Inside your <txp:smd_switch> container put one or more <txp:smd_case /> tags to test the item against each successive value. Case tags are usually containers that will execute the enclosed content if the value matches the item, but see example 4 for use as a self-closing tag.

Attributes

  • value : the value you want to check against. It can either be a fixed value or another field in the current context (see the <txp:smd_switch /> tag’s item attribute for info). Default: unset
  • type : the type of test you want to perform:
    • eq : Equality (the default)
    • gt : item is greater than value
    • ge : item is greater than or equal to value
    • lt : item is less than value
    • le : item is less than or equal to value
    • divisible : item is wholly divisible by value1
    • begins : item starts with value
    • contains : item has value somewhere within its contents
    • ends : item ends with value
    • isnum : value is made up entirely of digits
    • isalpha : value is made up entirely of alphabetic characters
    • isalnum : value is made up entirely of alphanumeric characters
    • islower : value is made up entirely of lower case characters2
    • isupper : value is made up entirely of upper case characters2
    • ispunct : value is made up entirely of punctuation characters
    • isspace : value is made up entirely of ‘whitespace’ characters
  • look_in : exactly the same options as for smd_switch except they apply to the value attribute
  • leave_empty : exactly the same behaviour for smd_switch except it applies to the value attribute
  • case_sensitive : whether you wish to take case into account when compare item and value; 1=yes, 0=no. Default: 0
  • numeric : whether you wish to compare the values numerically (1) instead of alpha-numerically (0). Useful when comparing numbers because ‘f’ is actually greater than ‘1’ in the ASCII table. Default: 0. Note that a numeric test is implied if using type="divisible"
  • fallthru : under normal circumstances, when one of the tests matches any further tests are ignored. Thus the order of the tests is important. Sometimes you may wish to take more than one action, e.g. if the item is greater than value1 then display something, and also display something else if it begins with value2. This type of “AND” condition is achieved by setting fallthru="1". In the event the case matches this condition, the next case tag will still be checked. For “OR” conditions, see “example 4:#eg4
  • default : inside any switch, one and only one of your case tags can be designated a ‘default’ by setting this attribute to 1. This default branch will be taken if none of the preceding case tags match anything. It is usually the last tag in a switch. Default: 0
  • debug : set to 1 to show diagnositc information for this case tag only. Default: 0

1 This test forces ‘numeric’ on automtically. Also, 0 is regarded as not wholly divisible by any value

2 case_sensitive is automatically set to 1 for these tests

Replacement variables

Some replacement variables are available within the <txp:smd_case> container so you may output the matched values directly, for example, in error messages:

  1. {smd_mc_item} (or {smd_switch}): the value of the switch item being looked at
  2. {smd_mc_value} (or {smd_case}): the value of the case value that matched the item

When testing more than one value to produce a single outcome, the most recent value that matches is the one assigned to the replacement variable.

Examples

Example 1

On your error_default page you could put this:

<txp:smd_switch item="?txp_error_code">
   <txp:smd_case value="403">
      <p>Forbidden access. Code: 403</p>
   </txp:smd_case>
   <txp:smd_case value="404">
      <p>Page not found. Code: 404</p>
   </txp:smd_case>
   <txp:smd_case value="500">
      <p>Something went horribly wrong. Code: 500</p>
   </txp:smd_case>
   <txp:smd_case default="1">
      <p>Whoops! Error code: {smd_mc_item} occurred</p>
   </txp:smd_case>
</txp:smd_switch>

Example 2

Test some value obtained from public-side form input:

<txp:smd_switch item="?quantity" look_in="urlvar">
   <txp:smd_case value="2" type="lt"
        numeric="1">
      <p>Value {smd_switch} is too small</p>
   </txp:smd_case>
   <txp:smd_case value="20" type="gt"
        numeric="1">
      <p>Value {smd_switch} is too large</p>
   </txp:smd_case>
</txp:smd_switch>

Example 3

Building on example 2, this runs the 2nd and 3rd tests regardless of whether the 2nd one returned true.

<txp:smd_switch item="?quantity" look_in="urlvar">
   <txp:smd_case value="2" type="lt"
        numeric="1">
      Value {smd_switch} is too small<br />
   </txp:smd_case>
   <txp:smd_case value="20" type="gt"
        numeric="1" fallthru="1">
      Value {smd_switch} is too large<br />
   </txp:smd_case>
   <txp:smd_case value="100" type="gt"
        numeric="1">
      ... and out of this world! <br />
   </txp:smd_case>
   <txp:smd_case default="1">
      Everything's fine
   </txp:smd_case>
</txp:smd_switch>

Thus, you see the following if you add these values to the address bar:

  • ?quantity=1 : Value 1 is too small
  • ?quantity=15 : Everything is fine
  • ?quantity=25 : Value 25 is too large
  • ?quantity=125 : Value 125 is too large… and out of this world!

Example 4

Sometimes you may want to perform the same action for a number of matches. For these instances you may use the <txp:smd_case /> tag in its Single form. List all the cases that you want to have the same outcome, then use the container of the last one to perform the action if any of the preceding cases matched.

<txp:smd_switch item="?custom1">
   <txp:smd_case value="2" type="divisible" />
   <txp:smd_case value="4" type="divisible" />
   <txp:smd_case value="10" type="divisible">
     {smd_switch} is divisible by 2, 4 or 10
   </txp:smd_case>
   <txp:smd_case value="5" type="ends" />
   <txp:smd_case value="0" type="ends">
     Yay! Numbers ending in 5 or 0 win a teddy.
   </txp:smd_case>
</txp:smd_switch>

If you add fallthru="1" to the value="10" case tag, both ‘divisible’ and ‘teddy bear’ sets of conditions would be tested and you’d see varying combinations of the output based on the contents of custom1.

Example 5

This one checks that the URL variable qty is within the range of a stock custom field.

<txp:smd_switch item="?qty">
   <txp:smd_case type="isalpha" />
   <txp:smd_case value="0">
      Please choose a valid order quantity
   </txp:smd_case>
   <txp:smd_case value="?stock" type="lt">
      There are enough of those in stock. Place order?
   </txp:smd_case>
   <txp:smd_case default="1" value="?stock">
     There are only {smd_mc_value} in stock. Please choose a lower number
   </txp:smd_case>
</txp:smd_switch>

So if someone enters ?qty=0 or ?qty=fred then a special message is shown to prompt them to enter a valid number. If the qty variable is lower than the stock level of the current article then all is well. But if any other value is used, the default condition kicks in and tells the visitor that there are not enough to satisfy their ravenous needs.

Note that the default case also uses value="?stock" even though it would appear to not be strictly necessary. It is used so the replacement variable {smd_mc_value} can be inserted in the output. If you omit the value attribute then {smd_mc_value} is not ‘primed’ because the case tag does not know where to look for the value.

Experimental software

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

Legacy software

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

Comrade Stef

Stef trying on a decidedly Eastern European hat