Mobile capability detection with WURFL

Mobile devices come in all shapes and sizes, and can have vastly different capabilities. The Wireless Universal Resource File (WURFL) can help you adapt your sites to mobile devices, and it's easy to integrate with its Java API through a plugin in Enonic Vertical Site.

Adapting web pages for mobile devices

In general, there are three methods for adapting web pages for mobile devices, each with its own problems:

  1. Including a mobile CSS on the normal web pages - not all mobile browsers support this, and you may want to adapt the information on the pages to mobile devices
  2. Keeping web pages for mobile devices completely separate from normal web pages - this can mean duplicating information and effort, and can appear as two different sites
  3. User agent detection: detecting what kind of browser and device the user is using, and serving content based on that - this is error prone, it depends on being able to detect the correct browser and device

In this article we will look into the latter method, and see how the Wireless Universal Resource File can be used for this. Mobile stylesheets and standards can help a lot, but this method can be very beneficial to customize even more.

WURFL to the rescue

WURFL is an XML configuration file that contains information on a large number of mobile devices. Although there are people trying to keep this file up to date, there is unfortunately no guarantee that it is correct. However, it is in use around the world, and the project receives device updates on a daily basis, and is most likely our best choice if we choose this method of adapting web pages.

The process of using WURFL is broken down in two stages: first we get the device ID from the user agent string, and then we get information about one or more capabilities for this device. Capabilities tell us what a device can or can't do. For instance, the capability xhtml_support_level tells us to which degree XHTML and CSS is supported, and the wallpaper capability tells us whether or not the device supports downloading of wallpapers. See the WURFL documentation for a complete list of capabilities.

Although WURFL is only an XML file, APIs are available for the most popular programming languages. Using this, we can easily make a function plugin for Enonic Vertical Site that we can use to query for supported capabilities. We simply accept a comma separated list of capabilities as input, pass the user agent string on to the WURFL API, and build up an XML containing the capabilities. First we'll need to download the API from the WURFL Java API pages and extract it. The download will also include a tag library, for use in JSPs. The JAR files we need from the download to build our plugin are wurfl/WEB-INF/lib/wurfltags.jar and wurfl/WEB-INF/lib/xom-1.0.jar.

In addition to downloading the API, we will of course also have to download the WURFL file containing the device information. It can be downloaded from the WURFL homepage. Download both the wurfl.xml file and web patch file (save as wurfl_patch.xml). The latter contains configuration for desktop browsers, so that we will recognize them. The API will look for them in one of two places: in /tmp/ (or c:\tmp\), or it will read wurfl.properties and look for the wurflpath property.

Below is the complete Java code for the plugin, which should be fairly self-explanatory.

package com.enonic.cms.plugins.wurfl;

import net.sourceforge.wurfl.wurflapi.CapabilityMatrix;
import net.sourceforge.wurfl.wurflapi.ObjectsManager;
import net.sourceforge.wurfl.wurflapi.UAManager;

import org.jdom.Document;
import org.jdom.Element;

import com.enonic.cms.api.plugin.PluginEnvironment;

public class WurflFunctions {
    private UAManager uam = ObjectsManager.getUAManagerInstance();
    private CapabilityMatrix cm = ObjectsManager.getCapabilityMatrixInstance();

    public Document getCapabilities(String capabilityList) {
        // Split the comma separated list of capabilities into an array
        String[] capabilities = capabilityList.split("\\s*,\\s*");

        PluginEnvironment env = PluginEnvironment.getInstance();
        String userAgentString = env.getCurrentRequest()
                .getHeader("user-agent");

        // Get the device ID
        String deviceId = uam.getDeviceIDFromUALoose(userAgentString);

        Element wurfl = new Element("wurfl");
        wurfl.setAttribute("deviceid", deviceId);

        // Loop over the capabilities and build up the XML
        for (String capability : capabilities) {
            Element tmp = new Element(capability);
            tmp.setAttribute("value", cm.getCapabilityForDevice(deviceId,
                    capability));
            wurfl.addContent(tmp);
        }

        return new Document(wurfl);
    }
}

To deploy the plugin, we will also need a plugin configuration file, which is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean class="com.enonic.cms.api.plugin.FunctionLibraryPlugin">
        <property name="name" value="wurfl" />
        <property name="target">
            <bean class="com.enonic.cms.plugins.wurfl.WurflFunctions" />
        </property>
    </bean>

</beans>

For more information on creating function plugins, please see the function plugin tutorial.

Using the plugin

To use the plugin, create an object with the following datasource, changing the list of capabilities to be the capabilities you want to check for.

<?xml version="1.0" ?>
<datasources>
<datasource>
<methodname>wurfl.getCapabilities</methodname>
<parameters>
<parameter override="url" type="string">mobile_browser,has_qwerty_keyboard,is_wireless_device</parameter>
</parameters>
</datasource>
</datasources>

In this example we query WURFL for the name of the mobile browser that is installed on the device, if it has a full qwerty keyboard, and if it is a wireless device. The latter is important, because with normal desktop browsers this will be set to false. There are several ways to customize web pages according to device capabilities, it all depends on our imagination and what kind of web application we are adapting.

One example of how to use this would be to enable users to make calls directly from a web page, perhaps on an Intranet page that lists employees, or on a company web page with a list of addresses and phone numbers to stores. If phone numbers are marked up correctly, some devices will call the number when clicked. We can check for this capability by looking for xhtml_make_phone_call_string. Simply add the capability to the datasource, and add a check for the capability in the XSL as follows:

<xsl:choose>
  <xsl:when test="/verticaldata/wurfl/xhtml_make_phone_call_string != ''">
    <a href="{concat(/verticaldata/wurfl/xhtml_make_phone_call_string, $number)}"><xsl:value-of select="$number"/></a>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="$number"/>
  </xsl:otherwise>
</xsl:choose>

Other capabilities worth mentioning are:

  • xhtml_file_upload - true if devices support uploading files to the server
  • xhtml_support_level - can have 6 different values, depending on the level of support of XHTML, CSS and JavaScript
  • max_image_width/height - can help you scale images to the right dimensions

For more capabilities to test for, see the WURFL capabilities list.

Summary

As browsing on mobile devices become more and more widespread, thanks to the adoption of smartphones with high-quality browsers and screens, web developers might benefit from taking advantage of the capabilities unique to these devices. We have now shown how WURFL can be used for this in Enonic Vertical Site, and this should hopefully be enough to get you started.

Comments

5 August 2008 14:08

Commented by Thomas Lund Sigdestad

One comment to this is that you may not cache the rendered result markup, as the cache key will be the same. Enonic is working on allowing developers to create the cache key themselves - effectively solving this problem.

20 November 2009 15:27

Commented by Idel Fuschini

I have published a new mode to detect devices in any programming language (JSP, PHP, Perl, Python.....), it's called Apache Mobile Filter is an Apache module (http://modules.apache.org/search.php?id=1787) that detect mobile device and also can adapt the images to the screen size of device. For more info: http://www.idelfuschini.it/it/apache-mobile-filter-v2x.html

If you want to comment on this article you need to be logged in.

Published in 2011

2010

2009

2008

2007