Download - Mason - A Template system for us Perl programmers

Transcript
Page 1: Mason - A Template system for us Perl programmers

MasonA Template System for us programmers

March 2013 - http://www.eteve.net

Page 2: Mason - A Template system for us Perl programmers

A bit of myth busting

● Mason is old● Mason is a viewcontroller● Mason is too complex● Mason is slow● Mason uses embedded Perl

Page 3: Mason - A Template system for us Perl programmers

Mason is old

Mason 1 is old (HTML::Mason)

Mason 2 released in 02/2011

Complete Moosified rewrite

Page 4: Mason - A Template system for us Perl programmers

Mason is a viewtroller

Kind of true for Mason 1

But that was 10 years ago

Mason 2 is a pure templating system

The controller bit has been moved to Poet

Page 5: Mason - A Template system for us Perl programmers

Mason is too complex

AugmentationInheritanceCompositionMethod modifiersDynamic filters

Page 6: Mason - A Template system for us Perl programmers

Mason is too complex

AugmentationInheritanceCompositionMethod modifiersDynamic filters

But wait..

Page 7: Mason - A Template system for us Perl programmers

We are programmersSo it should be just fine

Page 8: Mason - A Template system for us Perl programmers

Mason is slow

Hum, well...

Compared to TT (as complex as TT can take benchmark)

Rate Mason TTMason 909/s -- -53%TT 1923/s 112% --

Page 9: Mason - A Template system for us Perl programmers

Mason is slow - but

Power comes with a price tag

Experience shows it scales very well with complexity

Page 10: Mason - A Template system for us Perl programmers

Mason is slow - but

Power comes with a price tag

Experience shows it scales very well with complexity

The benchmark I wrote is not bigfat.Have a look:

https://bitbucket.org/jeteve/mason-pres/

Page 11: Mason - A Template system for us Perl programmers

Mason is slow - but honestly

Do we use Perl because it's faster than X?

Page 12: Mason - A Template system for us Perl programmers

Mason uses embedded Perl

Prefer PHP?

Page 13: Mason - A Template system for us Perl programmers

Mason uses embedded Perl

Or worse, a mini-language ?

Page 14: Mason - A Template system for us Perl programmers

Mason uses embedded Perl

Perl is just fine no?

use <Anything you like>;

Page 15: Mason - A Template system for us Perl programmers

The basics - Embedded code

