0
MasonA Template System for us programmers           March 2013 - http://www.eteve.net
A bit of myth busting●   Mason is old●   Mason is a viewcontroller●   Mason is too complex●   Mason is slow●   Mason uses ...
Mason is oldMason 1 is old (HTML::Mason)Mason 2 released in 02/2011Complete Moosified rewrite
Mason is a viewtrollerKind of true for Mason 1But that was 10 years agoMason 2 is a pure templating systemThe controller b...
Mason is too complexAugmentationInheritanceCompositionMethod modifiersDynamic filters
Mason is too complexAugmentationInheritanceCompositionMethod modifiersDynamic filtersBut wait..
We are programmers   So it should be just fine
Mason is slowHum, well...Compared to TT (as complex as TT can takebenchmark)      Rate Mason TTMason 909/s -- -53%TT   192...
Mason is slow - butPower comes with a price tagExperience shows it scales very well withcomplexity
Mason is slow - butPower comes with a price tagExperience shows it scales very well withcomplexityThe benchmark I wrote is...
Mason is slow - but honestlyDo we use Perl because its faster than X?
Mason uses embedded PerlPrefer PHP?
Mason uses embedded PerlOr worse, a mini-language ?
Mason uses embedded PerlPerl is just fine no?use <Anything you like>;
The basics - Embedded code% while( my $product = $products->next() ){<p>Buy our great    <% $product->name() | H %>.    It...
And now, some cool Mason stuff
Augmentation - A typical page               Header            Main content               Footer
Augmentation - Non Mason-ish/index.mc<& /comp/header.mi &>Welcome to index!<& /comp/footer.mi &>
Augmentation - The Mason Base.mc/Base.mc<%augment wrap> <html><head><title>Site</title></head> <body>  <% inner() %> <body...
Augmentation - a page/index.mc<h1>Welcome</h1>
Augmentation - a pageEvaluates to<html><head><title>Site</title></head> <body>  <h1>Welcome</h1> <body></html>
Augmentation - another page?/products.mc<ul> <li>Lathe</li> <li>Piano</li></ul>
Augmentation - another page?Evaluates to ..Well you get the idea
Augmentation - Become specific/products/Base.mc<%augment wrap><div class="product">  <% inner() %></div></%product>
Augmentation - Become specific/products/lathe.mc<h1>Lathe</h1>
Augmentation - Become specificEvaluates to<html> <head><title>Site</title></head> <body>  <div class="product">    <h1>Lat...
Augmentation - Wanna go bare?/products/baremetal.mc<%flags> extends => undef</%flags><h1>Some bare content</h1>Evaluates t...
A typical layout/index                   Header                   Menu               Content                   Footer
A typical layout/products/lathe.html                       Header                       Menu                 Share Box    ...
A typical layout/errors/404.html                   Header                    Menu               Error description         ...
Augmentation - Layout controlTypical hierarchy/layout/Base.mc/layout/withmenu.mc/Base.mc/index.mc/products/Base.mc/product...
Augmentation - Layout control/layout/Base.mc<%flags>  extends => undef</%flags><%augment wrap><html> <head><title>My site<...
Augmentation - Layout control/layout/withmenu.mc<%flags>  extends => undef</%flags><%augment wrap> <div class="menu">...</...
Augmentation - Layout control/Base.mc<%flags>  extends => /layout/withmenu.mc</%flags>
Augmentation - Layout control/index.mc<h1>This is index</h1>
Augmentation - Layout control/products/Base.mc<%augment wrap> <div class="share">...</div> <div class="product"> <% inner(...
Augmentation - Layout control/products/lathe.mc<h1>This is a lathe</h1>
Augmentation - Layout control/errors/Base.mc<%flags>extends => /layout/Base.mc</%flags><%augment wrap><div class="error"><...
Augmentation - Layout control/errors/404.mc<h1>Sorry, nothing here</h1>
Actually, I want the menu in the errorpagesNo problem:/errors/Base.mc<%flags>extends => /layout/Base.mc</%flags><%augment ...
And now, inheritance   And method modifiers
Lets speak about page titlesRemember /layout/Base.mc ?<%flags> inherit => undef</%flags><%method title>Site</%method><%aug...
Now the index title<%method title>Welcome to Site!</%method><h1>This is index</h1>
The lathe.mc<%after title> - Lathe</%method><h1>This is a Lathe</h1>Renders as:<title>Site - Lathe</title>
a_product.mc<%class> has product => ( isa => My::Product,                    required => 1 );</%class><%after title> - <% ...
a_product.mcIn Catalyst$c->stash()->{product} = $product;a_product.mc instance is built with whats onthe stash
a_product.mcTrivial unit testingmy $mason = Mason->new();my $p_page = $mason->run(/products/a_product, product => $p )->ou...
Composition And a bit more
Classic composition/comp/share.mi<%class>  has stuff => ( does => Sharable );</%class><div class="share">Share <% $.stuff-...
Composition - New /products/Base.mc/products/Base.mc<%class> has product => ( isa => Product );<%augment wrap> <& /comp/sh...
Internal components arecomponentsSo inheritance works/comp/share/advanced.mi<%flags> extends => /comp/share.mi</%flags>Adv...
Internal components - Unit testingmy $m = $mason->_make_request();my $m_text = $m->scomp(/comp/share.mi,                  ...
FiltersMore powerful than it sounds
A Simple filter% $.NoBlankLines {{HelloWorld% }}Renders:HelloWorld
With argument(s)% my $i = 1;% $.Repeat(3) {{<% $i++ %> % }}Renders:123
With parametric content% my $nums = [ 1 , 2 , 3 ];% $.Loop($nums) {{% my ( $num ) = @_;<% $num %>, % }}Renders:1, 2, 3,
Filters - Make your ownpackage My::Mason::Filters;use Mason::PluginRole;method Iterate($on){Mason::DynamicFilter->new(  fi...
Filters - Make your own/Base.mc<%class>with My::Mason::Filter;</%class>/anywhere% $.Iterate($resultset){{% my ($result) = ...
Filters - As component/comp/pager.mi<%class>  has on => ( isa => DBIx::Class::Resulset );  has page => ( isa => Int , defa...
Filters - As component/comp/pager.mi .. Continued%# Some paging was output% $.Iterate($rs){{% my $stuff = $_[0];<% $.yield...
Lets use our pager/products/index.mc<$class> has products => ( isa => DBIx::Resultset );</$class>% $.CompCall(/comp/page.m...
Filters can be curried<%class> has lang; has Translate ( lazy_build => 1 ); sub _build_Translate{   my ($self) = @_;   $se...
Filters - One more nice one% $.Cache($key , 10 minute) {{ <div class="sluggish">   .... </div>% }}Combine with currying fo...
ConclusionsIn case youre not convinced yet
Mason helps writing clean codeStrict by defaultEnforce type consistency a-la MooseEnforce stash content (With Catalyst)Min...
Mason is powerfulCode the view like a programmer withinheritance, augmentation, method modifiers,dynamic filters, currying...
Mason is extensibleBase class injection.my $mason = Mason->new(base_*_class =>MyApp::Mason::*Subclass );Or Role based Plug...
ReferenceIn order of preference● MasonHQ: http://www.masonhq.com/● Cpan: Mason● Cpan: Catalyst::View::Mason2● Mailing list...
Give it a go$ sudo apt-get install libmason-perl$ echo "Hello world" > mason/index.mc$ mason.pl mason/index.mc$ ## In cata...
Questions?Thanks for your watching!
Upcoming SlideShare
Loading in...5
×

Mason - A Template system for us Perl programmers

1,139

Published on

Templating Modules are a bit like editors. Every web application developer has a favourite one. And every template system is someone's favorite.

Mine is Mason. But not because the Perl MVC tutorials are full of examples using Mason. Not because it's the fastest (use xSlate if you want to trade speed for flexibility). Not because it's the most popular. It's my favourite for a very plain reason: It makes me more productive and allows me to develop web GUIs using all the powerful features a programmer should biterly miss if they are taken away. That includes writing Perl code :P

I never heard of a business that went down because they didn't have fast enough CPUs, so I'm not fussy about trading a few CPU cycles for elegance, ease and speed of development.

Published in: Technology
1 Comment
0 Likes
Statistics
Notes
  • % git clone https://bitbucket.org/jeteve/mason-pres.git

    foil bokutin (master) % perl bench.pl Rate TT Mason TT 1724/s -- -10% Mason 1923/s 12% -- foil bokutin (master) % perl -MTemplate -E 'say $Template::VERSION' 2.24 foil bokutin (master) % perl -MMason -E 'say $Mason::VERSION' 2.20 foil bokutin (master) % LANG=C date Fri Jun 14 01:44:52 JST 2013
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

No Downloads
Views
Total Views
1,139
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
4
Comments
1
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Mason - A Template system for us Perl programmers"

  1. 1. MasonA Template System for us programmers March 2013 - http://www.eteve.net
  2. 2. A bit of myth busting● Mason is old● Mason is a viewcontroller● Mason is too complex● Mason is slow● Mason uses embedded Perl
  3. 3. Mason is oldMason 1 is old (HTML::Mason)Mason 2 released in 02/2011Complete Moosified rewrite
  4. 4. Mason is a viewtrollerKind of true for Mason 1But that was 10 years agoMason 2 is a pure templating systemThe controller bit has been moved to Poet
  5. 5. Mason is too complexAugmentationInheritanceCompositionMethod modifiersDynamic filters
  6. 6. Mason is too complexAugmentationInheritanceCompositionMethod modifiersDynamic filtersBut wait..
  7. 7. We are programmers So it should be just fine
  8. 8. Mason is slowHum, well...Compared to TT (as complex as TT can takebenchmark) Rate Mason TTMason 909/s -- -53%TT 1923/s 112% --
  9. 9. Mason is slow - butPower comes with a price tagExperience shows it scales very well withcomplexity
  10. 10. Mason is slow - butPower comes with a price tagExperience shows it scales very well withcomplexityThe benchmark I wrote is not bigfat.Have a look:https://bitbucket.org/jeteve/mason-pres/
  11. 11. Mason is slow - but honestlyDo we use Perl because its faster than X?
  12. 12. Mason uses embedded PerlPrefer PHP?
  13. 13. Mason uses embedded PerlOr worse, a mini-language ?
  14. 14. Mason uses embedded PerlPerl is just fine no?use <Anything you like>;
  15. 15. The basics - Embedded code% while( my $product = $products->next() ){<p>Buy our great <% $product->name() | H %>. Its only <% $product->price() | H %> </p>%}With DefaultFilter set to H:<% $product->name() %>
  16. 16. And now, some cool Mason stuff
  17. 17. Augmentation - A typical page Header Main content Footer
  18. 18. Augmentation - Non Mason-ish/index.mc<& /comp/header.mi &>Welcome to index!<& /comp/footer.mi &>
  19. 19. Augmentation - The Mason Base.mc/Base.mc<%augment wrap> <html><head><title>Site</title></head> <body> <% inner() %> <body></html></%augment>
  20. 20. Augmentation - a page/index.mc<h1>Welcome</h1>
  21. 21. Augmentation - a pageEvaluates to<html><head><title>Site</title></head> <body> <h1>Welcome</h1> <body></html>
  22. 22. Augmentation - another page?/products.mc<ul> <li>Lathe</li> <li>Piano</li></ul>
  23. 23. Augmentation - another page?Evaluates to ..Well you get the idea
  24. 24. Augmentation - Become specific/products/Base.mc<%augment wrap><div class="product"> <% inner() %></div></%product>
  25. 25. Augmentation - Become specific/products/lathe.mc<h1>Lathe</h1>
  26. 26. Augmentation - Become specificEvaluates to<html> <head><title>Site</title></head> <body> <div class="product"> <h1>Lathe</h1> </div> <body></html>
  27. 27. Augmentation - Wanna go bare?/products/baremetal.mc<%flags> extends => undef</%flags><h1>Some bare content</h1>Evaluates to<h1>Some bare content</h1>
  28. 28. A typical layout/index Header Menu Content Footer
  29. 29. A typical layout/products/lathe.html Header Menu Share Box Product description Footer
  30. 30. A typical layout/errors/404.html Header Menu Error description Footer
  31. 31. Augmentation - Layout controlTypical hierarchy/layout/Base.mc/layout/withmenu.mc/Base.mc/index.mc/products/Base.mc/products/lathe.mc/errors/Base.mc/errors/404.mc
  32. 32. Augmentation - Layout control/layout/Base.mc<%flags> extends => undef</%flags><%augment wrap><html> <head><title>My site</title></head> <body><% inner() %></body></html></%augment>
  33. 33. Augmentation - Layout control/layout/withmenu.mc<%flags> extends => undef</%flags><%augment wrap> <div class="menu">...</div> <% inner() %></%augment>
  34. 34. Augmentation - Layout control/Base.mc<%flags> extends => /layout/withmenu.mc</%flags>
  35. 35. Augmentation - Layout control/index.mc<h1>This is index</h1>
  36. 36. Augmentation - Layout control/products/Base.mc<%augment wrap> <div class="share">...</div> <div class="product"> <% inner() %> </div></%augment>
  37. 37. Augmentation - Layout control/products/lathe.mc<h1>This is a lathe</h1>
  38. 38. Augmentation - Layout control/errors/Base.mc<%flags>extends => /layout/Base.mc</%flags><%augment wrap><div class="error"><% inner() %></div></%augment>
  39. 39. Augmentation - Layout control/errors/404.mc<h1>Sorry, nothing here</h1>
  40. 40. Actually, I want the menu in the errorpagesNo problem:/errors/Base.mc<%flags>extends => /layout/Base.mc</%flags><%augment wrap><div class="error"><% inner() %></div></%augment>
  41. 41. And now, inheritance And method modifiers
  42. 42. Lets speak about page titlesRemember /layout/Base.mc ?<%flags> inherit => undef</%flags><%method title>Site</%method><%augment wrap>... <title><% $.title() %></title> ...</%augment>
  43. 43. Now the index title<%method title>Welcome to Site!</%method><h1>This is index</h1>
  44. 44. The lathe.mc<%after title> - Lathe</%method><h1>This is a Lathe</h1>Renders as:<title>Site - Lathe</title>
  45. 45. a_product.mc<%class> has product => ( isa => My::Product, required => 1 );</%class><%after title> - <% $.product->title() %></%after><h1>This is a <% $.product->title() %></h1>
  46. 46. a_product.mcIn Catalyst$c->stash()->{product} = $product;a_product.mc instance is built with whats onthe stash
  47. 47. a_product.mcTrivial unit testingmy $mason = Mason->new();my $p_page = $mason->run(/products/a_product, product => $p )->output;ok_contains($p_page , $p->name() );
  48. 48. Composition And a bit more
  49. 49. Classic composition/comp/share.mi<%class> has stuff => ( does => Sharable );</%class><div class="share">Share <% $.stuff->share_name() %> on blabla</div>
  50. 50. 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>
  51. 51. Internal components arecomponentsSo inheritance works/comp/share/advanced.mi<%flags> extends => /comp/share.mi</%flags>Advanced share <% $.stuff->share_name() %>
  52. 52. Internal components - Unit testingmy $m = $mason->_make_request();my $m_text = $m->scomp(/comp/share.mi, p => Banana );ok_contains($m_text, "Share Banana");
  53. 53. FiltersMore powerful than it sounds
  54. 54. A Simple filter% $.NoBlankLines {{HelloWorld% }}Renders:HelloWorld
  55. 55. With argument(s)% my $i = 1;% $.Repeat(3) {{<% $i++ %> % }}Renders:123
  56. 56. With parametric content% my $nums = [ 1 , 2 , 3 ];% $.Loop($nums) {{% my ( $num ) = @_;<% $num %>, % }}Renders:1, 2, 3,
  57. 57. Filters - Make your ownpackage 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; });}
  58. 58. Filters - Make your own/Base.mc<%class>with My::Mason::Filter;</%class>/anywhere% $.Iterate($resultset){{% my ($result) = @_; This is result <% $result->name() %>!%}}
  59. 59. 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>
  60. 60. Filters - As component/comp/pager.mi .. Continued%# Some paging was output% $.Iterate($rs){{% my $stuff = $_[0];<% $.yield->($stuff) %>% }}%# Some other paging maybe?
  61. 61. Lets use our pager/products/index.mc<$class> has products => ( isa => DBIx::Resultset );</$class>% $.CompCall(/comp/page.mi,on=>$.products){{% my ( $product ) = @_; Product <% product->name() %>% }}
  62. 62. 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% }}
  63. 63. Filters - One more nice one% $.Cache($key , 10 minute) {{ <div class="sluggish"> .... </div>% }}Combine with currying for cleaner code :)
  64. 64. ConclusionsIn case youre not convinced yet
  65. 65. Mason helps writing clean codeStrict by defaultEnforce type consistency a-la MooseEnforce stash content (With Catalyst)Minimal global variablesEasy unit testing
  66. 66. Mason is powerfulCode the view like a programmer withinheritance, augmentation, method modifiers,dynamic filters, currying ..No change of mindset requiredChanges are simple and consistentWriting a new pages is trivial
  67. 67. Mason is extensibleBase class injection.my $mason = Mason->new(base_*_class =>MyApp::Mason::*Subclass );Or Role based Plugins (and Plugins Bundles)For instance: Mason::Plugin::Cache
  68. 68. ReferenceIn order of preference● MasonHQ: http://www.masonhq.com/● Cpan: Mason● Cpan: Catalyst::View::Mason2● Mailing list● Jerome :P
  69. 69. 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
  70. 70. Questions?Thanks for your watching!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×