Skip to content

Commit

Permalink
deprecated old Mojo::Template block syntax and added a very pretty re…
Browse files Browse the repository at this point in the history
…placement
  • Loading branch information
kraih committed Aug 30, 2010
1 parent e0ab007 commit 6ac074b
Show file tree
Hide file tree
Showing 11 changed files with 208 additions and 193 deletions.
2 changes: 2 additions & 0 deletions Changes
@@ -1,6 +1,8 @@
This file documents the revision history for Perl extension Mojolicious.

0.999930 2010-08-17 00:00:00
- Deprecated old Mojo::Template block syntax and added a very pretty
replacement.
- Added EXPERIMENTAL support for --mode and --home options to all
Mojolicious commands.
- Added EXPERIMENTAL write, write_chunk and rendered methods to
Expand Down
121 changes: 59 additions & 62 deletions lib/Mojo/Template.pm
Expand Up @@ -15,8 +15,8 @@ use constant CHUNK_SIZE => $ENV{MOJO_CHUNK_SIZE} || 262144;

__PACKAGE__->attr([qw/auto_escape compiled namespace/]);
__PACKAGE__->attr([qw/append code prepend/] => '');
__PACKAGE__->attr(capture_end => '}');
__PACKAGE__->attr(capture_start => '{');
__PACKAGE__->attr(capture_end => 'end');
__PACKAGE__->attr(capture_start => 'block');
__PACKAGE__->attr(comment_mark => '#');
__PACKAGE__->attr(encoding => 'UTF-8');
__PACKAGE__->attr(escape_mark => '=');
Expand All @@ -31,8 +31,8 @@ __PACKAGE__->attr(trim_mark => '=');
# Helpers
my $HELPERS = <<'EOF';
no strict 'refs'; no warnings 'redefine';
sub block;
*block = sub { shift->(@_) };
sub filter;
*filter = sub { shift->(@_) };
sub escape;
*escape = sub {
my $v = shift;
Expand Down Expand Up @@ -190,52 +190,70 @@ sub parse {
my $capture_start = quotemeta $self->capture_start;
my $capture_end = quotemeta $self->capture_end;

# DEPRECATED in Comet!
# Use "block" and "end" instead of "{" and "}"
my $mixed_re = qr/
(
$tag_start$capture_start$expr$escp # Escaped expression (start)
|
$tag_start$expr$escp # Escaped expression
|
$tag_start$capture_start$expr # Expression (start)
|
$tag_start$expr # Expression
|
$tag_start$capture_end$cmnt # Comment (end)
$tag_start$cmnt\s*$capture_end # Comment (end)
|
$tag_start$capture_start$cmnt # Comment (start)
$tag_start$cmnt\} # DEPRECATED Comment (end)
|
$tag_start$cmnt # Comment
|
$tag_start$capture_end # Code (end)
$tag_start\s*$capture_end # Code (end)
|
$tag_start$capture_start # Code (start)
$tag_start\} # DEPRECATED Code (end)
|
$tag_start # Code
|
$trim$capture_start$tag_end # Trim end (start)
$capture_start\s*$trim$tag_end # Trim end (start)
|
\{$trim$tag_end # DEPRECATED Trim end (start)
|
$trim$tag_end # Trim end
|
$capture_start$tag_end # End (start)
$capture_start\s*$tag_end # End (start)
|
\{$tag_end # DEPRECATED End (start)
|
$tag_end # End
)
/x;

# Capture regex
my $token_capture_re =
qr/^($tag_start|$tag_end)($capture_end|$capture_start)/;
# Capture end regex
my $capture_end_re = qr/
^(
$tag_start # Start
)
(?:
\s*$capture_end # (end)
|
\} # DEPRECATED (end)
)
/x;

# Tag end regex
my $end_re = qr/
^(
$trim$capture_start$tag_end # Trim end (start)
(?:
$capture_start\s*$trim$tag_end # Trim end (start)
|
\{$trim$tag_end # DEPRECATED Trim end (start)
)
)|(
$capture_start$tag_end # End (start)
(?:
$capture_start\s*$tag_end # End (start)
|
\{$tag_end # DEPRECATED End (start)
)
)|(
$trim$tag_end # Trim end
$trim$tag_end # Trim end
)|
$tag_end # End
$tag_end # End
$
/x;

Expand All @@ -245,40 +263,30 @@ sub parse {
my @capture_token;
my $trimming = 0;
for my $line (split /\n/, $tmpl) {
my @capture;

# Perl line with capture end or start
if ($line =~ /^$line_start($capture_end|$capture_start)/) {
my $capture = $1;
$line =~ s/^($line_start)$capture/$1/;
@capture =
("\\$capture" eq $capture_end ? 'cpen' : 'cpst', undef);
}

# Perl line with return value that needs to be escaped
if ($line =~ /^$line_start$expr$escp(.+)?$/) {
push @{$self->tree}, [@capture, 'escp', $1];
push @{$self->tree}, ['escp', $1];
$multiline_expression = 0;
next;
}

# Perl line with return value
if ($line =~ /^$line_start$expr(.+)?$/) {
push @{$self->tree}, [@capture, 'expr', $1];
push @{$self->tree}, ['expr', $1];
$multiline_expression = 0;
next;
}

# Comment line, dummy token needed for line count
if ($line =~ /^$line_start$cmnt(.+)?$/) {
push @{$self->tree}, [@capture];
$multiline_expression = 0;
next;
}

# Perl line without return value
if ($line =~ /^$line_start([^\>]{1}.*)?$/) {
push @{$self->tree}, [@capture, 'code', $1];
push @{$self->tree}, ['code', $1];
$multiline_expression = 0;
next;
}
Expand Down Expand Up @@ -309,14 +317,9 @@ sub parse {
# Done trimming
$trimming = 0 if $trimming && $state ne 'text';

# Perl token with capture end or start
if ($token =~ /$token_capture_re/) {
my $tag = quotemeta $1;
my $capture = quotemeta $2;
$token =~ s/^($tag)$capture/$1/;
@capture_token =
($capture eq $capture_end ? 'cpen' : 'cpst', undef);
}
# Capture end
@capture_token = ('cpen', undef)
if $token =~ s/$capture_end_re/$1/;

# End
if ($state ne 'text' && $token =~ /$end_re/) {
Expand Down Expand Up @@ -573,21 +576,15 @@ Whitespace characters around tags can be trimmed with a special tag ending.
<%= All whitespace characters around this expression will be trimmed =%>
You can capture whole template blocks for reuse later.
You can capture whole template blocks for reuse later with the C<block> and
C<end> keywords.
<% my $block = {%>
<% my $block = block %>
<% my $name = shift; =%>
Hello <%= $name %>.
<%}%>
<%= $block->('Sebastian') %>
<%= $block->('Sara') %>
%{ my $block =
% my $name = shift;
Hello <%= $name %>.
%}
%= $block->('Baerbel')
%= $block->('Wolfgang')
<% end %>
<%= $block->('Baerbel') %>
<%= $block->('Wolfgang') %>
L<Mojo::Template> templates work just like Perl subs (actually they get
compiled to a Perl sub internally).
Expand Down Expand Up @@ -673,24 +670,24 @@ Append Perl code to compiled template.
=head2 C<capture_end>
my $capture_end = $mt->capture_end;
$mt = $mt->capture_end('}');
$mt = $mt->capture_end('end');
Character indicating the end of a capture block, defaults to C<}>.
Keyword indicating the end of a capture block, defaults to C<end>.
%{ $block =
<% my $block = block %>
Some data!
%}
<% end %>
=head2 C<capture_start>
my $capture_start = $mt->capture_start;
$mt = $mt->capture_start('{');
$mt = $mt->capture_start('block');
Character indicating the start of a capture block, defaults to C<{>.
Keyword indicating the start of a capture block, defaults to C<block>.
<% my $block = {%>
<% my $block = block %>
Some data!
<%}%>
<% end %>
=head2 C<code>
Expand Down
32 changes: 16 additions & 16 deletions lib/Mojolicious/Guides/Rendering.pod
Expand Up @@ -239,9 +239,9 @@ used to generate C<HTML> tags.

<%= script '/script.js' %>

<%= script {%>
<%= script block %>
var a = 'b';
<%}%>
<% end %>

The plugins L<Mojolicious::Plugin::DefaultHelpers> and
L<Mojolicious::Plugin::TagHelpers> contain all of them.
Expand Down Expand Up @@ -318,10 +318,10 @@ Of course you can also pass stash values.
It's never fun to repeat yourself, thats why you can build reusable template
blocks in C<ep> that work very similar normal Perl functions.

<% my $block = {%>
<% my $block = block %>
<% my $name = shift; %>
Hello <%= $name %>.
<%}%>
<% end %>
<%= $block->('Sebastian') %>
<%= $block->('Sara') %>

Expand All @@ -330,10 +330,10 @@ containing only the closing bracket.
Whitespace characters between bracket and tag are not allowed, to
differentiate between template blocks and normal Perl code.

<% my $block = {%>
<% my $block = block %>
<% my $name = shift; %>
Hello <%= $name %>.
<%}%>
<% end %>
<% for (1 .. 10) { %>
<%= $block->('Sebastian') %>
<% } %>
Expand All @@ -359,9 +359,9 @@ the template to the layout.

@@ foo/bar.html.ep
% layout 'mylayout';
<% content header => {%>
<% content header => block %>
<title>MyApp!</title>
<%}%>
<% end %>
Hello World!

@@ layouts/mylayout.html.ep
Expand All @@ -381,27 +381,27 @@ extended templates don't get prefixed with C<layout/>.
@@ first.html.ep
%# "<div>First header!First footer!</div>"
<div>
<%= content header => {%>
<%= content header => block %>
First header!
<%}%>
<%= content footer => {%>
<% end %>
<%= content footer => block %>
First footer!
<%}%>
<% end %>
</div>

@@ second.html.ep
%# "<div>Second header!First footer!</div>"
% extends 'first';
<% content header => {%>
<% content header => block %>
Second header!
<%}%>
<% end %>

@@ third.html.ep
%# "<div>Second header!Third footer!</div>"
% extends 'second';
<% content footer => {%>
<% content footer => block %>
Third footer!
<%}%>
<% end %>

This chain could go on and on to allow a very high level of template reuse.

Expand Down

0 comments on commit 6ac074b

Please sign in to comment.