forgot page
[sdlgit/SDL-Site.git] / code / HTML / Zoom.pm
CommitLineData
9d159224 1package HTML::Zoom;
2
3use strict;
4use warnings FATAL => 'all';
5use Carp qw(confess);
6
7use HTML::Zoom::EventFilter;
8use HTML::Zoom::SelectorParser;
9use HTML::Zoom::ActionBuilder;
10use HTML::Zoom::Parser::BuiltIn;
11
12sub new {
13 my $proto = shift;
14 my $class = ref($proto) || $proto;
15 bless({}, $class);
16}
17
18sub _clone_with {
19 my ($self, %clone) = @_;
20 bless({ %$self, %clone }, ref($self));
21}
22
23sub from_string {
24 my $new = shift->new;
25 $new->{source_html} = shift;
26 $new;
27}
28
29sub from_fh {
30 my $new = shift->new;
31 my $fh = $_[0];
32 $new->{source_html} = do { local $/; <$fh> || die "from_fh: $!" };
33 $new;
34}
35
36sub with_selectors {
37 my $self = shift;
38 my $pairs = [];
39 while (my @spec = splice(@_, 0, 2)) {
40 push(
41 @$pairs,
42 HTML::Zoom::EventFilter->build_selector_pair(@spec)
43 );
44 }
45 $self->_clone_with(
46 _selector_handler => HTML::Zoom::EventFilter->selector_handler($pairs)
47 );
48}
49
50sub render_to {
51 my ($self, $out) = @_;
52 $self->_clone_with(
53 _emitter => HTML::Zoom::EventFilter->standard_emitter($out)
54 )->render;
55}
56
57sub render {
58 my ($self) = @_;
59 my $s_h = $self->{_selector_handler};
60 $s_h->set_next($self->{_emitter});
61 HTML::Zoom::Parser::BuiltIn::_hacky_tag_parser(
62 $self->{source_html}, sub { $s_h->call(@_) }
63 );
64 $self;
65}
66
67=head1 NAME
68
69HTML::Zoom - Lightweight CSS selector based HTML templating
70
71=head1 SYNOPSIS
72
73 use HTML::Zoom;
74
75 my $html = <<HTML;
76 <html>
77 <head>
78 <title>Hello people</title>
79 </head>
80 <body>
81 <h1 id="greeting">Placeholder</h1>
82 <div id="list">
83 <span>
84 <p>Name: <span class="name">Bob</span></p>
85 <p>Age: <span class="age">23</span></p>
86 </span>
87 <hr class="between" />
88 </div>
89 </body>
90 </html>
91 HTML
92
93 HTML::Zoom->from_string($html)
94 ->add_selectors(
95 'title, #greeting' => 'Hello world & dog!',
96 '#list' => [
97 { '.name' => 'Matt',
98 '.age' => 26
99 },
100 { '.name' => 'Mark',
101 '.age' => '0x29'
102 },
103 { '.name' => 'Epitaph',
104 '.age' => '<redacted>'
105 },
106 'span:odd p' => { -add_class => 'alt' },
107 ]
108 )
109 ->stream_to(\*STDOUT)
110 ->render;
111
112will print -
113
114 <html>
115 <head>
116 <title>Hello world &amp; dog!</title>
117 </head>
118 <body>
119 <h1 id="greeting">Hello world &amp; dog!</h1>
120 <div id="list">
121 <span>
122 <p>Name: <span class="name">Matt</span></p>
123 <p>Age: <span class="age">26</span></p>
124 <span>
125 <hr class="between" />
126 <span>
127 <p class="alt">Name: <span class="name">Mark</span></p>
128 <p class="alt">Age: <span class="age">0x29</span></p>
129 <span>
130 <hr class="between" />
131 <span>
132 <p>Name: <span class="name">Epitaph</span></p>
133 <p>Age: <span class="age">&lt;redacted&gt;</span></p>
134 <span>
135 </div>
136 </body>
137 </html>
138
139Using a layout -
140
141 <html>
142 <head>
143 <title>default title</title>
144 </head>
145 <body>
146 <img src="/logo.jpg" />
147 </body>
148 </html>
149
150=head1 SELECTORS
151
152http://docs.jquery.com/Selectors
153
154=cut
155
1561;