% while( my $product = $products->next() ){ <p>Buy our great <% $product->name() | H %>. It's only <% $product->price() | H %> </p>% }

With DefaultFilter set to H:<% $product->name() %>

Page 16: Mason - A Template system for us Perl programmers

And now, some cool Mason stuff

Page 17: Mason - A Template system for us Perl programmers

Header

Main content

Footer

Augmentation - A typical page

Page 18: Mason - A Template system for us Perl programmers

Augmentation - Non Mason-ish

/index.mc<& /comp/header.mi &>Welcome to index!<& /comp/footer.mi &>

Page 19: Mason - A Template system for us Perl programmers

Augmentation - The Mason Base.mc

/Base.mc<%augment wrap> <html><head><title>Site</title></head> <body> <% inner() %> <body></html></%augment>

Page 20: Mason - A Template system for us Perl programmers

Augmentation - a page

/index.mc<h1>Welcome</h1>

Page 21: Mason - A Template system for us Perl programmers

Augmentation - a page

Evaluates to <html><head><title>Site</title></head> <body> <h1>Welcome</h1> <body></html>

Page 22: Mason - A Template system for us Perl programmers

Augmentation - another page?

/products.mc<ul> <li>Lathe</li> <li>Piano</li></ul>

Page 23: Mason - A Template system for us Perl programmers

Augmentation - another page?

Evaluates to ..

Well you get the idea

Page 24: Mason - A Template system for us Perl programmers

Augmentation - Become specific

/products/Base.mc<%augment wrap> <div class="product"> <% inner() %> </div></%product>

Page 25: Mason - A Template system for us Perl programmers

Augmentation - Become specific

/products/lathe.mc<h1>Lathe</h1>

Page 26: Mason - A Template system for us Perl programmers

Augmentation - Become specific

Evaluates to<html> <head><title>Site</title></head> <body> <div class="product"> <h1>Lathe</h1> </div> <body></html>

Page 27: Mason - A Template system for us Perl programmers

Augmentation - Wanna go bare?

/products/baremetal.mc<%flags> extends => undef</%flags><h1>Some bare content</h1>

Evaluates to<h1>Some bare content</h1>

Page 28: Mason - A Template system for us Perl programmers

A typical layout

/index

Header

Menu

Content

Footer

Page 29: Mason - A Template system for us Perl programmers

A typical layout

/products/lathe.htmlHeader

Menu

Share BoxProduct description

Footer

Page 30: Mason - A Template system for us Perl programmers

A typical layout

/errors/404.htmlHeader

Menu

Error description

Footer

Page 31: Mason - A Template system for us Perl programmers

Augmentation - Layout control

Typical hierarchy/layout/Base.mc/layout/withmenu.mc/Base.mc/index.mc/products/Base.mc/products/lathe.mc/errors/Base.mc/errors/404.mc

Page 32: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/layout/Base.mc<%flags> extends => undef</%flags><%augment wrap><html> <head><title>My site</title></head> <body><% inner() %></body></html></%augment>

Page 33: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/layout/withmenu.mc<%flags> extends => undef</%flags><%augment wrap> <div class="menu">...</div> <% inner() %></%augment>

Page 34: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/Base.mc<%flags> extends => '/layout/withmenu.mc'</%flags>

Page 35: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/index.mc<h1>This is index</h1>

Page 36: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/products/Base.mc<%augment wrap> <div class="share">...</div> <div class="product"> <% inner() %> </div></%augment>

Page 37: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/products/lathe.mc<h1>This is a lathe</h1>

Page 38: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/errors/Base.mc<%flags> extends => '/layout/Base.mc'</%flags><%augment wrap><div class="error"><% inner() %></div></%augment>

Page 39: Mason - A Template system for us Perl programmers

Augmentation - Layout control

/errors/404.mc<h1>Sorry, nothing here</h1>

Page 40: Mason - A Template system for us Perl programmers

Actually, I want the menu in the error pages

No problem:/errors/Base.mc<%flags> extends => '/layout/Base.mc'</%flags><%augment wrap><div class="error"><% inner() %></div></%augment>

Page 41: Mason - A Template system for us Perl programmers

And now, inheritanceAnd method modifiers

Page 42: Mason - A Template system for us Perl programmers

Let's speak about page titles

Remember /layout/Base.mc ?<%flags> inherit => undef</%flags><%method title>Site</%method><%augment wrap> ... <title><% $.title() %></title> ...</%augment>

Page 43: Mason - A Template system for us Perl programmers

Now the index title

<%method title>Welcome to Site!</%method><h1>This is index</h1>

Page 44: Mason - A Template system for us Perl programmers

The lathe.mc

<%after title> - Lathe</%method><h1>This is a Lathe</h1>

Renders as:<title>Site - Lathe</title>

Page 45: Mason - A Template system for us Perl programmers

a_product.mc

<%class> has 'product' => ( isa => 'My::Product', required => 1 );</%class><%after title> - <% $.product->title() %></%after><h1>This is a <% $.product->title() %></h1>

Page 46: Mason - A Template system for us Perl programmers

a_product.mc

In Catalyst

$c->stash()->{product} = $product;

a_product.mc instance is built with what's on the stash

Page 47: Mason - A Template system for us Perl programmers

a_product.mc

Trivial unit testing

my $mason = Mason->new();

my $p_page = $mason->run('/products/a_product', product => $p )->output;

ok_contains($p_page , $p->name() );

Page 48: Mason - A Template system for us Perl programmers

CompositionAnd a bit more

Page 49: Mason - A Template system for us Perl programmers

Classic composition

/comp/share.mi<%class> has 'stuff' => ( does => 'Sharable' );</%class><div class="share">Share <% $.stuff->share_name() %> on blabla</div>

Page 50: Mason - A Template system for us Perl programmers

Composition - New /products/Base.mc

/products/Base.mc<%class> has 'product' => ( isa => 'Product' );<%augment wrap> <& /comp/share.mi , stuff => $.product &> <div class="product"> <% inner() %> </div></%augment>

Page 51: Mason - A Template system for us Perl programmers

Internal components are components

So inheritance works

/comp/share/advanced.mi<%flags> extends => '/comp/share.mi'</%flags>Advanced share <% $.stuff->share_name() %>

Page 52: Mason - A Template system for us Perl programmers

Internal components - Unit testing

my $m = $mason->_make_request();my $m_text = $m->scomp('/comp/share.mi', p => 'Banana' );

ok_contains($m_text, "Share Banana");

Page 53: Mason - A Template system for us Perl programmers

FiltersMore powerful than it sounds

Page 54: Mason - A Template system for us Perl programmers

A Simple filter

% $.NoBlankLines {{Hello

World% }}Renders:HelloWorld

Page 55: Mason - A Template system for us Perl programmers

With argument(s)

% my $i = 1;% $.Repeat(3) {{<% $i++ %> \% }}

Renders:1 2 3

Page 56: Mason - A Template system for us Perl programmers

With parametric content

% my $nums = [ 1 , 2 , 3 ];% $.Loop($nums) {{% my ( $num ) = @_;<% $num %>, \% }}

Renders:1, 2, 3,

Page 57: Mason - A Template system for us Perl programmers

Filters - Make your own

package My::Mason::Filters;use Mason::PluginRole;method Iterate($on){ Mason::DynamicFilter->new( filter => sub{ my ($yield) = @_;my $txt = ''; while( my $next = $on->next() ){ $txt .= $yield->($next); } return $txt; });}

Page 58: Mason - A Template system for us Perl programmers

Filters - Make your own

/Base.mc<%class> with My::Mason::Filter;</%class>/anywhere% $.Iterate($resultset){{% my ($result) = @_; This is result <% $result->name() %>!%}}

Page 59: Mason - A Template system for us Perl programmers

Filters - As component

/comp/pager.mi<%class> has 'on' => ( isa => 'DBIx::Class::Resulset' ); has 'page' => ( isa => 'Int' , default => 1 ); has 'yield';</%class>% my $rs=$.on->search({} , {page => $.page});<div class="pager">.. Do stuff with $rs->page() ..</div>

Page 60: Mason - A Template system for us Perl programmers

Filters - As component

/comp/pager.mi .. Continued

%# Some paging was output% $.Iterate($rs){{% my $stuff = $_[0]; <% $.yield->($stuff) %>% }}%# Some other paging maybe?

Page 61: Mason - A Template system for us Perl programmers

Let's use our pager

/products/index.mc<$class> has 'products' => ( isa => 'DBIx::Resultset' );</$class>% $.CompCall('/comp/page.mi',on=>$.products){{% my ( $product ) = @_; Product <% product->name() %>% }}

Page 62: Mason - A Template system for us Perl programmers

Filters can be curried<%class> has 'lang'; has 'Translate' ( lazy_build => 1 ); sub _build_Translate{ my ($self) = @_; $self->TranslateIn($self->lang));}</%class>% $.Translate(){{Some Text% }}

