1 # Blosxom Plugin: uf_hcard_meta
2 # Author(s): Gavin Carr <gavin@openfusion.com.au>
4 # Documentation: 'perldoc uf_hcard_meta'
10 # Uncomment next line to enable debug output (don't uncomment debug() lines)
11 #use Blosxom::Debug debug_level => 2;
13 # --- Configuration defaults -----
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 # --------------------------------
41 # Official hcard attributes
42 my @req_attr = qw(fn);
44 'adr' => [ qw(address-type post-office-box extended-address street-address
45 locality region postal-code country-name) ],
49 'geo' => [ qw(latitude longitude) ],
54 'n' => [ qw(honorific-prefix given-name additional-name family-name honorific-suffix) ],
57 'org' => [ qw(organization-name organization-unit) ],
72 'email-value' => [ 'email' ],
73 'tel' => [ qw(telephone phone) ],
74 'organization-name' => [ qw(org organisation organization) ],
75 'post-office-box' => [ 'pobox' ],
76 'street-address' => [ 'street' ],
77 'locality' => [ 'suburb', 'city' ],
78 'region' => [ 'state' ],
79 'postal-code' => [ 'postcode' ],
80 'country-name' => [ 'country' ],
82 my %attr_types = map { $_ => 1 } qw(tel);
83 my %attr_types_standalone = (
84 tel => { map { $_ => 1 } qw(fax cell mobile) },
90 $config{style} = 'div-span' unless $config{style} eq 'ul' or $config{style} eq 'dl';
94 # Return the first existing metadata item key and value given a list of keys
97 my $meta_attr = $attr;
98 $meta_attr =~ s/-/_/g;
99 my $value = $blosxom::meta{$meta_attr};
100 $value = eval "\$meta::$attr" unless defined $value;
101 return wantarray ? ( $attr, $value ) : $value if defined $value;
103 return wantarray ? () : undef;
107 my ($hcard, $attr, $value, $style, $parent_attr, $parent_started, $type) = @_;
109 # Start parent if set and not started
110 if ($parent_attr && (! defined $parent_started || ! $$parent_started)) {
111 $$hcard .= qq(<span class="$parent_attr">\n);
112 $$parent_started = 1 if defined $parent_started;
115 # Append hcard output
118 $label = join ', ', map { qq(<span class="type">$_</span>) } split /[_\W]+/, $type;
120 elsif ($attr =~ m/^(\w+)-(value)$/) {
124 elsif ($style eq 'dl') {
129 if ($style eq 'dl') {
130 $$hcard .= qq(<dt>$label</dt>);
134 $type_string = "($label) ";
136 my $etag = $style eq 'div-span' ? 'span' :
137 $style eq 'ul' ? 'li' : 'dd';
138 $$hcard .= qq(<$etag class="$attr">$type_string$value</$etag>\n);
140 # Close parent unless we have a $parent_started flag to set
141 $$hcard .= qq(</span>\n) if $parent_attr && ! defined $parent_started;
145 my ($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
147 # Skip unless all required attributes are set
149 my $value = _get_meta($_, $alias{$_} ? @{$alias{$_}} : ());
151 # debug(2, "No name attribute found in $path/$filename - skipping post");
156 my $story_style = _get_meta( 'hcard_style' ) || $config{style};
157 my $ctag = $story_style eq 'div-span' ? 'div' : $story_style;
160 my $container_classes = 'vcard';
161 if (my $meta_class = _get_meta('hcard_class')) {
162 $container_classes .= " $meta_class";
165 $container_classes .= " $config{class}" if $config{class};
167 $hcard .= qq(<$ctag class="$container_classes">\n);
168 for my $attr ( @req_attr ) {
169 my $value = _get_meta( $attr, $alias{$attr} ? @{$alias{$attr}} : () );
170 _add_attr(\$hcard, $attr, $value, $story_style) if $value;
172 for my $attr ( sort keys %opt_attr ) {
173 # Allow nested attributes
174 if (ref $opt_attr{$attr}) {
175 my $parent_attr = $attr;
176 my $parent_started = 0;
177 for $attr ( @{ $opt_attr{$parent_attr} } ) {
178 my $value = _get_meta( $attr, $alias{$attr} ? @{$alias{$attr}} : () );
179 _add_attr(\$hcard, $attr, $value, $story_style, $parent_attr, \$parent_started)
182 if ($parent_started) {
183 $hcard .= qq(</span>\n);
188 # Allow bare attributes and aliases
189 my $value = _get_meta( $attr, $alias{$attr} ? @{$alias{$attr}} : () );
190 _add_attr(\$hcard, $attr, $value, $story_style) if $value;
192 # Allow typed attributes
193 if ($attr_types{ $attr }) {
194 # TODO: need to support $meta package variables here too
195 for my $meta (sort keys %blosxom::meta) {
196 # Search for all metadata beginning with $attr or aliases
197 for my $a ( $attr, $alias{$attr} ? @{$alias{$attr}} : () ) {
198 if (lc $meta =~ m/^$a[^a-z]+(\w+)$/) {
199 _add_attr(\$hcard, 'value', $blosxom::meta{ $meta }, $story_style, $attr, undef, $1);
204 # Allow standalone types
205 for my $type ( sort keys %{ $attr_types_standalone{ $attr } } ) {
206 if (my $value = _get_meta( $type )) {
207 _add_attr(\$hcard, 'value', $value, $story_style, $attr, undef,
208 $alias_types{ $type } || $type);
214 $hcard .= qq(</$ctag>\n);
215 # debug(2, "hcard $hcard\n");
217 my $autoappend = _get_meta( 'hcard_autoappend' );
218 $autoappend = $config{auto_append_to_body} unless defined $autoappend;
219 return 1 unless $autoappend;
221 $$body_ref .= "\n\n$hcard\n\n";
232 uf_hcard_meta - plugin to create an 'hcard' microformat tag from post
237 uf_hcard_meta is a plugin to create an 'hcard' microformat tag from
238 metadata in your post. The microformat tag is created in the
239 $uf_hcard_meta::hcard story variable for use in templates or by other
240 plugins, or if the 'auto_append_to_body' config variable is set (it is
241 by default), uf_hcard_meta will append the tag to your story body
244 The following metadata items are supported. By and large the official
245 hcard attribute name is supported, and sometimes one or aliases
246 (labelled alt below) may also be supported. See the hcard definition at
247 http://www.microformats.org/wiki/hcard for definitions and discussion
248 of attributes and usage.
250 =head2 REQUIRED METADATA ITEMS
254 =item fn (alt: name) - full name
258 =head2 OPTIONAL METADATA ITEMS
264 =item post-office-box (alt: pobox)
266 =item extended-address
268 =item street-address (alt: street)
270 =item locality (alt: suburb, city)
272 =item region (alt: state)
274 =item postal-code (alt: postcode)
276 =item country-name (alt: country)
282 =item cell (alt: mobile)
300 =item honorific-prefix
304 =item additional-name
308 =item honorific-suffix
314 =item organization-name (alt: org, organization, organisation)
316 =item organization-unit
328 =item tel (alt: telephone, phone)
330 And see also the Telephone Element Handling section below.
340 =head2 Telephone Element Handling
342 hcard telephone numbers may have type attributes, and because most people have
343 multiple telephone numbers, uf_hcard_meta also supports decorating the 'tel'
344 element (or its aliases) with one or more hcard telephone types, just suffixed
345 on the end of the element and separated by hyphens or underscores. For instance,
346 all of the following are valid telephone number entries for uf_hcard_meta:
352 Mobile: 0401 8669 0005
353 Tel-Work: 123 456 7890
354 Phone-Work-Direct-Pref-Msg: +1 232 868 7123
355 Telephone-Home: 02 8669 0006
357 =head2 Config Elements
359 uf_hcard_meta also supports a couple of config elements that can be used to
360 override plugin config data on a per-story basis:
364 =item HCard-Class (metamail) / hcard_class (meta)
366 This class (or list of classes) is appended to the class list applied to the
367 top-level hcard element in the rendered hcard i.e. it overrides the
368 'class' config variable.
370 =item HCard-Autoappend (metamail) / hcard_autoappend (meta)
372 This is a flag (0 or 1) indicating whether the rendered hcard should be
373 automatically appended to the story body. It overrides the 'auto_append_to_body'
376 =item HCard-Style (metamail) / hcard_style (meta)
378 One of the following styles: 'div-span', 'ul', 'dl', used to render the
379 hcard. It overrides the 'style' config variable.
385 An simple example hcard for me:
390 Email: gavin@openfusion.com.au
391 URL: http://www.openfusion.net/
400 uf_hcard_meta should be loaded after the meta plugins (meta
401 itself, or the metaclear/metamail/metadir/metafile family).
405 Microformats.org: http://www.microformats.org/, http://microformats.org/wiki/hcard.
407 Blosxom: http://blosxom.sourceforge.net/
411 Probably, since hcards can be pretty horrendously complicated - please
412 report to the author. Also, this plugin is pretty alpha - I'm not sure
413 of quite a few of the interface elements, and would welcome input on how
414 attributes etc. should be represented.
416 I also make no guarantees about backwards compatibility - future releases
417 may break existing hcards, so use at your own risk.
421 Gavin Carr <gavin@openfusion.com.au>, http://www.openfusion.net/
425 Copyright 2007, Gavin Carr.
427 This plugin is licensed under the same terms as blosxom itself i.e.
429 Permission is hereby granted, free of charge, to any person obtaining a
430 copy of this software and associated documentation files (the "Software"),
431 to deal in the Software without restriction, including without limitation
432 the rights to use, copy, modify, merge, publish, distribute, sublicense,
433 and/or sell copies of the Software, and to permit persons to whom the
434 Software is furnished to do so, subject to the following conditions:
436 The above copyright notice and this permission notice shall be included
437 in all copies or substantial portions of the Software.
439 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
440 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
441 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
442 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
443 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
444 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
445 OTHER DEALINGS IN THE SOFTWARE.