Permalink
Browse files

Replace <% { %> <% } %> </%> with line-based filter - % ... {{; Short…

…en $m->apply_filter to $m->filter, allow it to take multiple filters and either a string or code ref; Set $_ to content as well as $_[0] in filter
  • Loading branch information...
1 parent a7a7496 commit edcbcc956f71214d357a9ba4aa7c6de694faad39 @jonswar committed Jun 13, 2011
@@ -1,13 +1,13 @@
<h2>Add an article</h2>
-<% $.FillInForm($form_data) { %>
+% $.FillInForm($form_data) {{
<form action="/article/publish" method=post>
<p>Title: <input type=text size=30 name=title></p>
<p>Text:</p>
<textarea name=content rows=20 cols=70></textarea>
<p><input type=submit value="Publish"></p>
</form>
-</%>
+% }}
<%init>
my $form_data = delete($m->req->session->{form_data});
View
@@ -120,9 +120,9 @@ method parse () {
$self->_match_unnamed_block && ( $lm = 'unnamed_block' ) && next;
$self->_match_named_block && ( $lm = 'named_block' ) && next;
$self->_match_unknown_block && ( $lm = 'unknown_block' ) && next;
- $self->_match_apply_filter && ( $lm = 'apply_filter' ) && next;
$self->_match_substitution && ( $lm = 'substitution' ) && next;
$self->_match_component_call && ( $lm = 'component_call' ) && next;
+ $self->_match_apply_filter && ( $lm = 'apply_filter' ) && next;
$self->_match_perl_line && ( $lm = 'perl_line' ) && next;
$self->_match_bad_close_tag && ( $lm = 'bad_close_tag' ) && next;
$self->_match_plain_text && ( $lm = 'plain_text' ) && next;
@@ -223,10 +223,10 @@ method _handle_apply_filter ($filter_expr) {
pos( $self->{source} ) += $incr;
}
else {
- $self->_throw_syntax_error("<% { %> without matching </%>");
+ $self->_throw_syntax_error("'{{' without matching '}}'");
}
my $code = sprintf(
- "\$self->m->_apply_filters_to_output([%s], %s);\n",
+ "\$self->m->_apply_filters_to_output(%s, %s);\n",
$self->_processed_perl_code($filter_expr),
$self->_output_method($method)
);
@@ -450,33 +450,24 @@ method _handle_text_block ($contents) {
method _match_apply_filter () {
my $pos = pos( $self->{source} );
- # Match <% ... { %>
- if ( $self->{source} =~ /\G(\n)? <% (.+?) (\s*\{\s*) %>(\n)?/xcgs ) {
- my ( $preceding_newline, $filter_expr, $opening_brace, $following_newline ) =
- ( $1, $2, $3, $4 );
-
- # and make sure we didn't go through a %>
- if ( $filter_expr !~ /%>/ ) {
- for ( $preceding_newline, $filter_expr, $following_newline ) {
- $self->{line_number} += tr/\n// if defined($_);
- }
- $self->_handle_apply_filter($filter_expr);
-
- return 1;
- }
- else {
- pos( $self->{source} ) = $pos;
- }
+ # Match % ... {{ at beginning of line
+ if ( $self->{source} =~ / \G (?<=^) % ([^\n]*) \{\{ \n /gcmx ) {
+ my ($filter_expr) = ($1);
+ $self->_handle_apply_filter($filter_expr);
+ return 1;
}
return 0;
}
method _match_apply_filter_end () {
- if ( $self->{current_method}->{type} eq 'apply_filter'
- && $self->{source} =~ /\G (?: (?: <% [ \t]* \} [ \t]* %> ) | (?: <\/%> ) ) (\n?\n?)/gcx )
- {
- $self->{end_parse} = pos( $self->{source} );
- return 1;
+ if ( $self->{source} =~ / \G (?<=^) % [ \t]+ \}\} (?:\n\n?|\z) /gmcx ) {
+ if ( $self->{current_method}->{type} eq 'apply_filter' ) {
+ $self->{end_parse} = pos( $self->{source} );
+ return 1;
+ }
+ else {
+ $self->_throw_syntax_error("'}}' without matching '{{'");
+ }
}
return 0;
}
@@ -63,9 +63,9 @@ L<Mason::Component|Mason::Component>.
Uses C<< $m->capture >> to capture the content in I<$ref>.
- <% $.Capture(\my $content) { %>
+ % $.Capture(\my $content) {{
<!-- this will end up in $content -->
- </%>
+ % }}
... do something with $content
@@ -78,9 +78,9 @@ via C<@_>. This is the replacement for Mason 1's L<Components With
Content|http://search.cpan.org/perldoc?HTML::Mason::Devel#Component_Calls_with_Content>.
In index.mc:
- <% $.CompCall ('list_items.mi', items => \@items) { %>
+ % $.CompCall ('list_items.mi', items => \@items) {{
<li><% $_[0] %></li>
- <% } %>
+ % }}
In list_items.mi:
<%args>
@@ -103,9 +103,9 @@ each time, which may result in different content.
<!-- Prints 1 to 5 -->
% my $i = 1;
- <% $.Repeat(5) { %>
+ % $.Repeat(5) {{
<% $i++ %><br>
- </%>
+ % }}
=item Trim
@@ -17,72 +17,85 @@ on CPAN, and it is easy to create your own.
Here's the standard way of invoking a filter:
- <% $.Trim { %>
- This string will be trimmed
- </%>
+ % $.Trim {{
+ This string will be trimmed
+ % }}
-An open brace at the end of a C<< <% %> >> tag denotes a filter call. The
-filtered content begins just afterwards and ends at the C<< </%> >> tag.
+A double open brace (C<< {{ >>) at the end of a C<< %-line >> denotes a filter
+call. The filtered content begins just afterwards and ends at the C<< }} >>.
The expression C<< $.Trim >>, aka C<< $self->Trim >>, is a method call on the
-component object which returns a filter. In general everything before the brace
-is evaluated and is expected to return a filter or list of filters.
+component object which returns a filter. In general everything before the C<<
+{{ >> is evaluated and is expected to return a filter or list of filters.
By convention, and to avoid name clashes with other component methods, filters
use CamelCase rather than traditional underscore names.
Filters can take arguments:
- <% $.Repeat(3) { %>
+ % $.Repeat(3) {{
There's no place like home.
- </%>
+ % }}
==> There's no place like home.
There's no place like home.
There's no place like home.
-Again, the expression C<< $.Repeat(3) >> returns a filter, meaning that it can
-be curried:
+Since the expression C<< $.Repeat(3) >> returns a filter, it can be curried:
% my $repeat_three = $.Repeat(3);
- <% $repeat_three { %>
+ % $repeat_three {{
There's no place like home.
- </%>
+ % }}
-A simple filter is just a subroutine that takes text as input and return the
-new text. Thus you can create one-off filters with anonymous subroutines:
+You can create one-off filters with anonymous subroutines. The subroutine
+receives the content in both C<< $_[0] >> and C<< $_ >>, and should return the
+filtered content.
- <% sub { reverse($_[0]) } { %>Hello</%>
+ % sub { reverse($_[0]) } {{
+ Hello
+ % }}
==> olleH
-Filters can be nested, with separate tags:
- <% $.Trim { %>
- <% sub { uc($_[0]) } { %>
- This string will be trimmed and uppercased
- </%>
- </%>
+ % sub { s/ //g; $_[0] } {{
+ A bunch of words
+ % }}
-or within a single tag:
+ ==> Abunchofwords
- <% $.Trim, sub { uc($_[0]) } { %>
+Filters can be nested, with separate lines:
+
+ % $.Trim {{
+ % sub { uc($_[0]) } {{
+ This string will be trimmed and uppercased
+ % }}
+ % }}
+
+or on a single line:
+
+ % $.Trim, sub { uc($_[0]) } {{
This will be trimmed and uppercased
- </%>
+ % }}
Multiple filters within the same tag are applied, intuitively, in reverse order
with the last one being innermost. e.g. in this block
% my $i = 1;
- <% $.Repeat(3), $.Cache($key, '1 hour') { %> <% $i++ %> </%>
+ % $.Repeat(3), $.Cache($key, '1 hour') {{
+ <% $i++ %>
+ % }}
=> 1 1 1
the output of C<< <% $i++ %> >> is cached, and then repeated three times,
whereas in this block
% my $i = 1;
- <% $.Cache($key, '1 hour'), $.Repeat(3) { %> <% $i++ %> </%>
+ % $.Cache($key, '1 hour'), $.Repeat(3) {{
+ <% $i++ %>
+ % }}
=> 1 2 3
@@ -112,8 +125,13 @@ C<HTML> filter in L<Mason::Plugin::HTMLFilters|Mason::Plugin::HTMLFilters>:
=head2 Manual invocation
-L<apply_filter|Mason::Request/apply_filter> can be used to manually apply a
-filter to a string. It returns the filtered output.
+L<$m-E<gt>filter|Mason::Request/filter> can be used to manually apply filter(s)
+to a string. It returns the filtered output. e.g.
+
+ <%init>
+ ...
+ my $filtered_string = $m->filter($.Trim, $string);
+ </%init>
=head1 CREATING A FILTER
@@ -151,18 +169,18 @@ To use these in a component:
with 'MyApp::Filters';
</%class>
- <% $.Upper { %>
+ % $.Upper {{
...
- </%>
+ % }}
Or if you want them available to all components, put them in C<Base.mp> at the
top of your component hierarchy, or in your application's C<Mason::Component>
subclass.
=head2 Simple vs. dynamic filters
-A I<simple filter> is a code ref which takes a string and returns the output.
-Your filter method should return this code ref. e.g.
+A I<simple filter> is a code ref which takes a string (via either $_[0] and $_)
+and returns the output. Your filter method should return this code ref. e.g.
method Rot13 () {
return sub {
@@ -227,13 +245,21 @@ $yield->() >> to generate the original content. e.g.
<li class="<% $class %>"><% $yield->() %></li>
</%filter>
- <% $.Item('std') { %> First </%>
- <% $.Item('std') { %> Second </%>
+ % $.Item('std') {{
+ First
+ % }}
+ % $.Item('std') {{
+ Second
+ % }}
generates
- <li class="std"> First </li>
- <li class="std"> Second </li>
+ <li class="std">
+ First
+ </li>
+ <li class="std">
+ Second
+ </li>
=head1 SEE ALSO
@@ -285,7 +285,9 @@ generate the original content. e.g.
</tr>
</%filter>
- <% $.Row('std') { %> First Second Third </%>
+ % $.Row('std') {{
+ First Second Third
+ % }}
generates
@@ -542,14 +542,14 @@ submitted values when validation fails.
1 <h2>Add an article</h2>
2
- 3 <% $.FillInForm($form_data) { %>
+ 3 % $.FillInForm($form_data) {{
4 <form action="/article/publish" method=post>
5 <p>Title: <input type=text size=30 name=title></p>
6 <p>Text:</p>
7 <textarea name=content rows=20 cols=70></textarea>
8 <p><input type=submit value="Publish"></p>
9 </form>
- 10 </%>
+ 10 % }}
11
12 <%init>
13 my $form_data = delete($m->req->session->{form_data});
View
@@ -18,10 +18,10 @@ request
<head>
<title><% $m->defer(sub { $m->page->title }) %></title>
- <% $.Defer { %>
- % my $content = join(", ", @{ $m->page->meta_content });
+ % $.Defer {{
+ % my $content = join(", ", @{ $m->page->meta_content });
<meta name="description" content="<% $content %>">
- </%>
+ % }}
<body>
...
@@ -54,10 +54,10 @@ associated code. e.g.
Applies C<< $m->defer >> to the content block. e.g.
- <% $.Defer { %>
- % my $content = join(", ", @{ $m->page->meta_content });
+ % $.Defer {{
+ % my $content = join(", ", @{ $m->page->meta_content });
<meta name="description" content="<% $content %>">
- </%>
+ % }}
=back
Oops, something went wrong.

0 comments on commit edcbcc9

Please sign in to comment.