Documentation for the Textpattern plugin smd_wrap by Stef Dawson follows this short message from our sponsor ;-)
If you like my code and it helps you out, feel free to show your appreciation with something from my UK Amazon wish list (or US) or donate to the Stef Dawson community coding pot, either via paypal.me/stefdawson or by following the Donate button below to PayPal. Thanks!
smd_wrap / smd_wrap_all
Wrap text with HTML, class, prefix, suffix, and apply tranforms to it in the process (linkify, format as date, trim, escape, sanitize, etc).
If the Textpattern tags inside the item you are intending to wrap returns nothing then no wrap is applied and nothing is displayed. This makes it an ideal candidate for placing around other tags and saves having to do the “assign content to <txp:variable>
, check if variable exists” dance. <txp:else />
is supported so you may take action if the contained content is empty.
If you want the plugin to wrap your content if there is any content in its form/container (e.g. if you are using it to wrap around a {replacement}
tag or something) then use <txp:smd_wrap_all />
instead.
Installation / uninstallation
Download the plugin from either GitHub, or the software page, paste the code into the TXP Admin->Plugins pane, install and enable the plugin.
To uninstall the plugin, simply delete the plugin from the Admin->Plugins page
Visit the forum thread for more info or to report on the success or otherwise of the plugin.
Tags: <txp:smd_wrap>
/ <txp:smd_wrap_all>
Wrap the item
or tag’s container with standard Txp wraptag
paraphernalia. The content is parsed so you can include other Txp tags. If the results of the parse return nothing, the plugin does nothing, though you may fire an optional <txp:else />
if you wish inside your container. The following attributes configure the plugin:
- item
- The thing to wrap. Can be text, a tag-in-tag or some
{replacement}
from other smd_ plugins. If not specifed, the container is used as input unlessform
is given. If you use this attribute you should probably self-close<txp:smd_wrap />
. - form
- An alternative to
item
for specifying the thing to wrap. If not used, and noitem
is given, the container is used as input. - If you employ a container as well, you can use
<txp:yield />
inside yourform
to plug the contained content in. Any contained content is trimmed (iftrim="1"
) and parsed before insertion. - wraptag
- Wrap this HTML tag around the item. Specify it without angle brackets, e.g.
wraptag="span"
- class
- Assign this CSS class to the wraptag. Unused if
wraptag
is empty. - html_id
- Assign this HTML
id
value to the wraptag. Unused ifwraptag
is empty. - attr
- Supply your own name=value pairs to add to the wraptag. For example,
attr="rel|external, title|My useful popup title"
would addrel="external" title="My useful popup title"
as attributes to the wraptag. - label
- Put this text as a heading / label before the item.
- labeltag
- Wrap the label with this HTML tag. Specify without angle brackets, e.g.
labeltag="h4"
- trim
- Strip leading and trailing whitespace from the item before it has prefix and suffix applied. Use
trim="0"
to turn this feature off. - Default: 1
- prefix
- Put this text before the item. It is prepended prior to the item being passed through any
transform
chain. - suffix
- Put this text after the item. It is appended prior to the item being passed through any
transform
chain. - transform
- Apply transformations to the item. Transforms can be chained and are applied in order, each one separated by
delim
. Transform configuration parameters are separated byparam_delim
. The following transforms are defined (see the examples below for more information) :- add — append some text to the item. This is not the same as using prefix / suffix because the
add
transform can be inserted into the chain at any point. Use the second argument to determine in which position to add the new text; the text itself is the third argument. Here are the positional options:- before — add the text at the start of the item.
- after — add the text at the end of the item.
- both — add the text at both start and end of the item.
- case — change the case of the item. You may chain case transforms in sequence, e.g.
transform="case|lower|ucfirst"
. Choose from:- upper — upper case.
- lower — lower case.
- ucfirst — upper case first character of sentence.
- ucwords — upper case first character of every word.
- title — intelligent(ish) version of ucwords that ignores small words and tries to leave intentional first-lower-case words (e.g. iPhone) alone. Works best on English but does support Unicode up to a point. You can specify your own list of words by creating a hidden pref called smd_wrap_small_words. List each word separated by a pipe. You may use regex strings if you wish but no sanitization is done so be careful! The default list of ignored short words are:
a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|vs?[.]?|via
- currency — format as a monetary value. Optional parameters:
- format string as defined in PHP’s money_format. If not set,
%.2n
is used - locale string. Current locale used if not set
- format string as defined in PHP’s money_format. If not set,
- cut — chop the item at the given character/word limit, providing it is longer than the passed value. Note that if the item contains HTML tags then the output is likely to be spurious (wrong count, or with unclosed tags) so it’s best to employ
strip_tags
first. See example 7. Arguments can be of the following form:- some_number (plus optional
c
): chop at the given number of characters - some_number (plus
w
): chop at the given number of words - some_string: the continuation character(s) to add to the end of the item if it has been truncated (e.g.
...
or…
)
- some_number (plus optional
- date or time — treat the item as a date and/or time, formatting it according to the strftime() compatible string given as the first argument. The item can either be a numeric (UNIX) timestamp or an English date string in an acceptable format. For datetime fields you could split the string first just to get the date portion.
- escape — run the item through
htmlspecialchars()
. Use additional parameters to list optional flags or use any of the following special values:- no_quotes —
ENT_NOQUOTES
- double_quotes —
ENT_COMPAT
- all_quotes —
ENT_QUOTES
- no_quotes —
- fordb — run the item through Txp’s
doSlash()
. Always consider using this if you are posting the item back to the database (beware that other plugins may do this for you, so be careful not to duplicate it or you’ll get backslashes where there shouldn’t be backslashes). - form — pass the item through the nominated forms. Specify each form as an argument, and inside those forms place
<txp:smd_wrap_info />
where you wish the item to be inserted. You may also use{smd_wrap_it}
but this may not be as secure as using the tag. - link — turn the item into a clickable URL anchor. Without an argument, the link text will be the link itself. If you specify an argument, the link text will be set to whatever you choose.
- no_widow — whether to allow the last word of the item to word-wrap to the next line. If you specify 0 as the argument, word-wrap will be allowed. Specifying 1 means the last word will never be allowed to wrap on its own. Without an argument, the Advanced Pref determines the behaviour.
- number — treat the item as numeric. The first parameter is optional and specifies the locale to assume (default: current locale). After that, three further optional parameters may be supplied:
- 1: decimal places
- 2: decimal point character
- 3: thousands separator character
- replace — find a string or regex and replace it with something else. Additional parameters are:
- 1: type: either
string
(or omitted) for a regular replace, orregex
for a regular expression - 2: from: the string to search for. If using a regex, you MUST specify the regular expression delimiters as well or you’ll get an error
- 3: to: the text with which to replace any found strings. If omited, the found strings will simply be removed
- 1: type: either
- round — treat the item as a number and round it to the nearest whole number or positive value. One optional argument can either be:
- down — round down
- up — round up
- positive — ignore sign
- some number — the decimal precision to round the value to
- sanitize — clean the item either for:
- url — address bar use.
- file — filename use.
- url_title — use as a URL title.
- encode — percent-encoded URL use
- raw — raw percent-encoded URL use compliant with RFC 3986
- split — split the item at the given character(s) and return one or more parts, optionally joined by the given characters. Parameters:
- 1: split character(s)
- 2: join character(s)
- 3+: which pieces to return, each separated by
param_delim
. You can either use numeric indices to specify discrete parts, e.g.1|4
returns the first and 4th parts. You can specify negative numbers to get parts starting from the end, e.g.-1|-2
returns the last and penultimate elements.last
is a synonym for-1
,all
returns every piece, andrand
chooses one piece at random. In addition you can also use greater-than and less-than symbols before a value to only return elements higher or lower than the given value, e.g.>2
returns the 3rd, 4th, 5th,… elements. See example 3 for details.
- strip_tags — remove all HTML / PHP tags from the item.
- textile — pass the item through the Textile processor.
- trim — remove leading and trailing characters from the item. Specify a list of characters as the argument. Without an argument, whitespace will be removed.
- add — append some text to the item. This is not the same as using prefix / suffix because the
- delim
- The plugin delimiter.
- Default: comma (,)
- param_delim
- The argument delimiter.
- Default: pipe (|)
- debug
- Display the item the tag is trying to wrap.
Example 1: Link anchor
<txp:variable name="docs" value="https://docs.textpattern.com/" />
<txp:smd_wrap wraptag="div" class="external"
transform="link|Textpattern documentation">
<txp:variable name="wiki" />
</txp:smd_wrap>
Returns:
<a href="https://docs.textpattern.com/">Textpattern documentation</a>
Example 2: Date formatting
Notice that because we’re using a comma in the formatted string, the delim
needs to be altered to some other (in this case arbitrary) string:
<txp:smd_wrap delim="@"
transform="date|%A, %d %B, %Y %l:%M%p">
2011-9-12 05:30:00
</txp:smd_wrap>
Returns: Monday, 12 September, 2011 5:30AM
Example 3: Split and join
3a: Get a filename extension
Notice no join character is specified in the third argument (although it doesn’t hurt to include one; it won’t be used in this case):
<txp:smd_wrap transform="split|.||last"
item="/path/to/some/really.big.file.name.jpg" />
Returns: jpg
3b: Get the file path and filename extension
Separated by colon (last
is the same as -1
) :
<txp:smd_wrap transform="split|.|:|1|-1">
/path/to/some/really.big.file.name.jpg
</txp:smd_wrap>
Returns: /path/to/some/really:jpg
3c: Split the date portion of a combined datetime
<txp:smd_wrap delim="@"
transform="split| ||1 @ date|%A, %d %B, %Y">
2011-9-12 05:30:00
</txp:smd_wrap>
Returns: Monday, 12 September, 2011
3d: Make an HTML list from some other markup system
<txp:smd_wrap wraptag="ul"
transform="split|#|</li><li>|>1, add|before|<li>, add|after|</li>">
# First
# Second
# Third
# Fourth
</txp:smd_wrap>
Returns:
<ul>
<li> First</li>
<li> Second</li>
<li> Third</li>
<li> Fourth</li>
</ul>
A couple of things to note about this example:
- The
add
transform is used instead of prefix / suffix. This is because the latter pair become part of the item/container and are then split with thetransform
attribute. In this case we need to add the opening and closing tags afterwards. - Splitting at ‘#’ renders an empty element before the “First” entry, so the transform is instructed to return items
>1
.
Example 4: with smd_query {replacements}
Wrap the custom_6 value with a div and sanitize it for use in a URL. If custom_6 is empty, nothing would be displayed.
<txp:smd_query query="SELECT * FROM wherever">
<txp:smd_wrap item="{custom_6}" wraptag="div"
transform="sanitize|url" />
</txp:smd_query>
If you wanted to trap the condition when custom_6 might be empty:
<txp:smd_query query="SELECT * FROM wherever">
<txp:smd_wrap wraptag="div" transform="sanitize|url">
{custom_6}
<txp:else />
<p>Sorry, custom_6 is empty</p>
</txp:smd_wrap>
</txp:smd_query>
Example 5: find / replace
<txp:smd_wrap
transform="replace||fox|badger">
Farewell my fox, it's been fun!
</txp:smd_wrap>
Returns: Farewell my badger, it's been fun!
Note that the 2nd parameter (‘type’) has been omitted. You could specify ‘string’ here if you wished.
Example 6: form + container + yield
If pulling data from the user table from, say, smd_query you could reformat it:
<txp:smd_wrap form="wrap_me"
transform="replace||agent_hunt|Ethan Hunt">
{author}, is to explain the use of smd_wrap
</txp:smd_wrap>
where wrap_me
contains:
Your mission, <txp:yield />.
This message will self-destruct in 5 seconds.
That will:
- stuff the
{author}
into the container from the surrounding plugin’s replacement tag - inject the container into the form where the yield tag is
- run the transform so if the author was agent_hunt the entire message would read: “Your mission, Ethan Hunt, is to explain the use of smd_wrap. This message will self-destruct in 5 seconds.”
Example 7: truncate to excerpt
Useful for excerpting data:
<txp:smd_wrap_all
transform="strip_tags, cut|180|25w|…">
Bacon ipsum dolor sit amet shoulder drumstick boudin
frankfurter. Andouille shoulder pastrami, rump cow
sausage ribeye shankle swine. Tail meatball cow pork.
Rump ham salami meatloaf sirloin beef ribs.
</txp:smd_wrap_all>
That will write out the string and cut it first at 180 characters, then make sure there are no more than 25 words in it. Thus it will end at: Rump ham salami…
If you omitted the 25w
or your chosen word count was higher than the number of remaining words you would see the following: Rump ham salami meatlo…
Author / credits
Written by Stef Dawson. Thanks to the jakob for making a business case for creating this plugin, and of course the adi_wrap plugin for inspiration.
Source code
If you’d rather dig for buried treasure, you’ll need to step into the view source page.
Legacy software
If, for some inexplicable reason, you need the un-current version of a plugin, it can probably be found on the plugin archive page.
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.