/[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.2 - (show annotations) (download)
Sun Feb 6 12:24:08 2005 UTC (19 years, 8 months ago) by wakaba
Branch: MAIN
CVS Tags: suikawiki3-redirect, HEAD
Branch point for: helowiki-2005, helowiki
Changes since 1.1: +57 -17 lines
Bidirectional linking support added

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24