Skip to content

devguide tagmodifiers

Violet edited this page Oct 28, 2010 · 3 revisions

MDG: Creating Template Tag Modifiers

Template Tag Modifiers are a special kind of template tag that do not exist as a tag literally, e.g. <mt:SomeTagModifier>. Instead, a template tag modifier is a type of template tag argument that has the ability to transform the contents of the tag it is associated with.

The following are some of the template tag modifiers that Melody ships with by default:

  • capitalize - convert all the characters output by the tag to uppercase.

  • replace - perform a simple string substitution on the contents of the tag.

  • word_count - instead of returning the contents directly, return an integer reflecting the number of words contained by the tag.

  • ltrim and rtrim - remove white space from the left/right of the tag's contents.

And many more of course. Here are some examples using some of the tags above:

<mt:Entries id="40" capitalize="1"><mt:EntryBody></mt:Entries>

<mt:Var name="foo" replace="Byrne Reese","BR">

The following reference will walk you through the process of defining your own template tag modifiers.

Registering Your Tag Modifier

As with any plugin feature, the first step is always a visit to the config.yaml. Here is a sample config.yaml file for declaring a template tag modifier:

name: Example Plugin for Melody
id: Example
description: This plugin is an example plugin for Melody.
version: 1.0
tags:
    modifier:
        lolcats:
            handler: $Example::Example::Plugin::lolcats

Defining Your Tag Modifier's Behavior

Once the tags have been declared in your config.yaml it is time to write the code that will govern their behavior.

  1. Create a plugin module called Plugin.pm in the following directory:

    /path/to/mt/plugins/Example/lib/Example/

  2. Edit Plugin.pm and cut and paste the following into it using a text editor:

     package Example::Plugin;
     use strict;
    
     sub lolcats {
         my ($str, $val, $ctx) = @_;
         return "LOL - CAN I HAZ A $str";
     }
    
     1; # Every module must return true
    

When a template tag modifier is invoked, Melody will pass three arguments to the handler. They are:

  • str - The value of the template tag's content.

  • val - The value passed into the global modifier attribute. If multiple values are passed, then val will be an ARRAY.

  • ctx - A reference to the template's context.

Passing Multiple Parameters into a Tag Modifier

One advanced capability that is utilized by the regex_replace modifier is the ability to pass multiple arguments into the modifier directly.

The regex_replace modifier requires two parameters from the user: a) the pattern to search for, and b) the string to replace matches with. For example, the following example will replace all occurrences of the word "cat" with "dog" within the entry's body:

<mt:EntryBody regex_replace="/cat/g","dog">

This is equivalent to the the regular expression:

s/cat/dog/g

Suppose you wanted to augment regex_replace to take an optional third parameter which would indicate whether the pattern should be evaluated in a case insensitive manner. The modifier's handler would then look like this:

sub _fltr_regex_replace {
my ($str, $val, $ctx) = @_;
# This one requires an array
return $str unless ref($val) eq 'ARRAY';
my $patt = $val->[0];
my $replace = $val->[1];
my $options = $val->[2] ? "i" : "";
if ($patt =~ m!^(/)(.+)\1([A-Za-z]+)?$!${options}) {
$patt = $2;
my $global;
if (my $opt = $3) {
$global = 1 if $opt =~ m/g/;
$opt =~ s/[ge]+//g;
$patt = "(?$opt)" . $patt;
}
my $re = eval { qr/$patt/ };
if (defined $re) {
$replace =~ s!\\(\d+)!$1!g; # for php, \1 is how you write $1
$replace =~ s!/!\/!g;
eval '$str =~ s/$re/' . $replace . '/' . ($global ? 'g' : '');
if ($@) {
return $ctx->error("Invalid regular expression: $@");
}
}
}
return $str;
}

Wow, that is some super serious perl code. Let's focus on just the parts that are relevant to passing arguments:

1 sub _fltr_regex_replace {
2    my ($str, $val, $ctx) = @_;
3    # This one requires an array
4    return $str unless ref($val) eq 'ARRAY';
5    my $patt = $val->[0];
6    my $replace = $val->[1];
7    my $options = $val->[2] ? "i" : "";

Line 4 is useful because it tests to see if $val is an array or not. If it is not then it aborts the regular expression and returns the value of $str unmodified.

Line 5, 6 and 7 show how you reference the first, second and third arguments passed into the modifier respectively.

Continue Reading

 


Questions, comments, can't find something? Let us know at our community outpost on Get Satisfaction.

Credits

  • Author: Byrne Reese
  • Edited by:
Clone this wiki locally