1
2
3__END__
4
5=pod
6
7=head1 NAME
8
9Mason::Manual::Filters - Content filters in Mason
10
11=head1 DESCRIPTION
12
13Filters can be used to process portions of content in a component.
14
15A set of filters comes built-in with Mason - see
16L<Mason::Filters::Standard|Mason::Filters::Standard>. Others will be available
17on CPAN, and it is easy to create your own.
18
19=head1 INVOKING
20
21=head2 Block invocation
22
23Here's the standard way of invoking a filter:
24
25   % $.Trim {{
26     This string will be trimmed
27   % }}  # end Trim
28
29A double open brace (C<< {{ >>) at the end of a C<< %-line >> denotes a filter
30call.  The filtered content begins just afterwards and ends at the C<< }} >>.
31Both C<< {{ >> and C<< }} >> may be followed by a comment.
32
33The expression C<< $.Trim >>, aka C<< $self->Trim >>, is a method call on the
34component object which returns a filter. In general everything before the C<<
35{{ >> is evaluated and is expected to return a filter or list of filters.
36
37By convention, and to avoid name clashes with other component methods, filters
38use CamelCase rather than traditional underscore names.
39
40Filters can take arguments:
41
42   % $.Repeat(3) {{
43     There's no place like home.
44   % }}
45
46     ==>  There's no place like home.
47          There's no place like home.
48          There's no place like home.
49
50Since the expression C<< $.Repeat(3) >> returns a filter, it can be curried:
51
52   % my $repeat_three = $.Repeat(3);
53   % $repeat_three {{
54     There's no place like home.
55   % }}
56
57You can create one-off filters with anonymous subroutines. The subroutine
58receives the content in both C<< $_[0] >> and C<< $_ >>, and should return the
59filtered content.
60
61   % sub { reverse($_[0]) } {{
62     Hello
63   % }}
64
65     ==> olleH
66
67
68   % sub { s/ //g; $_[0] } {{
69     A bunch of words
70   % }}
71
72     ==> Abunchofwords
73
74Filters can be nested, with separate lines:
75
76   % $.Trim {{
77   %   sub { uc($_[0]) } {{
78     This string will be trimmed and uppercased
79   %   }}
80   % }}
81
82or on a single line:
83
84   % $.Trim, sub { uc($_[0]) } {{
85     This will be trimmed and uppercased
86   % }}
87
88Multiple filters within the same tag are applied, intuitively, in reverse order
89with the last one being innermost. e.g. in this block
90
91   % my $i = 1;
92   % $.Repeat(3), $.Cache($key, '1 hour') {{
93     <% $i++ %>
94   % }}
95
96      => 1 1 1
97
98the output of C<< <% $i++ %> >> is cached, and then repeated three times,
99whereas in this block
100
101   % my $i = 1;
102   % $.Cache($key, '1 hour'), $.Repeat(3) {{
103     <% $i++ %>
104   % }}
105
106      => 1 2 3
107
108C<< <% $i++ %> >> is executed and output three times, and then the whole thing
109cached.
110
111=head2 Pipe invocation
112
113Filters can also appear in a limited way inside a regular C<< <% %> >> tag:
114
115    <% $content | NoBlankLines,Trim %>
116
117The filter list appears after a << | >> character and must contain one or more
118comma-separated names. The names are treated as methods on the current
119component class. With this syntax you cannot use anonymous subroutines or
120variables as filters, or pass arguments to filters. However in a pinch you can
121define local filter methods to get around this, e.g.
122
123    <%class>
124    method Repeat3 { $.Repeat(3); }
125    </%class>
126    ...
127    <% $message_body | Repeat3 %>
128
129For consistency with other syntax, multiple names are applied in reverse order
130with the rightmost applied first.
131
132One common use of this form is to escape HTML strings in web content, using the
133C<H> filter in L<Mason::Plugin::HTMLFilters|Mason::Plugin::HTMLFilters>:
134
135    <% $message_body | H %>
136
137=head2 Default filters
138
139L<Mason::Plugin::DefaultFilter|Mason::Plugin::DefaultFilter> allows you to
140define default filters that will automatically apply to all substitution tags.
141It is analagous to L<HTML::Mason's
142default_escape_flags|HTML::Mason::Compiler/default_escape_flags> setting.
143
144=head2 Manual invocation
145
146L<$m-E<gt>filter|Mason::Request/filter> can be used to manually apply filter(s)
147to a string. It returns the filtered output. e.g.
148
149    <%init>
150    ...
151    my $filtered_string = $m->filter($.Trim, $.NoBlankLines, $string);
152    </%init>
153
154=head1 CREATING A FILTER
155
156=head2 Package and naming
157
158By convention, filters are placed in roles so that they can be composed into
159L<Mason::Component|Mason::Component> or a subclass thereof. Take a look at
160L<Mason::Filters::Standard|Mason::Filters::Standard> for an example.
161
162Also by convention, filters use CamelCase rather than traditional
163underscore_separated naming.  Filter methods have to coexist with other methods
164in the Mason::Component namespace, so have to be distinguishable somehow, and
165we thought this was preferable to a "filter_" prefix or suffix. Of course, you
166are free to choose your own convention, but you should expect this naming in
167the standard filters at least.
168
169Here's a filter package that implements two filters, C<Upper> and C<Lower>:
170
171    package MyApp::Filters;
172    use Mason::PluginRole;
173
174    method Upper () {
175        return sub { uc($_[0]) }
176    }
177
178    method Lower () {
179        return sub { lc($_[0]) }
180    }
181
182    1;
183
184To use these in a component:
185
186    <%class>
187    with 'MyApp::Filters';
188    </%class>
189
190    % $.Upper {{
191    ...
192    % }}
193
194Or if you want them available to all components, put them in C<Base.mp> at the
195top of your component hierarchy, or in your application's C<Mason::Component>
196subclass.
197
198=head2 Simple vs. dynamic filters
199
200A I<simple filter> is a code ref which takes a string (via either $_[0] and $_)
201and returns the output.  Your filter method should return this code ref. e.g.
202
203    # Uses $_[0]
204    method Upper () {
205        return sub { uc($_[0]) };
206    }
207
208    # Uses $_
209    method Rot13 () {
210        return sub { tr/a-zA-Z/n-za-mN-ZA-M/; $_ };
211    }
212
213A I<dynamic filter> is an object of class C<Mason::DynamicFilter>. It contains
214a code ref which takes a I<yield block> and returns the output. A yield block
215is a zero-argument code ref that returns a content string. e.g.  this is
216functionally identical to the above:
217
218    method Rot13 () {
219        return Mason::DynamicFilter->new(
220            filter => sub {
221                my $yield = $_[0];
222                my $text = $yield->();
223                $text =~ tr/a-zA-Z/n-za-mN-ZA-M/;
224                return $text;
225            }
226        );
227    }
228
229The dynamic filter obviously doesn't buy you anything in this case, and for the
230majority of filters they are unneeded.  The real power of dynamic filters is
231that they can choose if and when to execute the yield block. For example, here
232is an implementation (slightly expanded for explanatory purposes) of the  C<<
233Cache >> filter in L<Mason::Plugin::Cache|Mason::Plugin::Cache>:
234
235    method Cache ( $key, $set_options ) {
236        return Mason::DynamicFilter->new(
237            filter => sub {
238                my $yield = $_[0];
239                my $cache = $self->cache;
240                my $output = $cache->get( $key );
241                if (!$output) {
242                    $output = $yield->();
243                    $cache->set( $key, $output, $set_options );
244                }
245                return $output;
246            }
247        );
248    }
249
250Notice that we call C<< $cache->get >> first, and return the output immediately
251if it is in the cache. Only on a cache miss do we actually execute the
252(presumably expensive) yield block.
253
254C<< Defer >> and C<< Repeat >> are two other examples of dynamic filters. See
255L<Mason::Filters::Standard|Mason::Filters::Standard> for their implementations.
256
257=head2 <%filter> block
258
259You can use the C<< <%filter> >> block to define filters that output content.
260It works just like a C<< <%method> >> block, except that you can call C<<
261$yield->() >> to generate the original content. e.g.
262
263    <%filter Item ($class)>
264    <li class="<% $class %>"><% $yield->() %></li>
265    </%filter>
266
267    % $.Item('std') {{
268      First
269    % }}
270    % $.Item('std') {{
271      Second
272    % }}
273
274generates
275
276    <li class="std">
277      First
278    </li>
279    <li class="std">
280      Second
281    </li>
282
283=head1 SEE ALSO
284
285L<Mason::Filters::Standard|Mason::Filters::Standard>, L<Mason|Mason>
286
287=head1 AUTHOR
288
289Jonathan Swartz <swartz@pobox.com>
290
291=head1 COPYRIGHT AND LICENSE
292
293This software is copyright (c) 2012 by Jonathan Swartz.
294
295This is free software; you can redistribute it and/or modify it under
296the same terms as the Perl 5 programming language system itself.
297
298=cut
299