• Save
Template::Semantic in Yokohama.pm
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,828
On Slideshare
1,536
From Embeds
292
Number of Embeds
6

Actions

Shares
Downloads
3
Comments
0
Likes
1

Embeds 292

http://e8y.net 280
http://blog.e8y.net 5
http://new.koneta.org 3
http://www.slideshare.net 2
http://blog.koneta.org 1
http://webcache.googleusercontent.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Naoki Tomita (tomi-ru) http://e8y.net/ 2010/3/5 Yokohama.pm #5
  • 2. Synopsis use Template::Semantic; use utf8; my $res = Template::Semantic->process('template.html', { 'title, .title' => '神奈川 & Me', 'img#photo@src' => 'kanagawa.jpg', 'table#list tr' => [ { 'th' => '川崎', 'td' => 'IMAX 3D良かった' }, { 'th' => '溝の口', 'td' => 'サンレッド大好き' }, ], }); print $res; # note: flagged text 2
  • 3. template.html <html> <head><title>場所</title></head> <body> <h1><span class="title">○○</span>おすすめスポット</h1> <img src="sample.jpg" id="photo" /><br /> <table id="list"> <tr> <th>場所</th> <td>説明!!</td> </tr> </table> </body> </html> • use pure XHTML/XML as a template 3
  • 4. output: <html> <head><title>神奈川 &amp; Me</title></head> <body> <h1><span class="title">神奈川 &amp; Me</span>おすすめスポット</h1> <img src="kanagawa.jpg" id="photo" /><br /> <table id="list"> <tr> <th>川崎</th> <td>IMAX 3D良かった</td> </tr> <tr> <th>溝の口</th> <td>サンレッド大好き</td> </tr> </table> </body> </html> 4
  • 5. Template::Semantic is ... • Web::Scraper / jQuery / CSS users friendly • inspired by Template::Refine • not replace TT completely • but focus on TT users • based on XML::LibXML • さくらインターネットセーフ (shared server JP) • Ideas: • mock-up HTML as a template • re-editing another app output • ... 5
  • 6. Usage print Template::Semantic->process($template, $vars); • custom libxml options my $tmpl = Template::Semantic->new( … # options ); print $tmpl->process($template, $vars); 6
  • 7. $template # file path print Template::Semantic->process('filename.html', $vars); # scalar-ref print Template::Semantic->process('<div>foo</div>', $vars); # filehandle, GLOB print Template::Semantic->process($fh, $vars); print Template::Semantic->process(*DATA, $vars); 7
  • 8. $vars print Template::Semantic->process($template, { 'selector' => 'value', 'selector' => 'value', 'selector' => 'value', 'selector' => 'value', }); 8
  • 9. 'selector': XPath/CSS selector print Template::Semantic->process($template, { '//title | //h1[1]' => ..., 'id("foo")' => ..., '//a[@id="foo"]/@href' => ..., 'title, h1' => ..., 'img#foo@src' => ..., # original syntax }); 9
  • 10. 'value': scalar, scalar-ref, undef 'h1' => 'foo & bar', # scalar: innerText # <h1>xxx</h1> => # <h1>foo &amp; bar</h1> 'h1' => '<a href="#">foo</a>bar', # scalar-ref: innerHTML # <h1>xxx</h1> => # <h1><a href="#">foo</a>bar</h1> 'h1' => undef, # undef: delete # <h1>xxx</h1> => # 10
  • 11. 'value': datalist <table class="list"> class="list"> print Template::Semantic->process(*DATA, { <tr> # array-ref: loop <th>aaa</th> <th>aaa</th> 'table.list tr' => [ <td>001</td> <td>001</td> { 'th' => 'aaa', 'td' => '001' }, </tr> </tr> { 'th' => 'bbb', 'td' => '002' }, <tr> { 'th' => 'ccc', 'td' => '003' }, <th>bbb</th> <th>bbb</th> ], <td>002</td> <td>002</td> }); </tr> </tr> <tr> __DATA__ <th>ccc</th> <th>ccc</th> <table class="list"> <td>003</td> <td>003</td> <tr> </tr> </tr> <th>foo</th> </table> </table> <td>bar</td> </tr> </table> 11
  • 12. 'value': callback 'h1' => sub { uc }, # $_ = innerHTML # <h1>xxx</h1> => # <h1>XXX</h1> 'h1' => sub { my $node = shift; # $_[0] = XML::LibXML::Element $node->nodeName; }, # <h1>xxx</h1> => # <h1>h1</h1> 12
  • 13. 'value': pipe filter print Template::Semantic->process($template, { 'p.entry' => [ $text, 'html_line_break' ], }); defined filter (Template::Semantic::Filter) my $ts = Template::Semantic->new; $ts->define_filter(markdown => sub { markdown($_) }); print $ts->process($template, { 'p.entry' => [ $text, 'markdown' ], }); note: you should not make T::S::Filter::* maybe 13
  • 14. ->process(...)->process(...) print Template::Semantic->process(*DATA, { '.a' => 'foo', '.b' => 'bar', '.c' => 'baz', })->process({ '@class' => undef, <html> }); <div>foo</div> <div>bar</div> __DATA__ <div>baz</div> <html> </html> <div class="a">aaa</div> <div class="b">bbb</div> <div class="c">ccc</div> </html> 14
  • 15. Template::Semantic::Cookbook • Zebra tables • JavaScript vars • Include • Template inheritance • Email template • ... 15
  • 16. XML::LibXML tips & tricks in Template::Semantic • for nervous XML::LibXML • recover(2) = recover_silently(1) = no warnings • auto fix s/&/&amp;/ • almost the same XML::Liberal • Against default namespace • <html xmlns="http://www.w3.org/1999/xhtml"> • use '//div' without XML::LibXML::XPathContext • XPath id("foo") function • allow id="foo" instead of xml:id="foo" • "Virtual DTD(XHTML)" for XHTML fragment • e.g. not <textarea/> but <textarea></textarea> 16
  • 17. Question? • "include_path", "cache" ? • You should make wrapper for your app. • Speed: • T::MT>>T::S>TT • HTML5? • some HTML5 (valid as XHTML) => OK • some HTML5 (e.g. <input … checked >) => NG (as yet). 17
  • 18. Recommended rule • use id="foo" ('#foo') only. • make some classes for the filter. • e.g. • '.dummy' for delete • '.comma' for comma filter 18