.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Mason::Manual::Filters 3pm" .TH Mason::Manual::Filters 3pm "2014-02-01" "perl v5.18.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Mason::Manual::Filters \- Content filters in Mason .SH "DESCRIPTION" .IX Header "DESCRIPTION" Filters can be used to process portions of content in a component. .PP A set of filters comes built-in with Mason \- see Mason::Filters::Standard. Others will be available on \s-1CPAN,\s0 and it is easy to create your own. .SH "INVOKING" .IX Header "INVOKING" .SS "Block invocation" .IX Subsection "Block invocation" Here's the standard way of invoking a filter: .PP .Vb 3 \& % $.Trim {{ \& This string will be trimmed \& % }} # end Trim .Ve .PP A double open brace (\f(CW\*(C`{{\*(C'\fR) at the end of a \f(CW\*(C`%\-line\*(C'\fR denotes a filter call. The filtered content begins just afterwards and ends at the \f(CW\*(C`}}\*(C'\fR. Both \f(CW\*(C`{{\*(C'\fR and \f(CW\*(C`}}\*(C'\fR may be followed by a comment. .PP The expression \f(CW\*(C`$.Trim\*(C'\fR, aka \f(CW\*(C`$self\->Trim\*(C'\fR, is a method call on the component object which returns a filter. In general everything before the \f(CW\*(C`{{\*(C'\fR is evaluated and is expected to return a filter or list of filters. .PP By convention, and to avoid name clashes with other component methods, filters use CamelCase rather than traditional underscore names. .PP Filters can take arguments: .PP .Vb 3 \& % $.Repeat(3) {{ \& There\*(Aqs no place like home. \& % }} \& \& ==> There\*(Aqs no place like home. \& There\*(Aqs no place like home. \& There\*(Aqs no place like home. .Ve .PP Since the expression \f(CW\*(C`$.Repeat(3)\*(C'\fR returns a filter, it can be curried: .PP .Vb 4 \& % my $repeat_three = $.Repeat(3); \& % $repeat_three {{ \& There\*(Aqs no place like home. \& % }} .Ve .PP You can create one-off filters with anonymous subroutines. The subroutine receives the content in both \f(CW$_[0]\fR and \f(CW$_\fR, and should return the filtered content. .PP .Vb 3 \& % sub { reverse($_[0]) } {{ \& Hello \& % }} \& \& ==> olleH \& \& \& % sub { s/ //g; $_[0] } {{ \& A bunch of words \& % }} \& \& ==> Abunchofwords .Ve .PP Filters can be nested, with separate lines: .PP .Vb 5 \& % $.Trim {{ \& % sub { uc($_[0]) } {{ \& This string will be trimmed and uppercased \& % }} \& % }} .Ve .PP or on a single line: .PP .Vb 3 \& % $.Trim, sub { uc($_[0]) } {{ \& This will be trimmed and uppercased \& % }} .Ve .PP Multiple filters within the same tag are applied, intuitively, in reverse order with the last one being innermost. e.g. in this block .PP .Vb 4 \& % my $i = 1; \& % $.Repeat(3), $.Cache($key, \*(Aq1 hour\*(Aq) {{ \& <% $i++ %> \& % }} \& \& => 1 1 1 .Ve .PP the output of \f(CW\*(C`<% $i++ %>\*(C'\fR is cached, and then repeated three times, whereas in this block .PP .Vb 4 \& % my $i = 1; \& % $.Cache($key, \*(Aq1 hour\*(Aq), $.Repeat(3) {{ \& <% $i++ %> \& % }} \& \& => 1 2 3 .Ve .PP \&\f(CW\*(C`<% $i++ %>\*(C'\fR is executed and output three times, and then the whole thing cached. .SS "Pipe invocation" .IX Subsection "Pipe invocation" Filters can also appear in a limited way inside a regular \f(CW\*(C`<% %>\*(C'\fR tag: .PP .Vb 1 \& <% $content | NoBlankLines,Trim %> .Ve .PP The filter list appears after a << | >> character and must contain one or more comma-separated names. The names are treated as methods on the current component class. With this syntax you cannot use anonymous subroutines or variables as filters, or pass arguments to filters. However in a pinch you can define local filter methods to get around this, e.g. .PP .Vb 5 \& <%class> \& method Repeat3 { $.Repeat(3); } \& \& ... \& <% $message_body | Repeat3 %> .Ve .PP For consistency with other syntax, multiple names are applied in reverse order with the rightmost applied first. .PP One common use of this form is to escape \s-1HTML\s0 strings in web content, using the \&\f(CW\*(C`H\*(C'\fR filter in Mason::Plugin::HTMLFilters: .PP .Vb 1 \& <% $message_body | H %> .Ve .SS "Default filters" .IX Subsection "Default filters" Mason::Plugin::DefaultFilter allows you to define default filters that will automatically apply to all substitution tags. It is analagous to HTML::Mason's default_escape_flags setting. .SS "Manual invocation" .IX Subsection "Manual invocation" \&\f(CW$m\fR\->filter can be used to manually apply filter(s) to a string. It returns the filtered output. e.g. .PP .Vb 4 \& <%init> \& ... \& my $filtered_string = $m\->filter($.Trim, $.NoBlankLines, $string); \& .Ve .SH "CREATING A FILTER" .IX Header "CREATING A FILTER" .SS "Package and naming" .IX Subsection "Package and naming" By convention, filters are placed in roles so that they can be composed into Mason::Component or a subclass thereof. Take a look at Mason::Filters::Standard for an example. .PP Also by convention, filters use CamelCase rather than traditional underscore_separated naming. Filter methods have to coexist with other methods in the Mason::Component namespace, so have to be distinguishable somehow, and we thought this was preferable to a \*(L"filter_\*(R" prefix or suffix. Of course, you are free to choose your own convention, but you should expect this naming in the standard filters at least. .PP Here's a filter package that implements two filters, \f(CW\*(C`Upper\*(C'\fR and \f(CW\*(C`Lower\*(C'\fR: .PP .Vb 2 \& package MyApp::Filters; \& use Mason::PluginRole; \& \& method Upper () { \& return sub { uc($_[0]) } \& } \& \& method Lower () { \& return sub { lc($_[0]) } \& } \& \& 1; .Ve .PP To use these in a component: .PP .Vb 3 \& <%class> \& with \*(AqMyApp::Filters\*(Aq; \& \& \& % $.Upper {{ \& ... \& % }} .Ve .PP Or if you want them available to all components, put them in \f(CW\*(C`Base.mp\*(C'\fR at the top of your component hierarchy, or in your application's \f(CW\*(C`Mason::Component\*(C'\fR subclass. .SS "Simple vs. dynamic filters" .IX Subsection "Simple vs. dynamic filters" A \fIsimple filter\fR is a code ref which takes a string (via either \f(CW$_\fR[0] and \f(CW$_\fR) and returns the output. Your filter method should return this code ref. e.g. .PP .Vb 4 \& # Uses $_[0] \& method Upper () { \& return sub { uc($_[0]) }; \& } \& \& # Uses $_ \& method Rot13 () { \& return sub { tr/a\-zA\-Z/n\-za\-mN\-ZA\-M/; $_ }; \& } .Ve .PP A \fIdynamic filter\fR is an object of class \f(CW\*(C`Mason::DynamicFilter\*(C'\fR. It contains a code ref which takes a \fIyield block\fR and returns the output. A yield block is a zero-argument code ref that returns a content string. e.g. this is functionally identical to the above: .PP .Vb 10 \& method Rot13 () { \& return Mason::DynamicFilter\->new( \& filter => sub { \& my $yield = $_[0]; \& my $text = $yield\->(); \& $text =~ tr/a\-zA\-Z/n\-za\-mN\-ZA\-M/; \& return $text; \& } \& ); \& } .Ve .PP The dynamic filter obviously doesn't buy you anything in this case, and for the majority of filters they are unneeded. The real power of dynamic filters is that they can choose if and when to execute the yield block. For example, here is an implementation (slightly expanded for explanatory purposes) of the \f(CW\*(C`Cache\*(C'\fR filter in Mason::Plugin::Cache: .PP .Vb 10 \& method Cache ( $key, $set_options ) { \& return Mason::DynamicFilter\->new( \& filter => sub { \& my $yield = $_[0]; \& my $cache = $self\->cache; \& my $output = $cache\->get( $key ); \& if (!$output) { \& $output = $yield\->(); \& $cache\->set( $key, $output, $set_options ); \& } \& return $output; \& } \& ); \& } .Ve .PP Notice that we call \f(CW\*(C`$cache\->get\*(C'\fR first, and return the output immediately if it is in the cache. Only on a cache miss do we actually execute the (presumably expensive) yield block. .PP \&\f(CW\*(C`Defer\*(C'\fR and \f(CW\*(C`Repeat\*(C'\fR are two other examples of dynamic filters. See Mason::Filters::Standard for their implementations. .SS "<%filter> block" .IX Subsection "<%filter> block" You can use the \f(CW\*(C`<%filter>\*(C'\fR block to define filters that output content. It works just like a \f(CW\*(C`<%method>\*(C'\fR block, except that you can call \f(CW\*(C`$yield\->()\*(C'\fR to generate the original content. e.g. .PP .Vb 3 \& <%filter Item ($class)> \&
  • <% $yield\->() %>
  • \& \& \& % $.Item(\*(Aqstd\*(Aq) {{ \& First \& % }} \& % $.Item(\*(Aqstd\*(Aq) {{ \& Second \& % }} .Ve .PP generates .PP .Vb 6 \&
  • \& First \&
  • \&
  • \& Second \&
  • .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Mason::Filters::Standard, Mason .SH "AUTHOR" .IX Header "AUTHOR" Jonathan Swartz .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2012 by Jonathan Swartz. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.