Magnolia 4.5 reached end of life on June 30, 2016. This branch is no longer supported, see End-of-life policy.

Page tree
Skip to end of metadata
Go to start of metadata

Microformats are an open source data format standard built upon existing frameworks such as HTML, CSS and XML. Microformats allow the encoding and extraction of events, contact information, social relationships and many more. They are used in HTML pages through the use of microformat tags. Traditional HTML markup tags display information, but not what the information means. Microformats introduce meaning to information by attaching semantics to it. Microformat standards are developed and maintained by microfromats.org.

Using microformat markup has many advantages:

  • It is widely adopted and the hCard microformat is in use on an estimated 2 billion Web pages.
  • Most browsers have built-in support for microformats or can be extended with plugins.
  • Most search engines, including Google, Yahoo and Bing, index microformats and in some cases highlight results. Google's new Recipe View is partially based on the hRecipe microformat.
  • Microformats allow data to be saved, reused and combined. Many parsing applications that convert and transfer microformat data exist. For example the Operator add-on for Firefox can export contact information to Yahoo Contacts or Microsoft Office Outlook, bookmark the information, or find the contact's location in Google or Yahoo Maps.

Example: Exporting a contact with the Firefox Operator add-on.

Microformat markup

HTML standards allow for the embedding and encoding of semantics within the attributes of markup tags. Microformats take advantage of these standards by indicating the presence of metadata. Microformats mostly use the class attribute, but rel and rev are also used.

In standard HTML typical contact details would be marked up like this:

<ul>
    <li>John Smith</li>
    <li>Jon-Jon</li>
    <li>The Company</li>
    <li>702-555-1234</li>
    <li><a href="http://company.com/">http://company.com/</a></li>   
</ul>

When microformat properties based on the hCard standard are added, it becomes:

<ul class="vcard">
    <li class="fn">John Smith</li>
    <li class="nickname">Jon-Jon</li>
    <li class="org">The Company</li>
    <li class="tel">702-555-1234</li>
    <li><a class="url" href="http://company.com/">http://company.com/</a></li>
</ul>

The code is wrapped in class="vcard". This indicates that the nested classes are from hCard. The properties fn (full name), org (organization), tel (telephone number) and url are identified with specific class names that conform to the standard. Software can now identify, extract and transfer the information.

STK built-in microformat support

The Standard Templating Kit (STK) has built-in support for two commonly used microformats: hCard and hCalendar. STK can be customized to adopt any microformat standard.

To test the examples, install the Firefox Operator add-on or a similar application.

hCard

hCard is a microformat for publishing contact details of people, companies, organizations, and places in HTML, Atom, RSS or arbitrary XML. The hCard microformat uses a 1:1 representation of vCard properties and values, identified using HTML classes and rel attributes.

The stkContact component is marked up with properties complying with the hCard standard. The component retrieves contact information stored in the Data module  and renders it on a Web page.

This component template definition is at Templating Kit > Template Definitions > /components/teasers/stkContact. The elements relevant to microformats are:

  • /parameters/divClass which assigns the div element a class attribute with value box card. This marks the component as a vcard for CSS styling.
  • templateScript which references the contact.ftl script that renders the component.

The contact.ftl script is available at Templating Kit > Templates > /templating-kit/components/teasers. The hCard standard has two required properties fn (full name) and n (name) and a number of optional properties. The template script snippet below shows the use of the required fn n and optional given-name, family-name, org, organization-name and organization-unit properties. If you view the entire script you will find many more such as adr, street-address, locality, postal-code, photo etc.

