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 #$config{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 $config{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
31 #$config{style} = 'div-span';
32 #$config{style} = 'ul';
33 $config{style} = 'dl';
35 # --------------------------------
40 # Official hcard attributes
41 my @req_attr = qw(fn);
43 'adr' => [ qw(address-type post-office-box extended-address street-address
44 locality region postal-code country-name) ],
48 'geo' => [ qw(latitude longitude) ],
53 'n' => [ qw(honorific-prefix given-name additional-name family-name honorific-suffix) ],
56 'org' => [ qw(organization-name organization-unit) ],
71 'email-value' => [ 'email' ],
72 'tel' => [ qw(telephone phone) ],
73 'organization-name' => [ qw(org organisation organization) ],
74 'post-office-box' => [ 'pobox' ],
75 'street-address' => [ 'street' ],
76 'locality' => [ 'suburb', 'city' ],
77 'region' => [ 'state' ],
78 'postal-code' => [ 'postcode' ],
79 'country-name' => [ 'country' ],
81 my %attr_types = map { $_ => 1 } qw(tel);
82 my %attr_types_standalone = (
83 tel => { map { $_ => 1 } qw(fax cell mobile) },
89 $config{style} = 'div-span' unless $config{style} eq 'ul' or $config{style} eq 'dl';
93 # Return the first existing metadata item key and value given a list of keys
96 my $meta_attr = $attr;
97 $meta_attr =~ s/-/_/g;
98 my $value = $blosxom::meta{$meta_attr};
99 $value = eval "\$meta::$attr" unless defined $value;
100 return wantarray ? ( $attr, $value ) : $value if defined $value;
102 return wantarray ? () : undef;
106 my ($hcard, $attr, $value, $style, $parent_attr, $parent_started, $type) = @_;
108 # Start parent if set and not started
109 if ($parent_attr && (! defined $parent_started || ! $$parent_started)) {
110 $$hcard .= qq(<span class="$parent_attr">\n);
111 $$parent_started = 1 if defined $parent_started;
114 # Append hcard output
117 $label = join ', ', map { qq(<span class="type">$_</span>) } split /[_\W]+/, $type;
119 elsif ($attr =~ m/^(\w+)-(value)$/) {
123 elsif ($style eq 'dl') {
128 if ($style eq 'dl') {
129 $$hcard .= qq(<dt>$label</dt>);
133 $type_string = "($label) ";
135 my $etag = $style eq 'div-span' ? 'span' :
136 $style eq 'ul' ? 'li' : 'dd';
137 $$hcard .= qq(<$etag class="$attr">$type_string$value</$etag>\n);
139 # Close parent unless we have a $parent_started flag to set
140 $$hcard .= qq(</span>\n) if $parent_attr && ! defined $parent_started;
144 my ($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
146 # Skip unless all required attributes are set
148 my $value = _get_meta($_, $alias{$_} ? @{$alias{$_}} : ());
150 # debug(2, "No name attribute found in $path/$filename - skipping post");
155 my $story_style = _get_meta( 'hcard_style' ) || $config{style};
156 my $ctag = $story_style eq 'div-span' ? 'div' : $story_style;
159 my $container_classes = 'vcard';
160 if (my $meta_class = _get_meta('hcard_class')) {
161 $container_classes .= " $meta_class";
164 $container_classes .= " $config{class}" if $config{class};
166 $hcard .= qq(<$ctag class="$container_classes">\n);
167 for my $attr ( @req_attr ) {
168 my $value = _get_meta( $attr, $alias{$attr} ? @{$alias{$attr}} : () );
169 _add_attr(\$hcard, $attr, $value, $story_style) if $value;
171 for my $attr ( sort keys %opt_attr ) {
172 # Allow nested attributes
173 if (ref $opt_attr{$attr}) {
174 my $parent_attr = $attr;
175 my $parent_started = 0;
176 for $attr ( @{ $opt_attr{$parent_attr} } ) {
177 my $value = _get_meta( $attr, $alias{$attr} ? @{$alias{$attr}} : () );
178 _add_attr(\$hcard, $attr, $value, $story_style, $parent_attr, \$parent_started)
181 if ($parent_started) {
182 $hcard .= qq(</span>\n);
187 # Allow bare attributes and aliases
188 my $value = _get_meta( $attr, $alias{$attr} ? @{$alias{$attr}} : () );
189 _add_attr(\$hcard, $attr, $value, $story_style) if $value;
191 # Allow typed attributes
192 if ($attr_types{ $attr }) {
193 # TODO: need to support $meta package variables here too
194 for my $meta (sort keys %blosxom::meta) {
195 # Search for all metadata beginning with $attr or aliases
196 for my $a ( $attr, $alias{$attr} ? @{$alias{$attr}} : () ) {
197 if (lc $meta =~ m/^$a[^a-z]+(\w+)$/) {
198 _add_attr(\$hcard, 'value', $blosxom::meta{ $meta }, $story_style, $attr, undef, $1);
203 # Allow standalone types
204 for my $type ( sort keys %{ $attr_types_standalone{ $attr } } ) {
205 if (my $value = _get_meta( $type )) {
206 _add_attr(\$hcard, 'value', $value, $story_style, $attr, undef,
207 $alias_types{ $type } || $type);
213 $hcard .= qq(</$ctag>\n);
214 # debug(2, "hcard $hcard\n");
216 my $autoappend = _get_meta( 'hcard_autoappend' );
217 $autoappend = $config{auto_append_to_body} unless defined $autoappend;
218 return 1 unless $autoappend;
220 $$body_ref .= "\n\n$hcard\n\n";
231 uf_hcard_meta - plugin to create an 'hcard' microformat tag from post
236 uf_hcard_meta is a plugin to create an 'hcard' microformat tag from
237 metadata in your post. The microformat tag is created in the
238 $uf_hcard_meta::hcard story variable for use in templates or by other
239 plugins, or if the 'auto_append_to_body' config variable is set (it is
240 by default), uf_hcard_meta will append the tag to your story body
243 The following metadata items are supported. By and large the official
244 hcard attribute name is supported, and sometimes one or aliases
245 (labelled alt below) may also be supported. See the hcard definition at
246 http://www.microformats.org/wiki/hcard for definitions and discussion
247 of attributes and usage.
249 =head2 REQUIRED METADATA ITEMS
253 =item fn (alt: name) - full name
257 =head2 OPTIONAL METADATA ITEMS
263 =item post-office-box (alt: pobox)
265 =item extended-address
267 =item street-address (alt: street)
269 =item locality (alt: suburb, city)
271 =item region (alt: state)
273 =item postal-code (alt: postcode)
275 =item country-name (alt: country)
281 =item cell (alt: mobile)
299 =item honorific-prefix
303 =item additional-name
307 =item honorific-suffix
313 =item organization-name (alt: org, organization, organisation)
315 =item organization-unit
327 =item tel (alt: telephone, phone)
329 And see also the Telephone Element Handling section below.
339 =head2 Telephone Element Handling
341 hcard telephone numbers may have type attributes, and because most people have
342 multiple telephone numbers, uf_hcard_meta also supports decorating the 'tel'
343 element (or its aliases) with one or more hcard telephone types, just suffixed
344 on the end of the element and separated by hyphens or underscores. For instance,
345 all of the following are valid telephone number entries for uf_hcard_meta:
351 Mobile: 0401 8669 0005
352 Tel-Work: 123 456 7890
353 Phone-Work-Direct-Pref-Msg: +1 232 868 7123
354 Telephone-Home: 02 8669 0006
356 =head2 Config Elements
358 uf_hcard_meta also supports a couple of config elements that can be used to
359 override plugin config data on a per-story basis:
363 =item HCard-Class (metamail) / hcard_class (meta)
365 This class (or list of classes) is appended to the class list applied to the
366 top-level hcard element in the rendered hcard i.e. it overrides the
367 'class' config variable.
369 =item HCard-Autoappend (metamail) / hcard_autoappend (meta)
371 This is a flag (0 or 1) indicating whether the rendered hcard should be
372 automatically appended to the story body. It overrides the 'auto_append_to_body'
375 =item HCard-Style (metamail) / hcard_style (meta)
377 One of the following styles: 'div-span', 'ul', 'dl', used to render the
378 hcard. It overrides the 'style' config variable.
384 An simple example hcard for me:
389 Email: gavin@openfusion.com.au
390 URL: http://www.openfusion.net/
399 uf_hcard_meta should be loaded after the meta plugins (meta
400 itself, or the metaclear/metamail/metadir/metafile family).
404 Microformats.org: http://www.microformats.org/, http://microformats.org/wiki/hcard.
406 Blosxom: http://blosxom.sourceforge.net/
410 Probably, since hcards can be pretty horrendously complicated - please
411 report to the author. Also, this plugin is pretty alpha - I'm not sure
412 of quite a few of the interface elements, and would welcome input on how
413 attributes etc. should be represented.
415 I also make no guarantees about backwards compatibility - future releases
416 may break existing hcards, so use at your own risk.
420 Gavin Carr <gavin@openfusion.com.au>, http://www.openfusion.net/
424 Copyright 2007, Gavin Carr.
426 This plugin is licensed under the same terms as blosxom itself i.e.
428 Permission is hereby granted, free of charge, to any person obtaining a
429 copy of this software and associated documentation files (the "Software"),
430 to deal in the Software without restriction, including without limitation
431 the rights to use, copy, modify, merge, publish, distribute, sublicense,
432 and/or sell copies of the Software, and to permit persons to whom the
433 Software is furnished to do so, subject to the following conditions:
435 The above copyright notice and this permission notice shall be included
436 in all copies or substantial portions of the Software.
438 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
439 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
440 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
441 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
442 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
443 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
444 OTHER DEALINGS IN THE SOFTWARE.