Overview

CycleServer formats and formatters are two parts of a single feature for displaying values based on attribute metadata. For example, using a built-in format/formatter, tagging an attribute “MemoryFree” with ‘Format=”Byte”‘ will cause CycleServer to interpret numeric values of that attribute as bytes and display values like “2GB” instead of 2147483648. Formatted values may also be non-textual values such as images, charts, links, etc.

What is a Format?

A format is an ad of type “Application.Format” which represents a particular data format, such as “Seconds since Epoch”, “Miles per Hour” or even enumerations such as “HTTP Request Method”. Below is an example of a format ad for “Seconds since Epoch”.

AdType="Application.Format"
Name="EpochSeconds"
Label="Seconds since Epoch"

That’s all there is to most format ads. However, there are a few other attributes which are defined below. Note that format ads do not contain much information about how to display values. They simply represent a known data format.

Application.Format Ad Definition

Attribute Type Status Description
Name String Required A unique name for this format
Label String Required The display name for this format.
Values List Optional If this format is an enumeration, this is a list of nested ads that
each define metadata about formatting specific values of the
enumeration.

Each nested ad in the Label attribute has the following attributes:

Value (any): the value
Label (string): a display name for this value
Color (string): an RGB hex string for the color to use for this value (e.g. "6A357D")

What is a Formatter?

A formatter is an ad of type “Application.Formatter” which represents a method of displaying values of a given format. For example, the “Seconds since Epoch” format defined above may be displayed as “4/22/12”, “22/4/12”, “4-22-12 04:23:01”, etc. Each of those three examples would be represented by its own formatter ad. Below is an example of a formatter ad for the first string: “4/22/12”, using a fictitious Javascript formatter plugin “my.DateFormatter”.

AdType="Application.Formatter"
Format="EpochSeconds"
Name="MiddleEndianDate"
Label="Date: MM/DD/YYYY"
Plugin="my.DateFormatter"
DateFormatString="MM/DD/yy"

The “Format” attribute references the “Application.Format” defined above. Note that there is a one-to-many relationship between formats and their respective formatters. Two particularly interesting attributes of this formatter ad are “Plugin” and “DateFormatString”. The former references a Javascript plugin which performs the actual formatting. The latter is a non-standard attribute that is used by that Javascript plugin. See the example below for details on how these plugins are written.

Application.Formatter Ad Definition

Attribute Type Status Description
Name String Required A unique name for this formatter
Label String Required The display name for this formatter
Format String Required A reference to the “Name” attribute of an Application.Format.Ad
Plugin String Required The name of a Javascript plugin which performs formatting.
Order Integer Optional For each format, the formatter with the lowest order is used by
default. If no order is specified, 1000 is used as the default.

Formatter Plugins

Formatter plugins are executed on the client, and must be written in Javascript. These plugins should inherit from one of two different dojo classes depending on the type of Formatter:

pico/format/TextFormatter

Used when a formatter will display simple text only. No HTML formatting may be used.

Required Functions

getText(value, hints)
Arguments:
* value – the raw value
* hints – an object with attributes which hint at the context of the formatted value. Some
examples of this might include width & height, or whether the background is dark or light.
Returns: a plain-text formatted value.

pico/format/Formatter

Used when a formatter will produce HTML, or a mix of plain-text and HTML.

Required Functions

initElement()
Returns: a DOM element which will contain the formatted value once updateElement() is
called. This is separate from the updateElement() function for performance
reasons. initElement() is called once to set up the DOM tree, and updateElement() may be called
many times to update it.
updateElement(el, value, hints)
Arguments:
el – the DOM element which will contain the formatted value (created by initElement())
value – the raw value
hints – an object with attributes which hint at the context of the formatted value. Some
examples of this might include width & height, or whether the background is dark or light.

Optional Functions

getWidth()
Returns: the preferred width in pixels of the formatted value or null if there is no preferred width
getText(value, hints)
Arguments:
value – the raw value
hints – an object with attributes which hint at the context of the formatted value. Some
examples of this might include width & height, or whether the background is dark or light.
Returns: a plain-text formatted value.

How does CycleServer decide which formatter to use?

When choosing a formatter to use for an attribute, 3 factors are considered, in order of importance:

  1. User preferences (Note that this is not yet implemented as of CycleServer 4.2)
  2. Additional attributes on the Formatter ad. For example, if we’re looking for a Formatter which
    displays values in a verbose manner (particularly useful for tooltips), we might look for an
    attribute “Detail” with a value of true.
  3. The “DefaultFormatter” attribute on the attribute ad.
  4. The “Order” attribute (lower = higher priority)

Calling Formatters from Javascript

To display an attribute of an ad in an HTML context, simply call the “pico/format.apply” method on the ad in the following manner:

<div id="newsContainer">
    <h1 id="title"></h1>
    <span id="date"></span>
    <span id="bodyText"></span>
</div>

<script type="text/javascript">

    require([
        "dojo/_base/kernel",
        "pico/ads",
        "pico/format"
    ], function(dojo, ads, pformat) {

        /*
         * Create a "News" ad, with some example data.
         */
        var ad = ads.create("News", {
            Title: "Hello World!",
            Date: 1282327962,
            Body: "In this example, we will use a formatter to support [link url='http://www.cyclecomputing.com']forum-style tags[/link]'"
        });

        /*
         * pico/format.apply takes 4 arguments:
         *    - ad: an ad containing the attribute to format.
         *    - attribute: the attribute we're formatting.
         *    - el: the DOM node which will contain the formatted result.
         *    - hints (optional): additional hints about the display context.
         */
        pformat.apply(ad, "Title", dojo.byId("title"));
        pformat.apply(ad, "Date", dojo.byId("date"));
        pformat.apply(ad, "Body", dojo.byId("bodyText"));

    });

</script>

The example above could result in the following effective HTML, assuming we have two formats/formatter plugins registered: one for the “Date” attribute, which displays a human readable date, and another for the “Body” attribute, which converts forum-style tags into HTML markup. Note that the “Title” attribute is formatted as a string inside of a &lt;span&gt; tag. This is because the default string formatter plugin is being used. Any attribute without a format registered will be formatted by the default formatter registered to its type.

<div id="newsContainer">
    <h1 id="title"><span>Hello World!</span></h1>
    <span id="date"><span>Friday August 20th, 2010</span></span>
    <span id="bodyText"><span>In this example, we will use a formatter to support
    <a href='http://www.cyclecomputing.com'>forum-style tags</a></span></span>
</div>