1 # Blosxom Plugin: uf_hcalendar_meta
2 # Author(s): Gavin Carr <gavin@openfusion.com.au>
4 # Documentation: 'perldoc uf_hcalendar_meta'
6 package uf_hcalendar_meta;
10 # Uncomment next line to enable debug output (don't uncomment debug() lines)
11 #use Blosxom::Debug debug_level => 1;
13 # --- Configurable variables -----
17 # Extra CSS classes to add to the microformat container e.g. to turn display off
19 #class => 'nodisplay',
21 # Whether to automatically add microformat to story bodies. If not set,
22 # you must explicitly add $uf_adr_meta::adr to a template somewhere.
23 auto_append_to_body => 1,
25 # What markup style to use for your adr, if auto-appending.
26 # 3 styles are currently defined:
27 # 'div-span' uses a 'div' elt for the container, and 'span' elements for the fields
28 # 'ul' uses a 'ul' list for the container, and 'li' elements for the fields
29 # 'dl' uses a 'dl' list for the container, 'dt' elements for field names, and
30 # 'dd' elements for the fields themselves
37 # --------------------------------
40 use vars qw($hcalendar);
42 my @required = qw(summary dtstart);
43 my @optional = qw(dtend duration description location url uid);
51 $config{style} = 'div-span' unless $config{style} eq 'ul' or $config{style} eq 'dl';
55 # Return the first existing metadata item key and value given a list of keys
58 my $meta_attr = $attr;
59 $meta_attr =~ s/-/_/g;
60 my $value = $blosxom::meta{$meta_attr};
61 $value = eval "\$meta::$attr" unless defined $value;
62 return wantarray ? ( $attr, $value ) : $value if defined $value;
64 return wantarray ? () : undef;
70 $iso_date =~ s/^(\d{4}-\d{2}-\d{2})(\s+)/$1T/;
74 sub _format_duration {
76 my $iso_duration = uc $duration;
79 $iso_duration =~ s/^\s+//;
80 $iso_duration =~ s/\s+$//;
82 # If $iso_duration begins with an H, M, or S element, and no P, insert PT
83 $iso_duration =~ s/^(\d+)([HMS])/PT$1$2/;
85 # Otherwise, if $iso_duration begins without a P, insert one
86 $iso_duration =~ s/^(\d)/P$1/;
88 # Replace date-time whitespace with 'T'
89 $iso_duration =~ s/([PYMD])\s+/$1T/;
95 my ($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
98 for (@required, @optional) {
99 $meta{$_} = _get_meta($_);
101 my @req_count = map { $meta{$_} ? 1 : () } @required;
102 return 1 unless @req_count == @required;
104 my $story_style = _get_meta( 'hcal_style' ) || $config{style};
105 my $ctag = $story_style eq 'div-span' ? 'div' : $story_style;
106 my $etag = $story_style eq 'div-span' ? 'span' :
107 $story_style eq 'ul' ? 'li' : 'dd';
110 my $container_classes = 'vevent';
111 if (my $meta_class = _get_meta('hcal_class')) {
112 $container_classes .= " $meta_class";
115 $container_classes .= " $config{class}" if $config{class};
117 $hcalendar .= qq(<$ctag class="$container_classes">\n);
118 for (@required, @optional) {
119 next unless defined $meta{$_};
120 $hcalendar .= sprintf qq(<dt>%s</dt>), $label{$_} || ucfirst $_
121 if $story_style eq 'dl';
122 if ($_ eq 'dtstart' || $_ eq 'dtend') {
123 my $iso_date = _format_date($meta{$_});
124 $hcalendar .= qq(<$etag><abbr class="$_" title="$iso_date">$meta{$_}</abbr></$etag>\n);
126 elsif ($_ eq 'duration') {
127 my $iso_duration = _format_duration($meta{$_});
128 $hcalendar .= qq(<$etag><abbr class="$_" title="$iso_duration">$meta{$_}</abbr></$etag>\n);
130 elsif ($_ eq 'url') {
131 $hcalendar .= qq(<$etag><a class="$_" href="$meta{url}">$meta{url}</a></$etag>\n);
134 $hcalendar .= qq(<$etag class="$_">$meta{$_}</$etag>\n);
137 $hcalendar .= qq(</$ctag>\n);
138 # debug(1, "uf_hcalendar_meta: $hcalendar\n");
140 my $autoappend = _get_meta( 'hcal_autoappend' );
141 $autoappend = $config{auto_append_to_body} unless defined $autoappend;
142 return 1 unless $autoappend;
144 $$body_ref .= "\n\n$hcalendar\n\n";
155 uf_hcalendar_meta - plugin to create an 'hcalendar' microformat tag from
160 uf_hcalendar_meta is a plugin to create an 'hcalendar' microformat tag
161 from metadata in your post. The microformat tag is created in the
162 $uf_hcalendar_meta::hcalendar variable for use in templates or by other
163 plugins, or if the $auto_append_to_body flag is set (it is by default),
164 uf_hcalendar_meta will append the tag to your story body automatically.
166 =head2 REQUIRED METADATA ITEMS
168 (If using the 'metamail/metadir/metafile' plugins, metadata items
169 are matched case insensitively.)
175 The summary or title of the event.
179 The start date/time of the event.
181 Must be given as an ISO 8601 calendar date, in the form
182 YYYY-MM-DDTHH:MM:SS or YYYYMMDDTHHMMSS, with an optional trailing
183 timezone of the form /[+-]HH(:?MM)?/. Any number of rightmost time
184 elements may be omitted. Hours must be given in 24-hour time.
186 For convenience, this plugin allows the 'T' marker to be replaced by
189 The following are all valid dtstart values, for example:
193 =item 2007-09-01T19:30:00+10:00
195 =item 20070901T193000-10
199 =item 2007-09-01 17:45
211 The end date/time of the event. Must be an ISO 8601 calendar date
212 as defined for dtstart above.
216 The duration of the event. This may be an ISO 8601 duration, of the
217 form PnnYnnMnnDTnnHnnMnnS e.g. "P3Y6M4DT12H30M0S". Elements may be
218 omitted if their duration is zero. The smallest value used may also
219 have a decimal fraction, as in "P0.5Y" to indicate half a year.
221 For convenience, this plugin interprets the units case-insensitively,
222 allows the 'P' and 'T' markers to be omitted, and also accepts
223 whitespace in the place of the 'T' time marker.
225 Note that because months and minutes use the same signifier, there is
226 ambiguity about the meaning of 'P1M' and '1M'. This plugin interprets
227 'M' values as follows:
233 Interpreted as minutes, since this is the most common use case, and
234 since ISO 8601 really requires a leading 'P' signifier.
238 Interpreted as months, following ISO 8601.
242 Interpreted as minutes, following ISO 8601.
249 =head2 OPTIONAL METADATA ITEMS
255 A description of the event, sometimes longer than the summary.
259 The end date/time of the event, as discussed above.
263 The duration of the event, as discussed above.
267 A string describing the location of the event.
271 A canonical URL for the event.
275 A unique identifier for this event. Apparently required by some
276 versions of Microsoft Outlook.
280 =head2 Config Elements
282 uf_hcalendar_meta also supports a couple of config elements that can be used to
283 override plugin config data on a per-story basis:
287 =item HCal-Class (metamail) / hcal_class (meta)
289 This class (or list of classes) is appended to the class list applied to the
290 top-level hcalendar element in the rendered hcalendar i.e. it overrides the
291 'class' config variable.
293 =item HCal-Autoappend (metamail) / hcal_autoappend (meta)
295 This is a flag (0 or 1) indicating whether the rendered hcalendar should be
296 automatically appended to the story body. It overrides the 'auto_append_to_body'
299 =item HCal-Style (metamail) / hcal_style (meta)
301 One of the following styles: 'div-span', 'ul', 'dl', used to render the hcalendar.
302 It overrides the 'style' config variable.
308 uf_hcalendar_meta should be loaded after the meta plugins (meta
309 itself, or the metaclear/metamail/metadir/metafile family).
313 Microformats.org: http://www.microformats.org/,
314 http://microformats.org/wiki/hcalendar.
316 Blosxom: http://blosxom.sourceforge.net/
320 Only the most common hcalendar attributes have been implemented
321 so far. Please let me know if you'd like something not available
326 Gavin Carr <gavin@openfusion.com.au>, http://www.openfusion.net/
330 Copyright 2007, Gavin Carr.
332 This plugin is licensed under the same terms as blosxom itself i.e.
334 Permission is hereby granted, free of charge, to any person obtaining a
335 copy of this software and associated documentation files (the "Software"),
336 to deal in the Software without restriction, including without limitation
337 the rights to use, copy, modify, merge, publish, distribute, sublicense,
338 and/or sell copies of the Software, and to permit persons to whom the
339 Software is furnished to do so, subject to the following conditions:
341 The above copyright notice and this permission notice shall be included
342 in all copies or substantial portions of the Software.
344 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
345 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
346 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
347 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
348 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
349 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
350 OTHER DEALINGS IN THE SOFTWARE.