/rah_repeat/rah_repeat.php
PHP | 670 lines | 421 code | 161 blank | 88 comment | 35 complexity | 104143185afd1804a061cf10cee95ccd MD5 | raw file
- <?php
- // This is a PLUGIN TEMPLATE for Textpattern CMS.
- // Copy this file to a new name like abc_myplugin.php. Edit the code, then
- // run this file at the command line to produce a plugin for distribution:
- // $ php abc_myplugin.php > abc_myplugin-0.1.txt
- // Plugin name is optional. If unset, it will be extracted from the current
- // file name. Plugin names should start with a three letter prefix which is
- // unique and reserved for each plugin author ("abc" is just an example).
- // Uncomment and edit this line to override:
- $plugin['name'] = 'rah_repeat';
- // Allow raw HTML help, as opposed to Textile.
- // 0 = Plugin help is in Textile format, no raw HTML allowed (default).
- // 1 = Plugin help is in raw HTML. Not recommended.
- # $plugin['allow_html_help'] = 1;
- $plugin['version'] = '1.0.1';
- $plugin['author'] = 'Jukka Svahn';
- $plugin['author_uri'] = 'http://rahforum.biz';
- $plugin['description'] = 'Iterations made easy';
- // Plugin load order:
- // The default value of 5 would fit most plugins, while for instance comment
- // spam evaluators or URL redirectors would probably want to run earlier
- // (1...4) to prepare the environment for everything else that follows.
- // Values 6...9 should be considered for plugins which would work late.
- // This order is user-overrideable.
- $plugin['order'] = '5';
- // Plugin 'type' defines where the plugin is loaded
- // 0 = public : only on the public side of the website (default)
- // 1 = public+admin : on both the public and admin side
- // 2 = library : only when include_plugin() or require_plugin() is called
- // 3 = admin : only on the admin side (no AJAX)
- // 4 = admin+ajax : only on the admin side (AJAX supported)
- // 5 = public+admin+ajax : on both the public and admin side (AJAX supported)
- $plugin['type'] = '0';
- // Plugin "flags" signal the presence of optional capabilities to the core plugin loader.
- // Use an appropriately OR-ed combination of these flags.
- // The four high-order bits 0xf000 are available for this plugin's private use
- if (!defined('PLUGIN_HAS_PREFS')) define('PLUGIN_HAS_PREFS', 0x0001); // This plugin wants to receive "plugin_prefs.{$plugin['name']}" events
- if (!defined('PLUGIN_LIFECYCLE_NOTIFY')) define('PLUGIN_LIFECYCLE_NOTIFY', 0x0002); // This plugin wants to receive "plugin_lifecycle.{$plugin['name']}" events
- $plugin['flags'] = '0';
- // Plugin 'textpack' is optional. It provides i18n strings to be used in conjunction with gTxt().
- // Syntax:
- // ## arbitrary comment
- // #@event
- // #@language ISO-LANGUAGE-CODE
- // abc_string_name => Localized String
- /** Uncomment me, if you need a textpack
- $plugin['textpack'] = <<<EOT
- #@admin
- #@language en-gb
- abc_sample_string => Sample String
- abc_one_more => One more
- #@language de-de
- abc_sample_string => Beispieltext
- abc_one_more => Noch einer
- EOT;
- **/
- // End of textpack
- if (!defined('txpinterface'))
- @include_once('zem_tpl.php');
- # --- BEGIN PLUGIN CODE ---
- /**
- * Rah_repeat plugin for Textpattern CMS.
- *
- * @author Jukka Svahn
- * @license GNU GPLv2
- * @link http://rahforum.biz/plugins/rah_repeat
- *
- * Copyright (C) 2013 Jukka Svahn http://rahforum.biz
- * Licensed under GNU Genral Public License version 2
- * http://www.gnu.org/licenses/gpl-2.0.html
- */
- /**
- * Creates a list from the given values.
- *
- * @param array $atts
- * @param string $thing
- * @return string
- */
- function rah_repeat($atts, $thing = null)
- {
- global $rah_repeat, $variable;
- extract(lAtts(array(
- 'form' => '',
- 'delimiter' => ',',
- 'value' => '',
- 'limit' => null,
- 'offset' => 0,
- 'wraptag' => '',
- 'break' => '',
- 'class' => '',
- 'duplicates' => 0,
- 'sort' => '',
- 'exclude' => null,
- 'trim' => 1,
- 'range' => '',
- 'assign' => null,
- ), $atts));
- if ($range && strpos($range, ','))
- {
- $values = call_user_func_array('range', do_list($range));
- }
- else
- {
- $values = explode($delimiter, $value);
- }
- if ($trim)
- {
- $values = doArray($values, 'trim');
- }
- if ($duplicates)
- {
- $values = array_unique($values);
- }
- if ($exclude !== null)
- {
- $exclude = explode($delimiter, $exclude);
- if ($trim)
- {
- $exclude = doArray($exclude, 'trim');
- }
- $values = array_diff($values, $exclude);
- }
- if ($sort && $sort = doArray(doArray(explode(' ', trim($sort), 2), 'trim'), 'strtoupper'))
- {
- if (count($sort) == 2 && defined('SORT_'.$sort[0]))
- {
- sort($values, constant('SORT_'.$sort[0]));
- }
- if (end($sort) == 'DESC')
- {
- $values = array_reverse($values);
- }
- }
- $values = array_slice($values, $offset, $limit);
- if ($assign !== null)
- {
- foreach (do_list($assign) as $key => $var)
- {
- $value = isset($values[$key]) ? $values[$key] : '';
- $variable[$var] = $value;
- }
- }
- if (!$values || ($thing === null && $form === ''))
- {
- return '';
- }
- $count = count($values);
- $i = 0;
- $out = array();
- foreach ($values as $string)
- {
- $i++;
- $parent = $rah_repeat;
- $rah_repeat = array(
- 'string' => $string,
- 'first' => ($i == 1),
- 'last' => ($count == $i),
- 'index' => $i - 1,
- );
- if ($thing === null && $form !== '')
- {
- $out[] = parse_form($form);
- }
- else
- {
- $out[] = parse($thing);
- }
- $rah_repeat = $parent;
- }
- unset($rah_repeat);
- return doWrap($out, $wraptag, $break, $class);
- }
- /**
- * Returns the current value.
- *
- * @param array $atts
- * @return string
- */
- function rah_repeat_value($atts)
- {
- global $rah_repeat;
- extract(lAtts(array(
- 'escape' => 0,
- 'index' => 0,
- ), $atts));
- if (!isset($rah_repeat['string']))
- {
- return '';
- }
- if ($index)
- {
- return $rah_repeat['index'];
- }
- if ($escape)
- {
- return txpspecialchars($rah_repeat['string']);
- }
- return $rah_repeat['string'];
- }
- /**
- * Checks if the item is the first.
- *
- * @param array $atts
- * @param string $thing
- * @return string
- */
- function rah_repeat_if_first($atts, $thing = '')
- {
- global $rah_repeat;
- return parse(EvalElse($thing, $rah_repeat['first'] == true));
- }
- /**
- * Checks if the item is the last.
- *
- * @param array $atts
- * @param string $thing
- * @return string
- */
- function rah_repeat_if_last($atts, $thing = '')
- {
- global $rah_repeat;
- return parse(EvalElse($thing, $rah_repeat['last'] == true));
- }
- # --- END PLUGIN CODE ---
- if (0) {
- ?>
- <!--
- # --- BEGIN PLUGIN HELP ---
- <h1>rah_repeat</h1>
- <p><a href="http://rahforum.biz/plugins/rah_repeat" rel="nofollow">Project page</a> | <a href="https://packagist.org/packages/rah/rah_repeat" rel="nofollow">Packagist</a> | <a href="http://twitter.com/gocom" rel="nofollow">Twitter</a> | <a href="https://github.com/gocom/rah_repeat" rel="nofollow">GitHub</a> | <a href="http://forum.textpattern.com/viewtopic.php?id=32384" rel="nofollow">Support forum</a> | <a href="http://rahforum.biz/donate/rah_repeat" rel="nofollow">Donate</a></p>
- <p>Rah_repeat is a <a href="http://www.textpattern.com" rel="nofollow">Textpattern <span class="caps">CMS</span></a> plugin used for iterations. The plugin splits a provided value to smaller chunks and iterates overs, just like you would expect from a for each loop in any programming language. With the plugin you can turn a simple comma-separated list of values into advanced <span class="caps">HTML</span> output, or extract parts of a value as <a href="http://textpattern.net/wiki/index.php?title=variable" rel="nofollow">variables</a>.</p>
- <h2>Requirements</h2>
- <p>Rah_repeat’s minimum requirements:</p>
- <ul>
- <li>Textpattern 4.5.0 or newer.</li>
- </ul>
- <h2>Installing</h2>
- <p>Rah_repeat’s installation follows the standard plugin installation steps.</p>
- <ol>
- <li>Download the plugin installation code.</li>
- <li>Copy and paste the installation code into the <em>Install plugin</em> box of your Textpattern Plugin pane.</li>
- <li>Run the automated setup.</li>
- <li>After the setup is done, activate the plugin. Done.</li>
- </ol>
- <h2>Basics</h2>
- <pre><code><txp:rah_repeat range="min, max, step" value="value1, value2, ..." assign="variable1, variable2, ...">
- ...contained statement...
- </txp:rah_repeat></code></pre>
- <p>Rah_repeat’s main job is primely iterating over values. Its iteration power can used to create lists or extract subsets of data. The plugin can come very handy when you have a <a href="http://textpattern.net/wiki/index.php?title=custom_field" rel="nofollow">custom field</a> that contains comma-separated list of values which you want to present as a <span class="caps">HTML</span> list or extract as individual separate values.</p>
- <p>The values you want to iterate over are provided to the tag with the <code>value</code> attribute, each individual subset value separated from each other with the <code>delimiter</code>, defaulting to a comma. The current value that is being iterated over can be returned using the <code>rah_repeat_value</code> tag, wrapped in <code>rah_repeat</code> block. The following would generate a <span class="caps">HTML</span> list from comma-separated list of <code>red, blue, green</code>.</p>
- <pre><code><txp:rah_repeat value="red, blue, green" wraptag="ul" break="li">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>In addition to iterating over values and creating lists, the tag can also be used to extract values and assign each one to a <a href="http://textpattern.net/wiki/index.php?title=variable" rel="nofollow">variable</a> tag. This can be done using the <code>rah_repeat</code> tag’s <code>assign</code> attribute. The attribute takes a comma-separated list of variable names that will be created, each containing one of the values.</p>
- <pre><code><txp:rah_repeat value="red, blue, green" assign="color1, color2, color3" /></code></pre>
- <p>The above would extra each of the colors as a variable. These variables would be named as <code>color1</code>, <code>color2</code> and <code>color3</code>. Using <code><txp:variable name="color1" /></code> would return <code>red</code>.</p>
- <h2>Tags and attributes</h2>
- <p>The plugin comes with a total of four tags. The main tag <code>rah_repeat</code>, a single tag <code>rah_repeat_value</code>, and two conditionals <code>rah_repeat_if_first</code> and <code>rah_repeat_if_last</code>.</p>
- <h3>rah_repeat</h3>
- <pre><code><txp:rah_repeat value="value1, value2, ...">
- ...contained statement...
- </txp:rah_repeat></code></pre>
- <p>The <code><txp:rah_repeat></code> tag is the plugin’s main tag. It’s a container tag used for iterations. Attributes for it are as follows.</p>
- <p><strong>value</strong><br />
- Sets the values that are passed to the tag. Multiple values are separated with the <code>delimiter</code> which by default is a comma (<code>,</code>). This attribute or either <code>range</code> is required.<br />
- Example: <code>value="dog,cat,human"</code> Default: <code>""</code></p>
- <p><strong>range</strong><br />
- Creates a list of values containing a range of elements. Using <code>range</code> overrides <code>value</code> attribute. It works identically to <span class="caps">PHP</span>’s <a href="http://php.net/manual/en/function.range.php" rel="nofollow">range</a> function and uses same sequence syntax as it. The attribute’s value consists of three parts: <code>minimum</code>, <code>maximum</code> and <code>step</code>, which are separated by a comma. All but <code>step</code> are required.<br />
- Example: <code>range="1, 10"</code> Default: undefined</p>
- <p><strong>delimiter</strong><br />
- Sets the delimiter that is used to split the provided <code>value</code> into a list. Default delimiter is comma (<code>,</code>).<br />
- Example: <code>delimiter="|"</code> Default: <code>","</code></p>
- <p><strong>assign</strong><br />
- Assigns values as Textpattern’s <a href="http://textpattern.net/wiki/index.php?title=variable" rel="nofollow">variables</a>. Takes a comma-separated list of variable names: <code>variable1, variable2, variable3, ...</code>.<br />
- Example: <code>assign="label, value"</code> Default: <code>unset</code></p>
- <p><strong>duplicates</strong><br />
- Removes duplicate values from the list. If the attribute is set to <code>1</code>, only first occurrence of the value is used and duplicates are stripped off.<br />
- Example: <code>duplicates="1"</code> Default: <code>"0"</code></p>
- <p><strong>exclude</strong><br />
- Exclude certain values from the list. The attribute takes a comma (or <code>delimiter</code>, if <code>delimiter</code> is changed) separated list of values.<br />
- Example: <code>exclude="foo,bar"</code> Default: undefined</p>
- <p><strong>trim</strong><br />
- Trims values from extra whitespace. This can be particularly helpful if the provided values are from user-input (e.g. from an article field), or the values just have extra whitespace, and the resulting output has to be clean (i.e. used in <span class="caps">XML</span>, JavaScript or to a <a href="http://textpattern.net/wiki/index.php?title=variable" rel="nofollow">variable</a> comparison). If you want to keep whitespace intact, you can use this attribute. By default the option is on, and values are trimmed.<br />
- Example: <code>trim="0"</code> Default: <code>"1"</code></p>
- <p><strong>sort</strong><br />
- Sorts the values. If the attribute is used, all values are rearranged to the specified order. Available options are <code>regular</code> (sorts without checking the type), <code>numeric</code> (sorts in a numeric order), <code>string</code> (sorts as strings) and <code>locale_string</code> (sorts according server’s locale settings). All the values can be followed by the sorting direction, either <code>desc</code> and <code>asc</code>. By default the option isn’t used (unset), and the values are returned in the order they were supplied.<br />
- Example: <code>sort="regular asc"</code> Default: <code>""</code></p>
- <p><strong>offset</strong><br />
- The number of items to skip. Default is <code>0</code> (none).<br />
- Example: <code>offset="5"</code> Default: <code>"0"</code></p>
- <p><strong>limit</strong><br />
- The number of items are displayed. By default there is no limit, and all items are returned.<br />
- Example: <code>limit="10"</code> Default: undefined</p>
- <p><strong>form</strong><br />
- Use specified form partial. By default contained statement is used instead of a form.<br />
- Example: <code>form="price_column"</code> Default: <code>""</code></p>
- <p><strong>wraptag</strong><br />
- The (X)HTML tag (without brackets) used to wrap the output.<br />
- Example: <code>wraptag="div"</code> Default: <code>""</code></p>
- <p><strong>break</strong><br />
- The (X)HTML tag (without brackets) or a string used to separate list items.<br />
- Example: <code>"break="br"</code> Default: <code>""</code></p>
- <p><strong>class</strong><br />
- The (X)HTML class applied to the <code>wraptag</code>. Default is unset.<br />
- Example: <code>class="plugin"</code> Default: <code>""</code></p>
- <h3>rah_repeat_value</h3>
- <pre><code><txp:rah_repeat value="value1, value2, ...">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Rah_repeat_value a single tag, used to display a iterated value. The tag should be used inside a <code><txp:rah_repeat></txp:rah_repeat></code> block.</p>
- <p><strong>escape</strong><br />
- If set to <code>1</code>, <span class="caps">HTML</span> and Textpattern markup are escaped, and special characters are converted to <span class="caps">HTML</span> entities. By default this option is off.<br />
- Example: <code>escape="1"</code> Default: <code>"0"</code></p>
- <p><strong>index</strong><br />
- If set to <code>1</code>, the tag returns the iterated value’s index number. The index starts from 0.<br />
- Example: <code>index="1"</code> Default: <code>"0"</code></p>
- <h3>rah_repeat_if_first</h3>
- <pre><code><txp:rah_repeat value="value1, value2, ...">
- <txp:rah_repeat_if_first>
- Fist item.
- </txp:rah_repeat_if_first>
- </txp:rah_repeat></code></pre>
- <p>The <code><txp:rah_repeat_if_first></code> tag is a container, and has no attributes. It’s a conditional tag that checks if the current item is the first one.</p>
- <h3>rah_repeat_if_last</h3>
- <pre><code><txp:rah_repeat value="value1, value2, ...">
- <txp:rah_repeat_if_last>
- Last item.
- </txp:rah_repeat_if_last>
- </txp:rah_repeat></code></pre>
- <p>The <code><txp:rah_repeat_if_last></code> tag is a container, and has no attributes. It’s a conditional tag that checks if the current item is the last one.</p>
- <h2>Examples</h2>
- <h3>Simple usage example</h3>
- <p>This example turns simple comma separated list of <code>dog, cat, butterfly</code> into a <span class="caps">HTML</span> list.</p>
- <pre><code><txp:rah_repeat value="dog, cat, butterfly" wraptag="ul" break="li">
- A <txp:rah_repeat_value />.
- </txp:rah_repeat></code></pre>
- <p>The above returns:</p>
- <pre><code><ul>
- <li>A dog.</li>
- <li>A cat.</li>
- <li>A butterfly.</li>
- </ul></code></pre>
- <h3>Using tags as values</h3>
- <p>As of Textpattern version 4.0.7, you can use tags inside tags.</p>
- <p>Let’s say that you have comma separated list of items stored inside article’s <a href="http://textpattern.net/wiki/index.php?title=custom_field" rel="nofollow">custom field</a>. For example, list of “Nameless” video service’s video IDs (<code>ID1, ID2, ID3, ID4</code>), and you want to embed each of those as a playable video.</p>
- <p>We pass the custom field hosting the video IDs to rah_repeat tag (with the <code>value</code> attribute), and place the video player code inside the container:</p>
- <pre><code><txp:rah_repeat value='<txp:custom_field name="MyCustomFieldName" />'>
- <object width="600" height="380">
- <param name="movie" value="http://example.com/v/<txp:rah_repeat_value />"></param>
- <embed src="http://example.com/v/<txp:rah_repeat_value />" width="600" height="380"></embed>
- </object>
- </txp:rah_repeat></code></pre>
- <p>The above code would output 4 embedded players (one for each clip), displaying the videos specified with the custom field.</p>
- <h3>Taking advantage of offset and limit attributes</h3>
- <p>First display two items, then some text between, two more items, some more text and then the rest of the items.</p>
- <pre><code><txp:rah_repeat value='<txp:custom_field name="MyCustomFieldName" />' limit="2">
- <txp:rah_repeat_value />
- </txp:rah_repeat>
- <p>Some text here.</p>
- <txp:rah_repeat value='<txp:custom_field name="MyCustomFieldName" />' offset="2" limit="4">
- <txp:rah_repeat_value />
- </txp:rah_repeat>
- <p>Some another cool phrase here.</p>
- <txp:rah_repeat value='<txp:custom_field name="MyCustomFieldName" />' offset="4">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <h3>Repeat inside repeat</h3>
- <pre><code><txp:rah_repeat value="group1|item1|item2, group2|item1|item2">
- <ul>
- <txp:rah_repeat value='<txp:rah_repeat_value />' delimiter="|">
- <li><txp:rah_repeat_value /></li>
- </txp:rah_repeat>
- </ul>
- </txp:rah_repeat></code></pre>
- <p>Returns two <span class="caps">HTML</span> lists:</p>
- <pre><code><ul>
- <li>group1</li>
- <li>item1</li>
- <li>item2</li>
- </ul>
- <ul>
- <li>group2</li>
- <li>item1</li>
- <li>item2</li>
- </ul></code></pre>
- <h3>Basic usage of the if_first and the if_last tags</h3>
- <p>With the conditional tags <code><txp:rah_repeat_if_first /></code> and <code><txp:rah_repeat_if_last></code> we can test which value is the first and which is the last.</p>
- <pre><code><txp:rah_repeat value="item1, item2, item3, item4, item5" wraptag="ul" break="li">
- <txp:rah_repeat_if_first>First: </txp:rah_repeat_if_first>
- <txp:rah_repeat_if_last>Last: </txp:rah_repeat_if_last>
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Returns:</p>
- <pre><code><ul>
- <li>First: item1</li>
- <li>item2</li>
- <li>item3</li>
- <li>item4</li>
- <li>Last: item5</li>
- </ul></code></pre>
- <h3>Remove duplicate values</h3>
- <pre><code><txp:rah_repeat duplicates="1" value="foo, bar, bar, foo, bar, bar, foo, foobar">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Returns: <code>foo, bar, foobar</code></p>
- <h3>Arrange the values from lowest to highest</h3>
- <pre><code><txp:rah_repeat value="b, a, c" sort="regular asc">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Returns: <code>a, b, c</code></p>
- <h3>Excluding values</h3>
- <pre><code><txp:rah_repeat value="foo, bar, foobar" exclude="foo, bar">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Returns: <code>foobar</code></p>
- <h3>Using range attribute</h3>
- <p>With the <code>range</code> it’s possible to create a range of elements with out specifying each. For example generating list of alphabet (A-z) can be done with range.</p>
- <pre><code><txp:rah_repeat range="a, z, 1">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Or listing number from 0 to 10.</p>
- <pre><code><txp:rah_repeat range="0, 10, 1">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <p>Or values <code>0</code>, <code>2</code>, <code>4</code>, and <code>6</code>.</p>
- <pre><code><txp:rah_repeat range="0, 6, 2">
- <txp:rah_repeat_value />
- </txp:rah_repeat></code></pre>
- <h3>Assign variables with assign attribute</h3>
- <p>The <code>assign</code> attribute allows exporting split values as <a href="http://textpattern.net/wiki/index.php?title=variable" rel="nofollow">variables</a>.</p>
- <pre><code><txp:rah_repeat value="JavaScript, jQuery, 1.8.0" assign="language, framework, version" />
- <txp:variable name="language" />
- <txp:variable name="framework" />
- <txp:if_variable name="version" value="1.8.0">
- Version is 1.8.0.
- </txp:if_variable></code></pre>
- <h2>Changelog</h2>
- <h3>Version 1.0.1 – 2013/05/07</h3>
- <ul>
- <li>Composer package now uses <a href="https://packagist.org/packages/textpattern/lock" rel="nofollow">textpattern/lock</a> and <a href="https://packagist.org/packages/textpattern/installer" rel="nofollow">textpattern/installer</a>. The package installs to Textpattern without any extra configuration.</li>
- </ul>
- <h3>Version 1.0.0 – 2013/04/23</h3>
- <ul>
- <li>Fixed: Return a empty string instead of <span class="caps">NULL</span> byte on halt.</li>
- <li>Added: <code>form</code> attribute.</li>
- <li>Added: <code>index</code> attribute to the <code>rah_repeat_value</code> tag.</li>
- <li>Now requires Textpattern 4.5.0 or newer.</li>
- </ul>
- <h3>Version 0.8.1 – 2012/08/25</h3>
- <ul>
- <li>Fixed: <code>range</code> attribute. It ignored any options and always created an list of 1-10.</li>
- </ul>
- <h3>Version 0.8 – 2012/08/24</h3>
- <ul>
- <li>Fixed: made the <code>sort</code> attribute’s direction optional.</li>
- <li>Added: <code>exclude</code> can now take and exclude empty strings (<code>""</code>) and zeros (<code>0</code>).</li>
- <li>Added: <code>range</code> attribute. Allows generating automated lists (<code>range="min, max, step"</code>).</li>
- <li>Added: <code>assign</code> attribute. Allows extracting values as variables.</li>
- <li>Added: <code>escape</code> attribute to <code><txp:rah_repeat_value /></code>.</li>
- <li>Added: Support for natural ordering (<code>sort="natural"</code>).</li>
- <li>Changed: Now <code>trim</code> is enabled by default. Previously values weren’t trimmed from white-space by default.</li>
- <li>Changed: Renamed <code>locale</code> sorting option to <code>LOCALE_STRING</code>.</li>
- <li>Changed: Order can be reversed with out re-sorting by using <code>sort="desc"</code>.</li>
- <li>Now requires <span class="caps">PHP</span> 5.2 (or newer).</li>
- </ul>
- <h3>Version 0.7 – 2011/12/02</h3>
- <ul>
- <li>Added: <code>trim</code> attribute. When set to <code>1</code>, provided values are trimmed from surrounding whitespace.</li>
- <li>Fixed: “locale” sorting option. Previously it sorted values as a string, not by locale options.</li>
- <li>Changed: limit’s default to <span class="caps">NULL</span>. Leave limit unset if you only want offset without limit, or use a high value.</li>
- <li>Improved: Better offset and limit functionality. Now slices the list of values before staring to build the markup.</li>
- </ul>
- <h3>Version 0.6 – 2010/05/09</h3>
- <ul>
- <li>Added: <code>exclude</code> attribute.</li>
- <li>Fixed: <code><txp:rah_repeat_if_last></code> tag. Issue was caused by v0.5 update.</li>
- </ul>
- <h3>Version 0.5 – 2010/05/08</h3>
- <ul>
- <li>Changed offset’s default value from <code>unset</code> to <code>0</code>.</li>
- <li>Added: <code>sort</code> attribute.</li>
- <li>Added: <code>duplicates</code> attribute.</li>
- </ul>
- <h3>Version 0.4 – 2009/11/30</h3>
- <ul>
- <li>Fixed: now returns old parent global, if two tags are used inside each other, instead of defining it empty.</li>
- <li>Added: <code><txp:rah_repeat_if_first></code>.</li>
- <li>Added: <code><txp:rah_repeat_if_last></code>.</li>
- </ul>
- <h3>Version 0.3 – 2009/11/28</h3>
- <ul>
- <li>Added: <code>wraptag</code> attribute.</li>
- <li>Added: <code>break</code> attribute.</li>
- <li>Added: <code>class</code> attribute.</li>
- </ul>
- <h3>Version 0.2 – 2009/11/23</h3>
- <ul>
- <li>Added: <code>limit</code> attribute.</li>
- <li>Added: <code>offset</code> attribute.</li>
- </ul>
- <h3>Version 0.1 – 2009/11/20</h3>
- <ul>
- <li>Initial release.</li>
- </ul>
- # --- END PLUGIN HELP ---
- -->
- <?php
- }
- ?>