Page 63: Mason - A Template system for us Perl programmers

Filters - One more nice one% $.Cache($key , '10 minute') {{ <div class="sluggish"> .... </div>% }}

Combine with currying for cleaner code :)

Page 64: Mason - A Template system for us Perl programmers

ConclusionsIn case you're not convinced yet

Page 65: Mason - A Template system for us Perl programmers

Mason helps writing clean code

Strict by default

Enforce type consistency a-la Moose

Enforce stash content (With Catalyst)

Minimal global variables

Easy unit testing

Page 66: Mason - A Template system for us Perl programmers

Mason is powerful

Code the view like a programmer with inheritance, augmentation, method modifiers, dynamic filters, currying ..

No change of mindset required

Changes are simple and consistent

Writing a new pages is trivial

Page 67: Mason - A Template system for us Perl programmers

Mason is extensible

Base class injection.

my $mason = Mason->new(base_*_class => 'MyApp::Mason::*Subclass' );

Or Role based Plugins (and Plugins Bundles)

For instance: Mason::Plugin::Cache

Page 68: Mason - A Template system for us Perl programmers

Reference

In order of preference● MasonHQ: http://www.masonhq.com/● Cpan: Mason● Cpan: Catalyst::View::Mason2● Mailing list● Jerome :P

Page 69: Mason - A Template system for us Perl programmers

Give it a go

$ sudo apt-get install libmason-perl$ echo "Hello world" > mason/index.mc$ mason.pl mason/index.mc

$ ## In catalyst$ sudo cpan -i Catalyst::View::Mason2

Page 70: Mason - A Template system for us Perl programmers

Thanks for your watching!

Questions?