[#if hasOrganization]
   <div class="org">
      <h3>${i18n['contact.company']}</h4. 
      [#if contact.organizationName?has_content]
         <p class="organization-name">${contact.organizationName?html}</p>
      [/#if]
      [#if contact.organizationUnit?has_content]
         <p class="organization-unit">${contact.organizationUnit?html}</p>
      [/#if]
      [#if contact.title?has_content]
         <p class="title">${contact.title?html}</p>
      [/#if]
   </div>
[/#if]
[#if contact.givenName?has_content]
   <div>
      <h3>${i18n['contact.name']}</h4. 
         <p class="fn n"><span class="given-name">${contact.givenName?html}</span> 
         <span class="family-name">${contact.familyName?html}</span></p>
   </div>
[/#if]

CSS styling is controlled by the pop theme's main stylesheet, styles.css, available in Templating Kit > Resources templating-kit/themes/pop/css/styles.css. Search for "vcard". Here is a sample.

#main .vcard .organization-name {
  background: url(../img/bgs/microformat.png) 0 3px no-repeat;
  margin-bottom: 5px;
  padding: 1px 0 1px 35px;
  font-weight: bold;
  font-size: 160%;
}

When a contact from the Data module is added and the component is rendered on a page, the resulting HTML markup is similar to the snippet below. View the source of the demo-project/news-and-events page to HTML generated for the stkContact component in the extras area.

<div class="box vcard" id="box-1">
   <h2>Contact</h2>
      <div class="org">
         <h3>Firm</h3>
            <p class="organization-name">Magnolia International Ltd.</p>
      </div>
      <div>
         <h3>Name</h3>
            <p class="fn n"><span class="given-name">Jens</span> 
            <span class="family-name">Mustermann</span></p>
      </div>

The addition of the hCard properties allows browser add-ons, search engines and other parsing software to indentify the contact information. To test the capabilites:

  1. Install the Firefox Operator add-on.
  2. Open the demo-project/news-and-events page.
  3. In the Operator toolbar select Contacts > Jens Musterman > Find with Google Maps.

The contact's address is displayed in a map.

hCalendar

hCalendar is a distributed calendaring and events microformat that uses a 1:1 representation of standard iCalendar VEVENT properties and values in semantic HTML.

The Page Header of the stkEvent template is generated by a template script like all other header components in the STK. This component includes the hCalendar microformat properties that allow parsing software to extract the details of an event. In the screenshot below, note how the Firefox Operator add-on has identified the hCalendar properties and made the event information available for use in various ways.

The stkEvent template definition is at Templating Kit > Templates > /pages/stkEvent:

  • The infoBlock area is specifically enabled because it is disabled in the prototype template. This is the only STK template that uses this area.
  • The templateScript property references the infoblock.ftl script that renders the header component.

The infoblock.ftl script is in Templating Kit > Templates > /templating-kit/pages/content/event. The hCalendar standard has two required properties: dtstart (ISO date format) and summary, and a number of optional properties. The script snippet below shows the use of the required properties and the optional description property. View the entire script to see the ISO date formatting and use of the other optional properties.

<div class="vevent">
   <div class="date">
   <h2 class="summary">${content.eventTitle!'No "Event Title" is defined: 
      Fill out the "Event Header"'}</h3. 
   <p class="description">${content.abstract!'No "Event Description" is defined: 
      Fill out the "Event Header"'}</p>
   <dl>
      <dt>${i18n['event.date']}</dt>
      <dd>
         [#if hasDate]
            ${content.date?date?string.long}
            <span class="dtstart">${microFormatDate}</span>
         [#else]
            ${i18n['infoblock.no.event.date.error']}
         [/#if]
         [#if hasDateEnd] - ${content.dateEnd?date?string.long} 
            <span class="dtend">${microFormatDateEnd}</span>
         [/#if]
      </dd>
   </dl>

The event header component has distinct styling that is controlled by the pop theme's main style sheet, styles.css, available in Templating Kit > Resources templating-kit/themes/pop/css/styles.css.

When an event is added on a page the resulting HTML is similar to the snippet below. You can view the full source of the vevent div class on the New Year's Eve page.

<div class="vevent">
   <h2 class="summary">Basels most famous New Year's Eve</h3. 
   <p class="description">This is the abstract of an event-page. It is a brief
   r&eacute;sum&eacute; on the content of this page. The abstract on the beginning of a page 
   is also used in teasers and openers that reference this page. Li Europan lingues es 
   membres del sam familie. Lor separat existentie es un myth.</p>
   <dl>
      <dt>Date</dt>
      <dd>
      December 31, 2009 <span class="dtstart">2009-12-31T09:00:46</span>
      - January 1, 2010 <span class="dtend">2010-01-01T07:00:56</span>
      </dd>
   </dl>

Adding custom microformats

There are a number of other microformat standards and many are in development. Next we look at how to adapt the STK to support the hRecipe standard. hRecipe is a standard for adding semantic markup to cooking recipes. It is supported by Google Recipe View. When the ingredients and preparation time are marked with standard elements, the Recipe View uses the information to show rich content and allows you to search for recipes by ingredients, for example.

Google also supports microdata and RDFa standards.

hRecipe specfies two required properties fn (recipe name) and ingredient (one or more ingredients) and a number of optional properties. Our example also includes the optional properties: author, yield (number of servings), instructions, duration, photo and summary (introductory text). We have not used nutrition, value, type or tag but you can add them if you like.

Google also requires a name property (fn equivalent) and suggests additional properties. We have included prepTime (preparation time), cookTime (cooking time) and totalTime (duration equivalent) from their list.

In our example we modify the stkTextImage component. We selected this components because:

  • CSS styling is suitable and there is no need to add specific syles.
  • TextImageModel model class is suitable and extends the ImageModel.
  • Dialog fields are easy to copy and modify, and the Image tab is already there.

Create the component definition

The first step is to create a new component definition in Templating Kit > Template Definitions.

  1. Copy the components/content/stkTextImage node and remane it stkRecipe.
  2. Change the property values as follows:
    • desciption to a suitable description. The description is displayed below the component title in the selector dialog when an editor adds the component.
    • dialog to standard-templating-kit:components/content/stkRecipe. You will create this dialog below.
    • templateScript to /templating-kit/components/content/recipe.ftl. You will create this script below.
    • title to a suitable name. The component title is displayed in the selector dialog.

Create the dialog defintion

The next step is to create the dialog definition for the new component in Templating Kit > Dialog Definitions.

  1. Copy the components/content/stkTextImage node and rename it stkRecipe.
  2. Under tabText, create six edit controls: name (recipe name), author, prepTime (preparation time), cookTime (cooking time)), totalTime and yield.
  3. Under tabText, create three fckEdit controls: summary (introductory text), ingredients (recipe ingredients) and instructions.
  4. Set the value of the description and label nodes of each field appropriately.
  5. Order the nodes as shown below.
  6. Set the value of the label node. The value is displayed in the dialog header.

Create the component script

The next step is to create the template script in Templating Kit > Templates.

  1. Add a new template to the templating-kit/components/content node and name it recipe.
  2. Copy the script below and paste it into the dialog.
  3. Select Enable template to ensure that the template is served from the repository.
  4. Save.
[#include "/templating-kit/components/macros/image.ftl"/]
[#assign divClass = def.parameters.divClass!"text-section"]
<div class="hrecipe">
   [#if content.name?has_content]
      <h2 class="fn">${content.name?html}</h3. 
   [/#if]
   [#if content.author?has_content]
      <p>By: <span class="author">${content.author?html}</span></p>
   [/#if]
   [@image image=model.image! imageClass=model.imageClass/]  
   [#if content.summary?has_content]
      <p class="summary">${cmsfn.decode(content).summary}</p>
   [/#if]
   <table width="100%">
      <tr>
         <th>Preparation Time</th>
         <th>Cooking Time</th>
         <th>Total Time</th>
         <th>Servings</th>
      </tr>
      <tr>
         <td class="prepTime">
            [#if content.prepTime?has_content]         
            <span class="value-title" title="PT${content.prepTime?html}M"></span>
            ${content.prepTime?html} min
            [/#if]
         </td>
         <td class="cookTime">
            [#if content.cookTime?has_content]         
            <span class="value-title" title="PT${content.cookTime?html}M"></span>
            ${content.cookTime?html} min
            [/#if]
         </td>
         <td class="duration">
            [#if content.totalTime?has_content]
            <span class="value-title" title="PT${content.totalTime?html}M"></span>
            ${content.totalTime?html} min
            [/#if]
         </td>
         <td class="yield">
            ${content.yield?html!} portions
         </td>
      </tr>
   </table>
   <h2>Ingredients</h3. 
      [#if content.ingredients?has_content]
         <p class="ingredient">${cmsfn.decode(content).ingredients}</p>
      [/#if]
   <h2>Instructions</h3. 
      [#if content.instructions?has_content]
         <p class="instructions">${cmsfn.decode(content).instructions}</p>
      [/#if]         
</div>

Note the following about the code

  • According to the hRecipe microformat specification, durations such as the cooking time and preparation time must be given in an ISO 8601 format. For example, 1 hour and 30 minutes is "PT1H30M".
  • To simplify the example, we used a single ingredients class for the entire ingredients list. This is not quite right. The correct way would be to list each ingredient and its quantity separately. You could extend the example by storing common ingredients in the Data module and allow the editor pick them with a multiselect control.

Make the component available

The next step is to make the component available to editors. You can configure site-wide availability in the site definition or make the component available in a specific template. Here we add the component to the stkArticle template only.

  1. Go to Templating Kit > Template Definitions.
  2. Under /pages/stkArticle/areas/main/areas/content/availableComponents, add a content node and name it stkRecipe.
  3. Under stkRecipe, add a data node id and set its value to standard-templating-kit:components/content/stkRecipe.

Test the result

In Website add the Recipe component to any page based on the stkArticle template.

Google provides a Rich Snippets Testing Tool to test complaince with their rich snippet standards. Once you have published the page to a live URL, test it in the tool.

Download the example

Download microformats-example.zip  and import the XML into the demo-project website and configuration.

  • No labels