Permalink
Browse files

pod 2/3 phew..

  • Loading branch information...
1 parent d540bc7 commit 3db745371bc7fee5882620c42f2703646d97dafc @tomill tomill committed Feb 8, 2010
Showing with 420 additions and 36 deletions.
  1. +1 −1 Changes
  2. +4 −4 Makefile.PL
  3. +289 −15 README
  4. +6 −6 lib/Template/Semantic.pm
  5. +26 −0 lib/Template/Semantic/Cookbook.pod
  6. +32 −5 lib/Template/Semantic/Document.pm
  7. +60 −3 lib/Template/Semantic/Filter.pm
  8. +2 −2 t/07_default-filters.t
View
@@ -1,4 +1,4 @@
Revision history for Perl extension Template::Semantic
-0.01 Sat Jan 30 16:04:35 JST 2010
+0.01
- original version
View
@@ -1,18 +1,18 @@
use inc::Module::Install;
name 'Template-Semantic';
-all_from 'lib/Template/Semantic.pm';
+all_from 'lib/Template/Semantic.pm';
readme_from 'lib/Template/Semantic.pm';
+auto_set_repository;
requires 'XML::LibXML' => 1.69;
requires 'HTML::Selector::XPath';
requires 'Scalar::Util' => 1.19;
test_requires 'Test::More' => 0.88;
test_requires 'Test::Requires';
-use_test_base
+use_test_base;
author_tests 'xt';
+auto_install;
auto_include_deps;
-auto_set_repository;
-
WriteAll;
View
304 README
@@ -1,27 +1,301 @@
-This is Perl module Template::Semantic.
+NAME
+ Template::Semantic - Use pure XHTML/XML as a template
-INSTALLATION
+SYNOPSIS
+ use Template::Semantic;
+
+ print Template::Semantic->process('template.html', {
+ 'title, h1' => 'Naoki Tomita',
+ 'ul.urls li' => [
+ {
+ 'a' => 'Homepage >>',
+ 'a@href' => 'http://e8y.net/',
+ 'a@target' => undef,
+ },
+ {
+ 'a' => 'Twitter >>',
+ 'a@href' => 'http://twitter.com/tomita/',
+ 'a@target' => '_blank',
+ },
+ ],
+ });
-Template::Semantic installation is straightforward. If your CPAN shell is set up,
-you should just be able to do
+ template:
- % cpan Template::Semantic
+ <html>
+ <head><title>person name</title></head>
+ <body>
+ <h1>person name</h1>
+ <ul class="urls">
+ <li><a href="#" target="">his page</a></li>
+ </ul>
+ </body>
+ </html>
-Download it, unpack it, then build it as per the usual:
+ output:
- % perl Makefile.PL
- % make && make test
+ <html>
+ <head><title>Naoki Tomita</title></head>
+ <body>
+ <h1>Naoki Tomita</h1>
+ <ul class="urls">
+ <li><a href="http://e8y.net/">Homepage &gt;&gt;</a></li>
+ <li><a href="http://twitter.com/tomita/" targer="_blank">Twitter &gt;&gt;</a></li>
+ </ul>
+ </body>
+ </html>
-Then install it:
+DESCRIPTION
+ Template::Semantic is a template engine for XHTML/XML that does't use
+ any template syntax. This module takes pure XHTML/XML as a template, and
+ uses XPath or CSS selector to assign value.
- % make install
+ This is beta release. Feedbacks are welcome.
-DOCUMENTATION
+ See Template::Semantic::Cookbook for the practical examples.
-Template::Semantic documentation is available as in POD. So you can do:
+METHODS
+ $ts = Template::Semantic->new( %options )
+ This method constructs a new "Template::Semantic" object.
- % perldoc Template::Semantic
+ my $ts = Template::Semantic->new;
+ my $out = $ts->process(...);
-to read the documentation online with your favorite pager.
+ Template::Semantic uses XML::LibXML parser as follows by default.
+
+ my $parser = XML::LibXML->new;
+ $parser->no_newwork(1); # faster
+ $parser->recover(2); # = recover_silently(1) = no warnings
+
+ If you may not change this, call "process()" directly, skip "new()".
+
+ my $out = Template::Semantic->process(...);
+
+ Set %options if you want to change parser options:
+
+ * "parser"
+
+ Set if you want to replace XML parser. It should be XML::LibXML
+ based.
+
+ my $ts = Template::Semantic->new(
+ parser => $your_libxml_parser,
+ );
+
+ * (others)
+
+ All other parameters except "parser" are passed to XML parser
+ like "$parser->$key($value)".
+
+ my $ts = Template::Semantic->new(
+ recover => 1,
+ expand_xinclude => 1,
+ );
+
+ $out = $ts->process($filename, \%vars)
+ $out = $ts->process(\$text, \%vars)
+ $out = $ts->process(FH, \%vars)
+ Process a template and return Template::Semantic::Document object.
+
+ The first parameter is the input template that can take 3 types:
+
+ # filename
+ my $out = Tempalte::Semantic->('template.html', $vars);
+
+ # text reference
+ my $out = Tempalte::Semantic->(\'<html><body>foo</body></html>', $vars);
+
+ # file handle
+ my $out = Tempalte::Semantic->($fh, $vars);
+ my $out = Tempalte::Semantic->(\*DATA, $vars);
+
+ The second parameter $vars is a value set to bind the template. This
+ should be hash-ref of 'selector' => $value, ... See below.
+
+ $ts->define_filter($filtername, \&code)
+ See "Filter" section.
+
+SELECTOR
+ Use XPath expression or CSS selector as a selector (can be mixed).
+
+ print Tempalte::Semantic->process($template, {
+
+ # XPath sample that indicate tag:
+ '/html/body/h2[2]' => ...,
+ '//title | //h1' => ...,
+ '//img[@id="foo"]' => ...,
+ 'id("foo")' => ...,
+
+ # XPath sample that indicate attribute:
+ '//a[@id="foo"]/@href' => ...,
+ '//meta[@name="keywords"]/@content' => ...,
+
+ # CSS selector sample that indicate tag:
+ 'title' => ...,
+ '.foo span.bar' => ...,
+ '#foo' => ...,
+
+ # CSS selector sample that indicate attribute:
+ 'img#foo@src' => ...,
+ 'span.bar a@href' => ...,
+
+ });
+
+ Note 1: CSS selector is converted to XPath internally. You can use
+ '@attr' expression to indicate attribute in this module unlike CSS
+ format.
+
+ Note 2: You can use 'id()' function in XHTML (with "html xmlns="..."")
+ without using XML::LibXML::XPathContext. This module sets "xmlns="""
+ namespace declarations automatically if template like a XHTML.
+
+VALUE TYPE
+ Basics
+ * selector => $text
+
+ *Scalar:* Replace the inner content with this as Text.
+
+ $ts->process($template, {
+ 'h1' => 'foo & bar', # <h1></h1> => <h1>foo &amp; bar</h1>
+ '.foo@href' => '/foo', # <a href="#" class="foo">bar</a> => <a href="/foo" class="foo">bar</a>
+ });
+
+ * selector => \$html
+
+ *Scalar-ref:* Replace the inner content with this as flagment
+ XML/HTML.
+
+ $ts->process($template, {
+ 'h1' => \'<a href="#">foo</a>bar', # <h1></h1> => <h1><a href="#">foo</a>bar</h1>
+ });
+
+ * selector => undef
+
+ *undef:* Delete the element/attirbute that the selector indicates.
+
+ $ts->process($template, {
+ 'h1' => undef, # => every <h1> disappear
+ 'div.foo@class' => undef, # <div class="foo">foo</div> => <div>foo</div>
+ });
+
+ * selector => \&foo
+
+ *Code-ref:* Callback subroutine. Subroutine can user $_ as inner
+ HTML or first argument as XML::LibXML::Node object.
+
+ $ts->process($template, {
+ 'h1' => sub { uc }, # <h1>foo</h1> => <h1>FOO</h1>
+ 'h1' => sub {
+ my $node = shift;
+ $node->nodeName; # <h1>foo</h1> => <h1>h1</h1>
+ },
+ });
+
+ * selector => XML::LibXML::Node
+
+ Replace the inner content by the node.
+
+ $ts->process($template, {
+ 'h1' => do { XML::LibXML::Text->new('foo') },
+ });
+
+ * selector => Template::Semantic::Document
+
+ Replace the inner content by another "process()"-ed result.
+
+ $ts->process($template, {
+ 'div#content' => $ts->process('inner.html', ...),
+ });
+
+ * selector => { 'selector' => $value, ... }
+
+ *Hash-ref:* Sub query of the part.
+
+ $ts->process($template, {
+ 'div.header' => {
+ 'a' => undef, # => All <a> tag in <div class="header"> disappears
+ },
+ # same as above
+ 'div.header a' => undef,
+ });
+
+ Loop
+ * selector => [ \%row, \%row, ... ]
+
+ *Array-ref of Hash-refs:* Loop the part as template. Each item of
+ the arrey-ref should be hash-ref.
+
+ $ts->process($template, {
+ 'table.list tr' => [
+ { 'th' => 'aaa', 'td' => '001' },
+ { 'th' => 'bbb', 'td' => '002' },
+ { 'th' => 'ccc', 'td' => '003' },
+ ],
+ });
+
+ template:
+
+ <table class="list">
+ <tr>
+ <td></td>
+ <td></td>
+ </tr>
+ </table>
+
+ output:
+
+ <table class="list">
+ <tr>
+ <th>aaa</th>
+ <td>001</td>
+ </tr>
+ <tr>
+ <th>bbb</th>
+ <td>002</td>
+ </tr>
+ <tr>
+ <th>ccc</th>
+ <td>003</td>
+ </tr>
+ </table>
+
+ Filter
+ * selector => [ $value, \&filter, 'filter', PIPE('foo'), ... ]
+
+ *Array-ref of Scalars:* Value and filters. Filter can take A)
+ Callback subroutine or B) Defined filter name or C) Object like
+ Text::Pipe("it->can('filter')").
+
+ $ts->process($template, {
+ 'h1' => [ 'foo', sub { uc }, sub { "$_!" } ], # <h1></h1> => <h1>FOO!</h1>
+ 'h2' => [ ' foo ', 'trim', sub { "$_!" } ], # <h2></h2> => <h2>FOO!</h2>
+ 'h3' => [ 'foo', PIPE('UppercaseFirst') ], # <h3></h3> => <h3>Foo</h3>
+ });
+
+ default filters
+ Some basic filters included. See Template::Semantic::Filter.
+
+ define filter name
+ You can define the your filter name using "define_filter()".
+
+ $ts->define_filter(wow => sub { "$_!!!" })
+ $ts->process($template, {
+ 'h1' => [ 'foo', 'wow' ], # <h1></h1> => <h1>FOO!!!</h1>
+ });
+
+SEE ALSO
+ Template::Semantic::Cookbook: for the practical examples.
+
+ XML::LibXML, HTML::Selector::XPath
+
+ Template::Refine, Web::Scraper: got a lot of ideas. thanks!
+
+AUTHOR
+ Naoki Tomita <tomita@cpan.org>
+
+ Feedbacks, patches, POD English check are always welcome!
+
+LICENSE
+ This library is free software; you can redistribute it and/or modify it
+ under the same terms as Perl itself.
-Naoki Tomita
View
@@ -167,7 +167,7 @@ C<< $parser->$key($value) >>.
=item $out = $ts->process(FH, \%vars)
-Process a template and return L<Template::Semantic::Document> object.
+Process a template and returns L<Template::Semantic::Document> object.
The first parameter is the input template that can take 3 types:
@@ -308,7 +308,7 @@ I<Hash-ref:> Sub query of the part.
=item * selector => [ \%row, \%row, ... ]
-I<Array-ref of Hash-refs:> Loop the part as template. Each item of the arrey-ref should be hash-ref.
+I<Array-ref of Hash-refs:> Loop the part as template. Each item of the array-ref should be hash-ref.
$ts->process($template, {
'table.list tr' => [
@@ -359,14 +359,14 @@ B) Defined filter name or
C) Object like L<Text::Pipe>(C<< it->can('filter') >>).
$ts->process($template, {
- 'h1' => [ 'foo', sub { uc }, sub { "$_!" } ], # <h1></h1> => <h1>FOO!</h1>
- 'h2' => [ ' foo ', 'trim', sub { "$_!" } ], # <h2></h2> => <h2>FOO!</h2>
- 'h3' => [ 'foo', PIPE('UppercaseFirst') ], # <h3></h3> => <h3>Foo</h3>
+ 'h1' => [ 'foo', sub { uc }, sub { "$_!" } ], # => <h1>FOO!</h1>
+ 'h2' => [ ' foo ', 'trim', sub { "$_!" } ], # => <h2>FOO!</h2>
+ 'h3' => [ 'foo', PIPE('UppercaseFirst') ], # => <h3>Foo</h3>
});
=over 4
-=item default filters
+=item defined filters by default
Some basic filters included. See L<Template::Semantic::Filter>.
Oops, something went wrong.

0 comments on commit 3db7453

Please sign in to comment.