Templa...Method(3pm)
๐ Template::Alloy::VMethod โ the VMethod role ๐
welcome to Templa...Method(3pm), bestie!! this is from the User Contributed Perl Documentation corner of the universe and it's literally the page that explains where all the extra sparkle in Template::Alloy comes from. part 1 of 2, so don't go anywhere ๐ธ
โจ NAME โจ
Template::Alloy::VMethod โ it's the VMethod role. that's the whole name. short. iconic. ๐
๐ DESCRIPTION ๐
okay so the Template::Alloy::VMethod role is the โจglow-upโจ layer โ it hands you all the extra vmethods, filters, and virtual objects that get stacked on top of Template::Alloy's base feature set. think of it as the accessories drawer for your template engine ๐
most of the vmethods listed here are basically the same ones Template::Toolkit gives you. the goal is to keep Template::Alloy's versions in sync with TT's. fr fr, they're trying ๐ช
and because one engine can never have enough side quests, Template::Alloy also ships several extra methods that are needed for HTML::Template::Expr support. slay.
๐ซถ ROLE METHODS ๐ซถ
define_vmethodโ defines a vmethod. if you want the full tea, go read Template::Alloy for more details. that's where the deep lore lives ๐vmethod_*โ methods with names like this implement the virtual methods that are too complex to be one-liners. heads up though: these are not exposed via the role. they're backstage crew, not main characters ๐filter_*โ same vibe, different job: methods named like this implement filters that are more complex than one liners. also not exposed via the role. internal business only, iykyk ๐
๐ VIRTUAL METHOD LIST ๐
here's the whole menu, bestie โ the builtin virtual methods and filters you can call on each type of data ๐
so in Template::Alloy, the | operator can be used to call virtual methods exactly the same way the . operator can. same energy, different punctuation โจ
the one big difference: when you're accessing hashrefs or objects, the | means "always call the virtual method or filter" rather than peeking inside the hashref for a key with that name, or trying to call that method on the object. no sneaky lookups, no substitutions. this is similar to how TT3 will function ๐ฎ
virtual methods are also made available via Virtual Objects, which get discussed in a later section. stay tuned ๐
๐ธ SCALAR VIRTUAL METHODS AND FILTERS ๐ธ
this is the list of builtin virtual methods and filters you can call on scalar data types ๐
in Alloy and TT3, filters and virtual methods are way more closely related than they are in TT2. in general, anywhere a virtual method can be used, a filter can be used too โ and likewise, all scalar virtual methods can be used as filters. it's giving flexible ๐
on top of the filters listed below, Alloy will automatically load Template::Filters and use them if Template::Toolkit is installed. free extras, no cap ๐
and on top of the scalar virtual methods: any scalar will be automatically converted to a single item list if a list virtual method gets called on it. surprise promotion โจ
scalar virtual methods are also available through the Text virtual object โ except for true filters such as eval and redirect. those two don't get to hang out there ๐
โโ๏ธ
oh and all scalar virtual methods are available as top level functions as well. that is not true of TT2, so don't get it twisted. in Template::Alloy these two are equivalent:
[% "abc".length %]
[% length("abc") %]
if you want to turn that behavior off, you may set VMETHOD_FUNCTIONS to 0. your call bestie ๐
๐ '0' ๐
[% item = 'foo' %][% item.0 %]
Returns foo.
allows for scalars to mask as arrays โ and yeah, scalars already will, but this lets you get more direct access. handy ๐
not available in TT.
๐ abs ๐
[% -1.abs %]
Returns the absolute value. no negatives allowed on this page, only good vibes โจ
๐ atan2 ๐
[% pi = 4 * 1.atan2(1) %]
Returns the arctangent. the item itself represents Y, and the passed argument represents X. math but make it cute ๐
not available in TT โ but it is available in HTML::Template::Expr.
๐ chunk ๐
[% item.chunk(60).join("\n") %]
Split the string up into a list of chunks of text, 60 chars wide. chopping it into snackable pieces ๐ซ
๐ collapse ๐
[% item.collapse %]
Strip leading and trailing whitespace, and collapse all other space to one space. tidy queen behavior ๐งน
๐ cos ๐
[% item.cos %]
Returns the cosine of the item. trigonometry said periodt ๐
not available in TT โ but it is available in HTML::Template::Expr.
๐ defined ๐
[% item.defined %]
Always true โ because the undef sub translates all undefs to ''. so like, everything is defined now, we don't do undefined here ๐
๐ eval ๐
[% item.eval %]
Process the string as though it was a template โจ this will start the parsing engine and will use the same configuration as the current process. Alloy is several times faster at doing this than TT is, and it's considered acceptable. we love a speed demon ๐ฅ
this is a filter and is not available via the Text virtual object.
Template::Alloy has attempted to make the compile process painless and fast. by default an MD5 sum of evaled is taken and used to cache the AST. you can turn that behavior off using the CACHE_STR_REFS configuration item.
Template::Alloy also allows for named parameters to be passed to the eval filter ๐
[% '[% 1 + 2 %]'.eval %]
[% '${ 1 + 2 }'.eval(interpolate => 1) %]
[% "#get( 1 + 2)"|eval(syntax => 'velocity') %]
[% '<TMPL_VAR EXPR="1 + 2">'.eval(syntax => 'hte') %]
[% '<TMPL_VAR EXPR="1 + 2">'.eval(syntax => 'hte') %]
๐ evaltt ๐
Same as the eval filter. literally the same. twin energy ๐ฏโโ๏ธ
๐ exp ๐
[% 1.exp %]
Something like 2.71828182845905 ๐ธ
returns "e" to the power of the item. exponent realness โจ
๐ file ๐
Same as the redirect filter. two names, one job ๐
๐ fmt ๐
[% item.fmt('%d') %]
[% item.fmt('%6s') %]
[% item.fmt('%*s', 6) %]
Similar to format. returns a string formatted with the passed pattern. the default pattern is %s. this is the opposite of the sprintf vmethod ๐
๐ format ๐
[% item.format('%d') %]
[% item.format('%6s') %]
[% item.format('%*s', 6) %]
Print the string out in the specified format. it's similar to the fmt virtual method โ except that the item is split on newline and each line is processed separately. line by line, one at a time, very thorough ๐
๐ hash ๐
[% item.hash %]
Returns a one item hash with a key of "value" and a value of the item. tiny hash, big heart ๐
๐ hex ๐
[% "FF".hex %]
Returns the decimal value of the passed hex numbers. also note that you may just use [% 0xFF %] instead. shortcuts are valid โจ
not available in TT โ but it is available in HTML::Template::Expr.
๐ html ๐
[% item.html %]
Performs a very basic html encoding โ it swaps out &, <, > and " with the corresponding html entities ๐
previously it also encoded the ', but that behavior did not match TT2's behavior. so if you want that behavior back, use .xml instead. we don't do legacy encoding here ๐
๐ indent ๐
[% item.indent(3) %]
Indent by that number of spaces if an integer is passed โ the default is 4 โจ
[% item.indent("Foo: ") %]
Add the string "Foo: " to the beginning of every line. cute prefix energy ๐
๐ int ๐
[% item.int %]
Return the integer portion of the value โ and it's 0 if there is none. no decimals allowed on this one โจ
๐ json ๐
[% item.json %]
Returns a JSON encoded representation.
[% item.json(1) %]
Returns a pretty JSON encoded representation. yes, the 1 is the glow-up โจ
๐ lc ๐
Same as the lower vmethod. returns the lowercased version of the item. lowercase era ๐ซถ
๐ lcfirst ๐
[% item.lcfirst %]
Lowercase the leading letter. just the one. the rest stays exactly how it is ๐
๐ length ๐
[% item.length %]
Return the length of the string. how many characters, bestie ๐
๐ list ๐
[% item.list %]
Returns a list (arrayref) with a single value โ that value being the item. one item, but make it a list ๐ธ
๐ log ๐
[% 8.exp.log %]
Equal to 8 ๐
returns the natural log base "e" of the item.
not available in TT โ but it is available in HTML::Template::Expr.
๐ lower ๐
[% item.lower %]
Return the string lowercased. down bad for lowercase fr fr โจ
๐ match ๐
[% item.match("(\w+) (\w+)") %]
Return a list of items matching the pattern.
[% item.match("(\w+) (\w+)", 1) %]
Same as before โ but match globally ๐
in Template::Alloy and TT3 you can use regular expressions notation as well:
[% item.match( /(\w+) (\w+)/ ) %]
Same as before.
[% item.match( m{(\w+) (\w+)} ) %]
Same as before.
heads up: you can't use the 'g' regex modifier here โ you must pass the second argument to turn on global match. that's the rule ๐
๐ none ๐
Returns the item without modification. this was added as a compliment case for when the AUTO_FILTER configuration is specified ๐
note that it must be called as a filter to bypass the application of the AUTO_FILTER.
[% item | none %]
Returns the item without modification. sneaky bypass unlocked ๐
๐ null ๐
[% item.null %]
Return nothing. empty. void. gone ๐
if the item contains a coderef it will still be executed, but the result would be ignored. so like, the work happens, you just don't get to see it ๐
๐ oct ๐
[% "377".oct %]
Returns the decimal value of the octal string.
on recent versions of perl you may also pass numbers starting with 0x which will be interpreted as hexadecimal, and starting with 0b which will be interpreted as binary. glow-up on the parsing rules โจ
not available in TT โ but it is available in HTML::Template::Expr.
๐ rand ๐
[% item = 10; item.rand %]
Returns a number greater or equal to 0 but less than 10 ๐ฒ
[% 1.rand %]
note: this filter is not available as of TT2.15.
๐ remove ๐
[% item.remove("\s+") %]
Same as replace โ but it is global and replaces with nothing. it's giving delete key ๐๏ธ
๐ redirect ๐
[% item.redirect("output_file.html") %]
Writes the contents out to the specified file. the filename must be relative to the OUTPUT_PATH configuration variable, and the OUTPUT_PATH variable must be set. no path, no output, no cap ๐จ
this is a filter and is not available via the Text virtual object.
๐ repeat ๐
[% item.repeat(3) %]
Repeat the item 3 times ๐
[% item.repeat(3, ' | ') %]
Repeat the item 3 times, separated with ' | '. cute little separators, we love to see it ๐
๐ replace ๐
[% item.replace("\s+", " ") %]
Globally replace all space with โจ
[% item.replace("foo", "bar", 0) %]
Replace only the first instance of foo with bar.
[% item.replace("(\w+)", "($1)") %]
Surround all words with parenthesis.
in Template::Alloy and TT3 you may also use normal regular expression notation:
[% item.replace(/(\w+)/, "($1)") %]
Same as before.
heads up: you can't use the 'g' regex modifier โ global match is on by default. you must pass the third argument of false to turn global match off. ๐
๐ return ๐
Returns the item from the inner most block, macro, or file. similar to the RETURN directive ๐ซถ
[% item.return %]
[% RETURN item %]
same thing, two ways. pick your fighter ๐
๐ search ๐
[% item.search("(\w+)") %]
Tests if the given pattern is in the string ๐
in Template::Alloy and TT3 you may also use normal regular expression notation:
[% item.search(/(\w+)/) %]
Same as before.
๐ sin ๐
[% item.sin %]
Returns the sine of the item. wave check ๐
๐ size ๐
[% item.size %]
Always returns 1. no matter what. it's committed to the bit ๐
๐ split ๐
[% item.split %]
Returns an arrayref from the item split on " " โจ
[% item.split("\s+") %]
Returns an arrayref from the item split on /\s+/.
[% item.split("\s+", 3) %]
Returns an arrayref from the item split on /\s+/, splitting until 3 elements are found.
in Template::Alloy and TT3 you may also use normal regular expression notation:
[% item.split( /\s+/, 3 ) %]
Same as before.
๐ sprintf ๐
[% item = "%d %d" %]
[% item.sprintf(7, 8) %]
Uses the pattern stored in self, and passes it to sprintf with the passed arguments. this is the opposite of the fmt vmethod ๐
๐ sqrt ๐
[% item.sqrt %]
Returns the square root of the number. root math, rooted in math ๐ฑ
srandโ okay so this calls the perlsrandfunction to set the internal random seed. This will affect future calls to therandvmethod. ๐ฒstderrโ Print the item to the currentSTDERRhandle. slay.
[% item.stderr %]
substrโ Returns a substring ofitemstarting atiand going to the end of the string.
[% item.substr(i) %]
Returns a substring of item starting at i and going n characters.
[% item.substr(i, n) %]
trimโ Strips leading and trailing whitespace. bye bye, extra spaces.
[% item.trim %]
ucโ Same as theuppercommand. Returns uppercased string. LOUDER, bestie.ucfirstโ Uppercase the leading letter. just the first one, main character energy.
[% item.ucfirst %]
upperโ Return the string uppercased. ALL CAPS VIBE.
[% item.upper %]
uriโ Perform a very basic URI encoding. basic but cute.
[% item.uri %]
urlโ Perform a URI encoding - but some characters such as:and/are left intact. they're too iconic to encode.
[% item.url %]
xmlโ Performs a very basic xml encoding (swaps out&,<,>,'and"with the corresponding xml entities) entity era.
[% item.xml %]
โจ LIST VIRTUAL METHODS โจ
The following methods can be called on an arrayref type data structures (scalar types will automatically promote to a single element list and call these methods if needed):
Additionally, list virtual methods can be accessed via the List Virtual Object.
fmtโ Passed a pattern and an string to join on. Returns a string of the values of the list formatted with the passed pattern and joined with the passed string. Default pattern is%sand the default join string is a space. formatting? obsessed.
[% mylist.fmt('%s', ', ') %]
[% mylist.fmt('%6s', ', ') %]
[% mylist.fmt('%*s', ', ', 6) %]
firstโ Returns a list of the first 3 items in the list. firsties!
[% mylist.first(3) %]
grepโ Returns a list of all items matching the pattern. filtering, but make it regex.
[% mylist.grep("^\w+\.\w+$") %]
In Template::Alloy and TT3 you may also use normal regular expression notation.
[% mylist.grep(/^\w+\.\w+$/) %]
Same as before.
[% mylist.grep(->(a){ a.foo.bar }
hashโ Returns a hashref with the array indexes as keys and the values as values. list to hash, glow up.
[% mylist.hash %]
joinโ Joins on space.
[% mylist.join %]
Joins on the passed argument.
[% mylist.join(", ")
jsonโ Returns a JSON encoded representation.
[% mylist.json %]
Returns a pretty JSON encoded representation. pretty print, because aesthetics.
[% mylist.json(1) %]
lastโ Returns a list of the last 3 items in the list. the finale.
[% mylist.last(3) %]
listโ Returns a reference to the list. just the ref, no copy.
[% mylist.list %]
map(Not in TT2) โ Returns a list with the macro played on each item. transform era.
[% mylist.map(->{ this.upper }) %]
Same thing
[% mylist.map(->(a){ a.upper }) %]
The RETURN directive or return list, item, and hash vmethods allow for returning more interesting items.
[% [1..3].map(->(a){ [1..a].return }) %]
maxโ Returns the last item in the array. the biggest, the best.
[% mylist.max %]
mergeโ Returns a new list with all defined items fromlist2added. merge, no cap.
[% mylist.merge(list2) %]
nsortโ Returns the numerically sorted items of the list. If the items are hashrefs, a key containing the field to sort on can be passed. numbers go brrr.
[% mylist.nsort %]
popโ Removes and returns the last element from the arrayref (the stash is modified). bye last element.
[% mylist.pop %]
pushโ Adds an element to the end of the arrayref (the stash is modified). append szn.
[% mylist.push(23) %]
pickโ Returns a random item from the list.
[% mylist.pick %]
[% ['a' .. 'z'].pick %]
An additional numeric argument is how many items to return.
[% ['a' .. 'z'].pick(8).join('') %]
Note: This filter is not available as of TT2.15. so if you're on TT2.15, bestie, it's giving missing.
returnโ Returns the list from the inner most block, macro, or file. Similar to theRETURNdirective.
[% mylist.return %]
[% RETURN mylist %]
reverseโ Returns the list in reverse order. backwards but make it fashion.
[% mylist.reverse %]
shiftโ Removes and returns the first element of the arrayref (the stash is modified). bye first element.
[% mylist.shift %]
sizeโ Returns the number of elements in the array. count 'em.
[% mylist.size %]
sliceโ Returns a list from the arrayref beginning at indexiand continuing fornitems. slice of the list, periodt.
[% mylist.slice(i, n) %]
sortโ Returns the alphabetically sorted items of the list. If the items are hashrefs, a key containing the field to sort on can be passed. alphabetical order, as you should.
[% mylist.sort %]
spliceโ Removes items from array beginning atiand continuing fornitems.
[% mylist.splice(i, n) %]
Same as before, but replaces removed items with the items from list2.
[% mylist.splice(i, n, list2) %]
uniqueโ Return a list of the unique items in the array. no duplicates, we don't do repeats.
[% mylist.unique %]
unshiftโ Adds an item to the beginning of the arrayref. prepend, but make it Unix.
[% mylist.unshift(23) %]
๐ HASH VIRTUAL METHODS ๐
The following methods can be called on hash type data structures:
Additionally, list virtual methods can be accessed via the Hash Virtual Object.
fmtโ Passed a pattern and an string to join on. Returns a string of the key/value pairs of the hash formatted with the passed pattern and joined with the passed string. Default pattern is"%s\t%s"and the default join string is a newline. formatting the hash, cute.
[% myhash.fmt('%s => %s', "\n") %]
[% myhash.fmt('%4s => %5s', "\n") %]
[% myhash.fmt('%*s => %*s', "\n", 4, 5) %]
definedโ Checks ifais defined in the hash. is it there? defined or not defined, that is the question.
[% myhash.defined('a') %]
deleteโ Deletes the item from the hash. gone, deleted, no trace.
[% myhash.delete('a') %]
Unlink Perl the value is not returned. Multiple values may be passed and represent the keys to be deleted.
eachโ Turns the contents of the hash into a list - subject to change as TT is changing the operations ofeachandlist. evolving, as all things do.
[% myhash.each.join(", ") %]
existsโ Checks ifais in the hash. does it exist? vibe check.
[% myhash.exists('a') %]
hashโ Returns a reference to the hash. the ref, the whole ref, nothing but the ref.
[% myhash.hash %]
importโ Overlays the keys ofhash2over the keys ofmyhash. overlay, merge, slay.
[% myhash.import(hash2) %]
itemโ Returns the hashes value for that key. gimme the value.
[% myhash.item(key) %]
itemsโ Returns a list of the key and values (flattened hash) flattened, like my emotional state during finals week.
[% myhash.items %]
jsonโ Returns a JSON encoded representation.
[% myhash.json %]
Returns a pretty JSON encoded representation. pretty print, for the aesthetic.
[% myhash.json(1) %]
keysโ Returns an arrayref of the keys of the hash. all the keys, no values.
[% myhash.keys.join(', ') %]
listโ Returns an arrayref with the hash as a single value (subject to change). single value, for now.
[% myhash.list %]
pairsโ Returns an arrayref of hashrefs where each hash contains{key => $key, value => $value}for each value of the hash. key-value pairs, the dynamic duo.
[% myhash.pairs %]
nsortโ Returns a list of keys numerically sorted by the values. numbers, sorted, by value.
[% myhash.nsort.join(", ") %]
returnโ Returns the hash from the inner most block, macro, or file. Similar to theRETURNdirective.
[% myhash.return %]
[% RETURN myhash %]
sizeโ Returns the number of key/value pairs in the hash. how many pairs? count.
[% myhash.size %]
sortโ Returns a list of keys alphabetically sorted by the values. alphabetical, by values, iconic.
[% myhash.sort.join(", ")
valuesโ Returns an arrayref of the values of the hash. just the values, no keys attached.
[% myhash.values.join(', ') %]
๐ VIRTUAL OBJECTS ๐
TT3 has a concept of Text, List, and Hash virtual objects which provide direct access to the scalar, list, and hash virtual methods. In the TT3 engine this will allow for more concise generated code. Because Alloy does not generated perl code to be executed later, Alloy provides for these virtual objects but does so as more of a namespace (using the methods does not provide a speed optimization in your template - just may help clarify things). so it's like a vibe namespace, not a speed boost.
[% a = "foo"; a.length %] => 3
[% a = "foo"; Text.length(a) %] => 3
[% a = Text.new("foo"); a.length %] => 3
[% a = [1 .. 30]; a.size %] => 30
[% a = [1 .. 30]; List.size(a) %] => 30
[% a = List.new(1 .. 30); a.size %] => 30
[% a = {a => 1, b => 2}; a.size %] => 2
[% a = {a => 1, b => 2}; Hash.size(a) %] => 2
[% a = Hash.new({a => 1, b => 2}); a.size %] => 2
[% a = Hash.new(a => 1, b => 2); a.size %] => 2
[% a = Hash.new(a = 1, b = 2); a.size %] => 2
[% a = Hash.new('a', 1, 'b', 2); a.size %] => 2
One limitation is that if you pass a key named "Text", "List", or "Hash" in your variable stash - the corresponding virtual object will be hidden. so don't name your variable "Text" unless you want to hide the Text object. iykyk.
Additionally, you can use all of the Virtual object methods with the pipe operator. pipe operator, for the aesthetic.
[% {a => 1, b => 2}
| Hash.keys
| List.join(", ") %] => a, b
Again, there aren't any speed optimizations to using the virtual objects in Alloy, but it can help clarify the intent in some cases. clarity is key, bestie.
Note: these aren't really objects. All of the "virtual objects" are references to the $SCALAR_OPS, $LIST_OPS, and $HASH_OPS hashes found in the $VOBJS hash of Template::Alloy. not objects, just refs. the more you know.
๐ AUTHOR ๐
Paul Seamons <paul@seamons.com> the legend himself.
๐ LICENSE ๐
This module may be distributed under the same terms as Perl itself. same as Perl, slay.
and that's the tea โ โ this page is from perl v5.38.2, dated 2024-03-07, and it's the Templa...Method(3pm) manpage. stay iconic, bestie. ๐ โจ
๐ฆ where this page comes from
- debian trixie: libtemplate-alloy-perl 1.022-3 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libtemplate-alloy-perl 1.022-3 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libtemplate-alloy-perl 1.022-3 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms