Don't be normal, be random

n: smd_random_text | v: 0.14 | f: /

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

Plugin list buttonPlugin download buttonCompressed plugin download button


Choose random text strings from a variety of sources. Could be used as a quote-of-the-day system, random tag lines, or something more elaborate.


  • Pull the item list from either:
    • a given delimited string
    • a file
    • a database table
    • a <txp:variable />
    • user-submitted form data
    • a Textpattern field
  • Grab as many random items as you like from your chosen list
  • Pass each to a form/the container if you wish to format them


Stef Dawson. Combines ideas from dru_random_text by Drew McLellan and simple_random_text by Manuel Ebert, plus some sprinklings of my own. Many thanks to the authors of those works.

Installation / Uninstallation

Download the plugin from either, 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.


Use the tag in any page, form or article/file/image/link context.


There are two mandatory attributes: type and source. The others are used to control how the information is extracted and/or presented.

Mandatory attributes

  • type : where to look for the pool of text strings. Can be one of string (the default), field, txpvar, urlvar, database, or file
  • source : further refinement of where to find the strings using the following rules:
    • string : a delimited list of text (e.g. source="my|cracking|words|of|the|day|in a natty little|list")
    • field : the name of the Textpattern field to look in (e.g. source="article_image" or source="my_custom_field_name")
    • txpvar : the name of a <txp:variable /> that has been defined (e.g. source="my_list")
    • urlvar : the name of a URL variable (via GET or POST) that will be passed to the page (e.g. source="property_list")
    • database : the table and column name, separated by delim (e.g. source="txp_category|title"). You may specify more than one column from the same table by listing them separated by comma. For example source="txp_discuss|message,name,discussid"
    • file : a file name relative to the root of your site, with or without leading slash (e.g. source="files/my_strings.txt")


  • limit : the number of items to pull from the list. Defaults to 1. If you specify more than the available number of items in the pool, the entire pool will be used and presented in a random order
  • form : the form to use to format the text. If not supplied, will try the container. If that’s not used either, the plugin will simply output the chosen text on its own
  • count : whether to count up (the default) or down for each random piece of text
  • trim : whether to remove whitespace from around each list item (1) or not (0). Default: 1
  • escape : escape HTML entities such as <, > and & in any text items. Use escape="" to turn it off. Default: html
  • wraptag : the (X)HTML tag with which to wrap the chosen strings, e.g. wraptag="ul". Default: unset
  • break : the (X)HTML tag to put between successive items of text, e.g. break="li". Default: unset
  • class : the CSS class to apply to the item wraptag, e.g. class="random_strings". Default: unset

Plugin configuration

  • delim : the delimiter to use between words/attribute options. Default: pipe |
  • file_delim : the delimiter to use when parsing files. If each word or phrase is on its own line then the default newline (\n) is sufficient. If you wish to have all your text strings on one line of the file delimited by some other character, set your own delimiter here. For more elaborate file structures, you may use regexes if you also set file_delim_type="regex"
  • file_delim_type : choose from either char (the default) to tell the plugin that you are splitting your file using regular ASCII characters in your file_delim, or regex to indicate you wish to use your own regular expression. Note there is no need to specify the regular expression delimiters as they will be chosen automatically based on the content of your regex
  • item_num : show this particular item from the pool. If it doesn’t exist, you get the first item. But wait?! This is a random_text plugin, why would anybody want to specify which item to use? Two uses spring to mind: Firstly, if you have already randomized your items externally you might wish to always pick, say, the first item. Secondly — and far more subtly — if you wish to pull more than one item from any randomly chosen place, you can nest smd_random_text tags and make the inner tags always use the same row/position number as the randomly chosen outer tag. See example 7
  • var_prefix : if you wish to nest smd_random_text tags then you may find that the replacement variable names clash. If that is the case you can alter the prefix to avoid this. Default: smd_rnd_txt
  • shuffle : perhaps a little pointless, this adds an extra layer of randomness to proceedings by shuffling the chosen items again. So if you had asked for 6 items in your list of 20 and the plugin had randomly chosen them in this order: 4, 17, 2, 5, 13, 11, using shuffle="1" might reorder them to 17, 5, 2, 11, 4, 13
  • debug : set to 1 to show the pool, the file name (if applicable) and the chosen items. Use 2 to see what fields and replacements are available for your use

Replacement tags

When using a form or container, use the following replacement tags to insert the relevant piece of information wherever you want it:

