File Coverage

blib/lib/Kwiki/PageTemplate.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Kwiki::PageTemplate;
2 1     1   1199 use Kwiki::Plugin -Base;
  0            
  0            
3             use mixin 'Kwiki::Installer';
4             our $VERSION = '0.04';
5              
6             use YAML;
7             use List::Util qw(max);
8              
9             const class_id => 'page_template';
10             const cgi_class => 'Kwiki::PageTemplate::CGI';
11             const config_file => 'page_template.yaml';
12             const css_file => 'page_template.css';
13              
14             field fields => {};
15             field previewed => 0;
16              
17             sub register {
18             my $reg = shift;
19             $reg->add(action => 'new_from_page_template');
20             $reg->add(action => 'edit_page_template_content');
21             $reg->add(wafl => field => 'Kwiki::PageTemplate::FieldPhrase');
22             $reg->add(wafl => page_template => 'Kwiki::PageTemplate::TemplateBlock');
23             $reg->add(wafl => page_template_display => 'Kwiki::PageTemplate::DisplayBlock');
24             $reg->add(wafl => page_template_fields => 'Kwiki::PageTemplate::FieldBlock');
25             $reg->add(wafl => page_template_content => 'Kwiki::PageTemplate::ContentBlock');
26             }
27              
28             sub init {
29             super;
30             $self->use_class('formatter');
31             }
32              
33             sub new_from_page_template {
34             my $fields = $self->fields_of($self->cgi->template_page);
35             $self->fields($fields);
36             my %raw = $self->cgi->vars;
37             my %values;
38             $values{$_} = $raw{"field_$_"} for keys %$fields;
39             my $tpinfo = {template => $self->cgi->template_page, values => \%values};
40             my $waflblock = $self->make_page_template_content($tpinfo);
41             $self->cgi->button eq $self->config->page_template_save_button_text ?
42             $self->save_new_page($waflblock): $self->preview($waflblock,$tpinfo);
43             }
44              
45             sub preview {
46             my ($waflblock,$tpinfo) = @_;
47             my $preview = $self->formatter->text_to_html($waflblock);
48             $preview =~ s{]*?>}{}gs;
49             my $page = $self->cgi->defined('save_to_page') ?
50             $self->cgi->save_to_page : '';
51             $self->previewed(1);
52             $self->render_edit_form($tpinfo,$page,$preview);
53             }
54              
55             sub save_new_page {
56             my $content = shift;
57             my $page = $self->get_page;
58             $page->content($content);
59             $page->store;
60             $self->redirect($page->id);
61             }
62              
63             sub make_page_template_content {
64             my $mark = ".page_template_content\n";
65             $mark.YAML::Dump(shift)."\n$mark";
66             }
67              
68             sub extract_page_template_content {
69             my $page_content = shift;
70             $page_content =~ s{(\.page_template_content)\n(.+)\n\1}{$2}sg;
71             YAML::Load($page_content);
72             }
73              
74             sub render_edit_form {
75             my ($content,$page_id,$preview) = @_;
76             my $tp = $self->pages->new_page($content->{template})->content;
77             while(my ($k,$v) = each %{$content->{values}}) {
78             # XXX: $self->uri_escape() somehow doesn't work well
79             $v =~ s/%/%25/g; $v =~ s/\n/%0A/g; $v =~ s/\r/%0D/g;
80             $tp =~ s/{field:\s*$k(.*?)?}/{field: $k , value:$v}/sg;
81             }
82             my $html = $self->formatter->text_to_html($tp);
83             my $save_to = $page_id ?
84             qq{} :
85             "";
86             $html =~ s{(}
87             {$1"$content->{template}" />$save_to}s;
88             $self->render_screen(
89             content_pane => 'page_template_edit_content.html',
90             preview => $preview,
91             page_template_content => $html
92             );
93             }
94              
95             sub edit_page_template_content {
96             my $page_id = $self->cgi->page_id;
97             my $ptc = $self->hub->pages->new_page($page_id)->content;
98             my $content = $self->extract_page_template_content($ptc);
99             $self->render_edit_form($content,$page_id);
100             }
101              
102             sub fields_of {
103             my $content = $self->hub->pages->new_page(shift)->content;
104             my $mark = ".page_template_fields";
105             $content =~ /$mark\n(.+?)$mark/s;
106             YAML::Load($1);
107             }
108              
109             sub get_page {
110             $self->cgi->defined('save_to_page') ?
111             $self->pages->new_page($self->cgi->save_to_page) :
112             $self->create_page($self->cgi->page_id_prefix) ;
113             }
114              
115             sub create_page {
116             my $prefix = shift;
117             my $num = 1 + max(map {s/^.*?(\d+)$/$1/; $_} grep { /^$prefix/ }
118             $self->hub->pages->all_ids_newest_first);
119             $self->pages->new_page("${prefix}${num}");
120             }
121              
122             sub extract_display_block {
123             my $content = shift;
124             if( $content =~ /^\.page_template_display$/m ) {
125             $content =~ s{.*(\.page_template_display)\s+(.*)\s+\1.*}{$2}s;
126             } else {
127             $content =~ s{.*(\.page_template)\s+(.*)\s+\1.*}{$2}s;
128             }
129             $content;
130             }
131              
132             sub render {
133             my ($template_page,$values) = @_;
134             my $c = $self->extract_display_block
135             ($self->pages->new_page($template_page)->content);
136             $c =~ s/{field:\s*$_\s*.*}/$values->{$_}/ for keys %$values;
137             $self->template_process(
138             'page_template_content.html',
139             content => $self->formatter->text_to_html($c)
140             );
141             }
142              
143             package Kwiki::PageTemplate::FieldBlock;
144             use base 'Spoon::Formatter::WaflBlock';
145              
146             sub to_html {
147             $self->hub->page_template->fields(YAML::Load($self->block_text));
148             "";
149             }
150              
151             package Kwiki::PageTemplate::ContentBlock;
152             use base 'Spoon::Formatter::WaflBlock';
153              
154             sub to_html {
155             my $p = YAML::Load($self->block_text);
156             $self->hub->page_template->render($p->{template},$p->{values});
157             }
158              
159             package Kwiki::PageTemplate::DisplayBlock;
160             use base 'Spoon::Formatter::WaflBlock';
161              
162             sub to_html { '' }
163              
164             package Kwiki::PageTemplate::TemplateBlock;
165             use base 'Spoon::Formatter::WaflBlock';
166              
167             sub to_html {
168             my $plugin = $self->hub->page_template;
169             my $prefix = $plugin->fields->{page_id_prefix}
170             || $self->hub->config->page_template_page_id_prefix;
171             $plugin->template_process(
172             'page_template_form.html',
173             template_page => $plugin->pages->current->id,
174             content => $self->hub->formatter->text_to_html($self->block_text) ,
175             page_template_page_id_prefix => $prefix
176             );
177             }
178              
179             package Kwiki::PageTemplate::CGI;
180             use base 'Kwiki::CGI';
181              
182             cgi 'template_page';
183             cgi 'page_id';
184             cgi 'page_id_prefix';
185             cgi 'button' => '-utf8';
186             cgi 'save_to_page';
187              
188             package Kwiki::PageTemplate::FieldPhrase;
189             use base 'Spoon::Formatter::WaflPhrase';
190              
191             # Without default: {field: foo}
192             # Default value: {field: foo, value:bar}
193             # the value of "value:" should be URI-escaped.
194             # Because wafl-phrase can only in a single line.
195             sub to_html {
196             my $fields = $self->hub->page_template->fields;
197             my ($name,$defvalue) = split/\s+,\s*value:\s*/,$self->arguments;
198             my $type = $fields->{$name};
199             $defvalue = $self->uri_unescape($defvalue||'');
200             $name = "field_$name";
201             if($type eq 'textarea') {
202             return qq{};
203             } elsif (ref($type) eq 'ARRAY') {
204             my $ret = qq{
205             my $selected = '';
206             for(@$type) {
207             $selected = 'selected' if($defvalue eq $_);
208             $ret .= qq{};
209             }
210             $ret .= "";
211             return $ret;
212             }
213             qq{};
214             }
215              
216             package Kwiki::PageTemplate;
217              
218             1;
219              
220             =head1 NAME
221              
222             Kwiki::PageTemplate - pre-fill kwiki page with this template
223              
224             =head1 SYNOPSIS
225              
226             Paste this into your SandBox and visit the SandBox.
227              
228             .page_template_fields
229             page_id_prefix: Resume
230             name: text
231             gender:
232             - Woman
233             - Woman-in-man
234             bio: textarea
235             .page_template_fields
236              
237             .page_template
238             = Resume form
239              
240             My name: {field:name}
241              
242             Email: {field:name}
243              
244             Biograph:
245             {field:bio}
246             .page_template
247              
248             Fill the above form and you will probabally get the job.
249              
250             =head1 DESCRIPTION
251              
252             This purpose of this plugin is to let your Kwiki User edit
253             pages even more easily. They only have to type some characters
254             into a given form, submit it, and done. Not even Kwiki formatter
255             syntax knowledged required.
256              
257             The basic idea is from mac.com hompage editing, they provide a nearly
258             WYSIWYG web interface to edit your homepage, because the have many
259             pr-defined HTML templates, which are a big form, after you submit that
260             form, what you just inputed replace the original input fields, becomes
261             the content of the generated page.
262              
263             The "page_template_fields" wafl block is a YAML block where you can
264             define your form variables, and their input types, if the type is a
265             array, it'll become a pull-down select menu. After user submit the
266             form, this plugin will generate a page prefixed with the value
267             "page_template_page_id_prefix", default to "PageTemplateGenerated" in
268             your config/page_template.yaml, but you may specify "page_id_prefix"
269             in the page_template_fields wafl block to override this. The example
270             given in SYNOPSIS demostrate this feature, let the form generate a
271             page named like "Resume3", the number afterwards are increased
272             automatically each time somebody submit the form.
273              
274             By default, the generated page will preserve same look as in the
275             "page_template" block. But if you want to display the generated page
276             in another look, you may write the template code in
277             "page_template_display" wafl block.
278              
279             This plugin is still in it's early development and currently,
280             re-editing the generated page is not implemented, and something may
281             break in the future. So use it at your on risk.
282              
283             =head1 COPYRIGHT
284              
285             Copyright 2004 by Kang-min Liu .
286              
287             This program is free software; you can redistribute it and/or modify
288             it under the same terms as Perl itself.
289              
290             See
291              
292             =cut
293              
294             __DATA__