/[pub]/suikawiki/script/misc/plugins/view/propedit.wp2
Suika

Contents of /suikawiki/script/misc/plugins/view/propedit.wp2

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sun Jul 25 06:54:29 2004 UTC (20 years, 3 months ago) by wakaba
Branch: MAIN
Property Editor implemented

1 wakaba 1.1 #?SuikaWikiConfig/2.0
2    
3     Plugin:
4     @Name: PropEdit
5     @Description:
6     @@@: WikiPage Property Editor
7     @@lang:en
8     @License: %%Perl%%
9     @Author:
10     @@Name:
11     @@@@: Wakaba
12     @@@lang:ja
13     @@@script:Latn
14     @@Mail[list]: w@suika.fam.cx
15     @Date.RCS:
16     $Date: 2004/02/08 08:44:13 $
17     @RequiredPlugin[list]:
18     WikiEdit
19     WikiFormCore
20     @Namespace:
21     @@media-type:
22     http://suika.fam.cx/~wakaba/-temp/2004/04/24/mt#
23     @@pe:
24     http://suika.fam.cx/~wakaba/archive/2004/7/20/sw-propedit#
25    
26     PluginConst:
27     @NS_XHTML1:
28     http://www.w3.org/1999/xhtml
29    
30     ViewDefinition:
31     @Mode: pe--propedit
32     @Condition:
33     @@http-method[list]:
34     GET
35     HEAD
36     @Description:
37     @@@: Editing WikiPage Properties
38     @@lang: en
39     @template:
40     @@http-status-code: 200
41     @@media-type: text/html
42     @@use-media-type-charset: 1
43     @@expires: %%edit%%
44     @@body:
45     %html-document (
46     title => {%res(name=>{PropEdit:WebPageTitle});}p,
47     link-meta => {%template (name => links);
48     %html-meta(name => ROBOTS, content => NOINDEX);}p,
49     content => {
50     %template (
51     name => ws--page,
52     -content => {
53     %section (
54     title => {%res (name => {PropEdit:Title});}p, heading,
55     content => {
56     %pe--propedit (template => {
57     %resource-as-plain-text (name => {PropEdit:Template});
58     }p);
59     }p,
60     );
61     },
62     );
63     }p,
64     );
65    
66     ViewDefinition:
67     @Mode: -pe--conflict
68     @Condition:
69     @@http-method[list]:
70     GET
71     @Description:
72     @@@: Editing WikiPage Properties -- Report Confliction
73     @@lang: en
74     @template:
75     @@http-status-code: 409
76     @@media-type: text/html
77     @@use-media-type-charset: 1
78     @@expires: %%error%%
79     @@body:
80     %html-document (
81     title => {%res(name=>{PropEdit:Conflict:WebPageTitle});}p,
82     link-meta => {%template (name => links);
83     %html-meta(name => ROBOTS, content => NOINDEX);}p,
84     content => {
85     %template (
86     name => ws--page,
87     -content => {
88     %section (
89     title => {%res (name => {PropEdit:Conflict:Title});}p, heading,
90     content => {
91     %paragraph (content => {
92     %res (name => {PropEdit:Conflict:Description});
93     }p);
94     %pe--propedit (template => {
95     %resource-as-plain-text (name => {PropEdit:Template});
96     }p,
97     );
98     }p);},
99     );
100     }p,
101     );
102    
103     FormattingRule:
104     @Category[list]: view
105     @Name: pe--propedit
106     @Description:
107     @@@: A property editor form
108     @@lang: en
109     @Parameter:
110     @@Name: page
111     @@Type: WikiName
112     @@Default: (auto)
113     @@Description:
114     @@@@: WikiPage to be edited
115     @@@lang:en
116     @Parameter:
117     @@Name: template
118     @@Type: template
119     @@Default: (required)
120     @@Description:
121     @@@@: Template of the content
122     @@@lang: en
123     @Formatting:
124     __ATTRTEXT:%page__;__ATTRTEXT:%template__;
125     my $page = $o->{wiki}->name ($p->{page} || $o->{wiki}->{var}->{page});
126     my $template = $p->{template};
127     my $content = __FUNCPACK{WikiEdit}__->get_content ($o, $page);
128     local $o->{var}->{content} = $content->{content};
129     local $o->{var}->{content_prop} = $content->{content_prop};
130     local $o->{var}->{source}->{prop} = sub {
131     my %opt = @_;
132     my $key = $opt{p}->{id};
133     my $uri = $opt{o}->{wiki}->{config}->{<Q:pe:prop>}->{$key}->{uri};
134     my $rv = {};
135     if ($uri) {
136     if (my $nv = $opt{o}->{wiki}->{input}->parameter ('PE--CTRL--'.$key)) {
137     $rv->{value} = $nv;
138     $rv->{class} = [qw/pe--from-parameter/];
139     } else {
140     $rv->{value} = $opt{o}->{var}->{content_prop}
141     ->get_attribute_value ($uri,
142     default => $opt{p}->{default});
143     }
144     } else {
145     $rv->{value} = $opt{p}->{default};
146     }
147     $rv;
148     };
149     __FUNCPACK{WikiFormCore}__->make_form_in_html
150     ($p->{-parent}, $template,
151     wiki => $o->{wiki},
152     o => $o,
153     index => -1,
154     local_id_prefix => 'PE--CTRL--',
155     output => {
156     mode => 'pe--write',
157     page => $page,
158     submit_button => 1,
159     hidden => sub {
160     my ($hidden, $o) = @_;
161     ## Embed hidden sequencial number to detect confliction
162     for ($hidden->append_new_node (type => '#element',
163     namespace_uri => $NS_XHTML1,
164     local_name => 'input')) {
165     $_->set_attribute (type => 'hidden');
166     $_->set_attribute (name => 'pe--seq');
167     $_->set_attribute (value => $o->{var}->{content_prop}
168     ->get_attribute_value (<Q:pe:seq>,
169     default => 0));
170     $_->option (use_EmptyElemTag => 1);
171     }
172     },
173     });
174    
175     ViewFragment:
176     @Name: links
177     @Description:
178     @@@: Link to property edit mode of the WikiPage
179     @@lang:en
180     @Formatting:
181     %link-wiki(mode => pe--propedit, up-to-date,
182     rel => edit, class => wiki-cmd,
183     description => {%res(name=>{PropEdit:Link:Description});}p);
184    
185     ViewDefinition:
186     @Mode: pe--write
187     @Condition:
188     @@http-method[list]:
189     POST
190     @Description:
191     @@@: Saving modified (new) WikiPage properties
192     @@lang: en
193     @Use:
194     use Message::Util::Error;
195     @method:
196     @@Name: main
197     @@@:
198     my $wiki = $self->{view}->{wiki};
199     $wiki->{var}->{db}->{read_only}->{'content'} = 1;
200     $wiki->{var}->{db}->{read_only}->{'content_prop'} = 0;
201     $wiki->{var}->{db}->{read_only}->{'lastmodified'} = 1;
202     $wiki->{var}->{db}->{read_only}->{'referer'} = 0;
203     $wiki->init_db;
204    
205     my $page = $wiki->{var}->{page};
206     my $old_content = $wiki->{db}->get (content => $page);
207     my $prop = $wiki->{db}->get (content_prop => $page);
208    
209     ## Check confliction
210     my $seq = $wiki->{input}->parameter ('pe--seq') || 0;
211     if ($seq != $prop->get_attribute_value (<Q:pe:seq>, default => 0)) {
212     $self->{view}->{wiki}->view_in_mode (mode => '-pe--conflict');
213     throw SuikaWiki::DB::Util::Error -type => 'ERROR_REPORTED';
214     }
215    
216     MODIFICATION: {
217    
218     my $modified = 0;
219     my $old_mt;
220     my $new_mt;
221     my %depend;
222     KEY: for my $key (grep s/^PE--CTRL--//, $wiki->{input}->parameter_names) {
223     my $propinfo = $wiki->{config}->{<Q:pe:prop>}->{$key};
224     next KEY unless $propinfo->{uri};
225    
226     ## Really modified?
227     my $new_value = [$wiki->{input}->parameter ('PE--CTRL--'.$key)];
228     if (@$new_value == 1) {
229     if ($propinfo->{is_list}) {
230     $new_value = [split /\x0A|\x0D\x0A?/, $new_value->[0]];
231     }
232     if ($propinfo->{type} eq <Q:media-type:media-type>) {
233     next KEY if $new_value->[0] eq '#asis';
234     }
235     }
236    
237     my $old_value = $prop->get_attribute_value ($propinfo->{uri});
238     if (ref $old_value and @$new_value == @$old_value) {
239     CHK: {
240     for my $i (0..$#$new_value) {
241     last CHK if $old_value->[$i] ne $new_value->[$i];
242     }
243     next KEY;
244     }
245     } elsif (not ref $old_value and @$new_value == 1) {
246     next KEY if $old_value eq $new_value->[0];
247     }
248     if ($propinfo->{uri} eq <Q:media-type:media-type>) {
249     $old_mt = $old_value;
250     $new_mt = $new_value->[0];
251     }
252     if (@$new_value) {
253     if ($propinfo->{is_list}) {
254     $prop->set_attribute ($propinfo->{uri} => $new_value);
255     } elsif (length $new_value->[0]) {
256     $prop->set_attribute ($propinfo->{uri} => $new_value->[0]);
257     } else {
258     $prop->remove_attribute ($propinfo->{uri});
259     }
260     } else {
261     $prop->remove_attribute ($propinfo->{uri});
262     }
263     $modified = 1;
264     $depend{$key} = $propinfo->{depend} if $propinfo->{depend};
265     }
266     DEPEND: for my $sub (keys %depend) {
267     for my $main (@{$depend{$sub}}) {
268     unless ($prop->get_attribute ($wiki->{config}->{<Q:pe:prop>}
269     ->{$main}->{uri})) {
270     $prop->remove_attribute ($wiki->{config}->{<Q:pe:prop>}
271     ->{$sub}->{uri});
272     next DEPEND;
273     }
274     }
275     }
276     last MODIFICATION unless $modified;
277    
278     $prop->set_attribute (<Q:pe:seq> => $seq + 1);
279    
280     ## Update content
281     try {
282     $self->{view}->{wiki}->{db}->set (content_prop => $page => $prop);
283     } catch SuikaWiki::DB::Util::Error with {
284     my $err = shift;
285     if ($err->{-type} eq 'ERROR_REPORTED') {
286     $err->throw;
287     } else {
288     $self->{view}->{wiki}->view_in_mode (mode => '-wdb--fatal-error');
289     throw SuikaWiki::DB::Util::Error -type => 'ERROR_REPORTED';
290     }
291     };
292    
293     ## Post-write events
294     if ($new_mt) {
295     my $format = __FUNCPACK{WikiFormat}__
296     ->handler (\$old_content,
297     serialized_media_type => $old_mt,
298     content_prop => $prop,
299     wiki => $wiki);
300     $format->content_type_changed_from (wiki => $wiki,
301     page => $page,
302     old_content => \$old_content,
303     new_content => \$old_content,
304     new_serialized_media_type => $new_mt,
305     content_prop => $prop);
306     }
307     my $format = __FUNCPACK{WikiFormat}__
308     ->handler (\$old_content,
309     serialized_media_type => $new_mt,
310     content_prop => $prop,
311     wiki => $wiki);
312     $format->content_prop_modified (wiki => $wiki,
313     page => $page,
314     content_prop => $prop);
315    
316     } # MODIFICATION
317    
318     ## Redirect appropriate mode
319     my $new_mode = $self->{view}->{wiki}->{input}->parameter
320     ('we--mode-modified');
321     $new_mode =~ s/[^0-9A-Za-z._-]+//g;
322     my $uri = $self->{view}->{wiki}->uri_reference
323     (page => $page,
324     mode => $new_mode,
325     up_to_date => 1,
326     param => {we__mode_modified => $new_mode});
327    
328     require SuikaWiki::Output::HTTP;
329     my $output = SuikaWiki::Output::HTTP->new
330     (wiki => $self->{view}->{wiki});
331     $output->set_redirect (uri => $uri, status_code => 303);
332     $output->output (output => 'http-cgi');
333    
334     FormattingRule:
335     @Category[list]:
336     form-input
337     @Name: pe--texts
338     @Description:
339     @@@@: Multiple texts input
340     @@@lang:en
341     @Formatting:
342     __ATTRTEXT:%id__;__ATTRNODE:%label__;
343     my $id = __FUNCPACK{WikiFormCore}__
344     ->control_id ($o,
345     local_id => $p->{id},
346     require_local_id => 1);
347     my $has_label = 0;
348     if ($p->{label}->count) {
349     $has_label = 1;
350     for ($p->{-parent}->append_new_node
351     (type => '#element',
352     namespace_uri => $NS_XHTML1,
353     local_name => 'label')) {
354     $_->set_attribute (for => $id->{global_id});
355     $_->append_node ($p->{label});
356     }
357     $p->{-parent}->append_new_node
358     (type => '#element',
359     namespace_uri => $NS_XHTML1,
360     local_name => 'br')
361     ->option (use_EmptyElemTag => 1);
362     }
363    
364     for ($p->{-parent}->append_new_node (type => '#element',
365     namespace_uri => $NS_XHTML1,
366     local_name => 'textarea')) {
367     $_->set_attribute (name => $id->{local_id});
368     $_->set_attribute (id => $id->{global_id}) if $has_label;
369     __ATTRTEXT:%size__;__ATTRTEXT:%lines__;__ATTRTEXT:%description__;
370     $_->set_attribute (cols => ($p->{size}||20)*2); ## Length
371     $_->set_attribute (title => $p->{description}) if $p->{description};
372     $_->set_attribute (disabled => 'disabled') if $o->{form}->{disabled};
373     __ATTRTEXT:%class__;
374     my @class = split /\s+/, $p->{class};
375     push @class, 'require' if $o->{form}->{require}->{id}->{$p->{id}};
376     __ATTRTEXT:%source__;
377     my $items = 5;
378     if ($p->{source}) {
379     if (ref $o->{var}->{source}->{$p->{source}}) {
380     my $d = $o->{var}->{source}->{$p->{source}}
381     ->(p=>$p, o=>$o, type => <Q:pe:texts>);
382     $_->append_text (ref $d->{value} eq 'ARRAY' ?
383     join "\n", @{$d->{value}} : $d->{value});
384     push @class, @{$d->{class}||[]};
385     $items = @{$d->{value}} + 1 if ref $d->{value} eq 'ARRAY';
386     } else {
387     $_->append_text (ref $o->{var}->{$p->{source}} eq 'ARRAY' ?
388     join "\n", @{$o->{var}->{$p->{source}}} :
389     $o->{var}->{$p->{source}});
390     $items = @{$o->{var}->{$p->{source}}} + 1
391     if ref $o->{var}->{$p->{source}} eq 'ARRAY';
392     }
393     } else {
394     __ATTRTEXT:%default__;
395     $_->append_text ($p->{default}); ## Default value
396     }
397     $_->set_attribute (rows => ($p->{lines} || $items)); ## Lines
398     $_->set_attribute (class => join ' ', @class) if @class;
399     }
400    
401     Resource:
402     @Edit:SaveAnd:pe--propedit:Description:
403     @@lang: en
404     @@@:
405     Save modified property values and show this property-editing
406     mode again.
407     @Edit:SaveAnd:pe--propedit:Label:
408     @@lang: en
409     @@@:
410     Editing Properties
411     @PropEdit:Conflict:Description:
412     @@lang: en
413     @@@:
414     Properties for WikiPage %link-to-wikipage (label => {%link-to-it (
415     label => {%page-name;}p);});
416     has been modified during you are editing them.
417     Please ensure that third-party's modification does not
418     affect your submitting changes.
419     @PropEdit:Conflict:Title:
420     @@lang: en
421     @@@:
422     Confliction - Editing Content Properties
423     @PropEdit:Conflict:WebPageTitle:
424     @@lang: en
425     @@@:
426     CONFLICTION - %page-name; (Editing Content Properties)
427     @PropEdit:Link:Description:
428     @@lang: en
429     @@@: Edit properties of this WikiPage
430     @PropEdit:Template:
431    
432     ## Should be defined in resource WikiPage
433     @PropEdit:Title:
434     @@lang: en
435     @@@:
436     Editing Content Properties
437     @PropEdit:WebPageTitle:
438     @@lang: en
439     @@@:
440     %page-name; (Editing Content Properties)
441    
442    
443    

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24