{smd_rnd_txt} : the text string itself (if you have altered var_prefix then this replacement name is whatever you have chosen as your prefix)
{smd_rnd_txt_rows} : the number of items in total
{smd_rnd_txt_thisrow} : the current row number
{smd_rnd_txt_thisindex} : the current row index (zero-based)
{smd_rnd_txt_chosen_item} : the zero-based index number of the actual item selected by the plugin

In addition, if you have chosen to extract multiple columns from a database table, you will have discreet replacements available for each item suffixed by the column name. So if you had used source="txp_category|name,title" you would have two extra replacements called {smd_rnd_txt_name} and {smd_rnd_txt_title}.


Example 1: Quote of the day

Read quotes from a database. The table is called “quotes” and has already been added to the TXP database (the connection must already be open). The column containing the quotes is called “text”:

<txp:smd_random_text type="database"
  <div class="qotd">Quote of the day: <br />{smd_rnd_txt}</div>

Example 2: Five random comments

<txp:smd_random_text type="database"
     source="txp_discuss|message,name" limit="5"
     wraptag="ul" break="li">
   <p><cite>{smd_rnd_txt_name}</cite> wrote:</p>

Example 3: Top 10 words

Top ten random silly words from a list in a file in the textpattern root folder, counting down from 10 to 1. Each word must be on a separate row of the file unless you alter the file_delim attribute; in which case the words must all appear on the first row of the file. If there aren’t 10 items in the file, the count begins from however high it can go.

<txp:smd_random_text type="file"
     source="words.txt" limit="10"
     form="wordout" count="down" />

and in form wordout:

#{smd_rnd_txt_thisrow} : {smd_rnd_txt} <br />

Example 4: Random e-mail address

Use a <txp:variable /> to hold a list of random e-mail addresses from which one will be selected to be sent via a zem_contact_reborn form:

<txp:variable name="emails"
     value="Aldous.Huxley|William.Shakespeare|John.Betjeman" />
     to='<txp:smd_random_text type="txpvar"
     source="emails" />'>
  // Other zem_contact options

Example 5: Random image selection

Indirectly, not just for text! Choose two random image IDs from a comma-separated list given in the custom field labelled “my_images” and display them via the built-in <txp:image /> tag.

<txp:smd_random_text type="field"
     source="my_images" limit="2" delim=",">
  <txp:image id="{smd_rnd_txt}" />

Example 6: Item from a fact file

Add this to your files form to display a random fact about each file from a pipe-delmiited list defined in the file’s description field:

<txp:smd_random_text type="field"
<br />FACT: {smd_rnd_txt}

Example 7: Keeping items in sync

Say you have a set of txp:variables that contain lists of related things:

<txp:variable name="hp_forename">
  Harry | Hermione | Ron | Severus
<txp:variable name="hp_surname">
  Potter | Granger | Weasley | Snape
<txp:variable name="hp_age">
  14 | 16 | 15 | 130

How would you ensure you retrieved the ‘column’ that corresponds with the correct value for each character? Like this:

<txp:smd_random_text type="txpvar"
     source="hp_forename" limit="2" wraptag="ul"
   Character: {smd_rnd_txt}
   <txp:smd_random_text type="txpvar"
     item_num="{smd_rnd_txt_chosen_item}" />
   is <txp:smd_random_text type="txpvar"
     item_num="{smd_rnd_txt_chosen_item}" />
   years old

As you can see, the first smd_random_text chooses two random character forenames from the first txp:variable. Then, for each of the chosen forenames, the second and third (inner) smd_random_text tags go and fetch the same column as the one just chosen. It uses {smd_rnd_txt_chosen_item} to force the plugin to read the correct column.


  • 10 Oct 08 | 0.1 | Initial release
  • 17 Mar 09 | 0.11 | Added trim and escape
  • 26 Jul 09 | 0.12 | Added item_num, shuffle and the replacement tag {smd_rnd_txt_chosen_item}
  • 28 Feb 11 | 0.13 | Permitted multiple database columns to be selected in one plugin call (thanks giampablo) ; added var_prefix
  • 03 May 11 | 0.14 | Added file_delim_type and permitted regexes in file_delim (thanks MyOtheHedgeFox)

Source code

If you’d rather dive in and out of functions, you’ll need to step into the view source page.

Legacy software

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

Experimental software

If you’re feeling brave, or fancy dipping your toe in shark-infested water, you can test out some of my beta code. It can be found on the plugin beta page.