WURFL Patch Files

Introduction

The idea behind WURFL is that you get a newer version of the WURFL file as more accurate information becomes available and is added to the WURFL file. Developers can add a wurfl_patch.xml file to their system, which stores modified/enhanced groups and capability lists for new or existing WURFL devices.

When the WURFL is parsed, the patch file is also imported to build a modified version of the device database.

To apply the patch file, please see the respective documentation for your WURFL API.

When to use the patch

There may be different reasons why one wishes to use a patch file. Here are some (there may be others):

  • Your application is very specific. You may need capabilities that are not in the WURFL and are unlikely to be added (i.e. the WURFL is too general for your needs). You can define the capabilities in a patch file and update your WURFL without interference.

  • Capabilities return correct values but you have your own reasons to assign them different values. In this case you can use the WURFL file to override those capability values and still update the WURFL independently.

What does the patch file look like?

The patchfile is very similar to the WURFL itself (but hopefully much shorter!). Bialetti is an Italian coffee-maker manufacturer. I'll add coffee-maker support for the WURFL with a patch:

There are a few things to note about patch files:

  • wurfl_patch and devices enclose the patch.
  • If you add new groups and or capabilities to the WURFL for some devices, you must initialize them by overriding generic values and providing corresponding groups and capabilities with the values for unrecognized devices.
  • If the id of a certain device already exists, then you are overriding an existing device. Otherwise, it's effectively a new device that you are defining.
  • If you override an existing device, you are not allowed to change the User Agent string associated to the device by the WURFL.
  • If you are defining a new device, you must provide a User Agent string.
  • If you override an existing device, the capabilities you introduce are either:
    • Added to the list of capabilities for that device (the capability was not previously defined in the original device).
    • Used to modify the value of the capability (the capability was previously defined in the original device). Of course, this happens automatically, so your patch will keep working even if the capabilities in the patch are added to the official WURFL version.

Example:

Let's assume we have a wurfl_patch.xml file and a mini wurfl.xml file like the ones that follow:

**Please note that the following example files do not use real world device data, but are written to show the behavior of our API using patch files.

wurfl_patch.xml:

<wurfl_patch>
    <devices>
        <device user_agent="" fall_back="root" id="generic">
            <group id="magical_powers">
                 <capability name="makes_good_coffee" value="false" />
                 <capability name="average_coffee_preparation_time" value="0" />
            </group>
            <group id="display">
                <capability name="resolution_height" value="200"/>
                <capability name="lucas_capa" value="0"/>
            </group>
            <group id="new_group">
                <capability name="new_capa1" value="false"/>
                <capability name="new_capa2" value="0"/>
            </group>
            </device>
        <device user_agent="Nokia 20" fall_back="generic" id="nokia_generic_series20">
            <group id="new_group">
                <capability name="new_capa1" value="true"/>
                <capability name="new_capa2" value="34832798"/>
            </group>
            <group id="display">
                <capability name="resolution_height" value="3300"/>
            </group>
        </device>

        <!-- Adding a Coffee Pot to the WURFL -->
        <device id="bialetti_ver61" user_agent="Bialetti 6.1" fall_back="generic">
            <group id="magical_powers">
                 <capability name="makes_good_coffee" value="true" />
                 <capability name="average_coffee_preparation_time" value="5" />
            </group>
            <group id="display">
                <capability name="resolution_width" value="190"/>
                <capability name="resolution_height" value="140"/>
                <capability name="lucas_capa" value="34832798"/>
            </group>
        </device>
    </devices>
</wurfl_patch>

wurfl.xml:

    <wurfl>
        <devices>
            <device fall_back="root" id="generic" user_agent="">
                <group id="wml_ui">
                    <capability name="access_key_support" value="false" />
                        <capability name="wrap_mode_support" value="false" />
                    </group>
                <group id="display">
                    <capability name="resolution_width" value="90" />
                    <capability name="resolution_height" value="40" />
                </group>
            </device>
            <device user_agent="Nokia 20" fall_back="generic" id="nokia_generic_series20">
                <group id="display">
                    <capability name="resolution_width" value="260" />
                    <capability name="resolution_height" value="440" />
                </group>
            </device>
            <device user_agent="Nokia 30" fall_back="nokia_generic_series20" id="nokia_generic_series30">
                <group id="wml_ui">
                    <capability name="access_key_support" value="true" />
                </group>
                <group id="display">
                    <capability name="resolution_width" value="96" />
                    <capability name="resolution_height" value="65" />
                </group>
            </device>
            <device user_agent="Nokia 40" fall_back="nokia_generic_series30" id="nokia_generic_series40">
                <group id="display">
                    <capability name="resolution_width" value="128" />
                    <capability name="resolution_height" value="128" />
                </group>
            </device>
            <device user_agent="Nokia 60" fall_back="nokia_generic_series40"  id="nokia_generic_series60">
                <group id="wml_ui">
                    <capability name="access_key_support" value="false" />
                </group>
            </device>
        </devices>
    </wurfl>

The merged patch file (i.e. wurfl.xml patched with wurfl_patch.xml) will be equivalent to this:

<wurfl>
    <devices>
        <device fall_back="root" id="generic" user_agent="">
            <group id="wml_ui">
                <capability name="access_key_support" value="false"/>
                <capability name="wrap_mode_support" value="false"/>
            </group>
            <group id="display">
                <capability name="resolution_width" value="90"/>
                <capability name="resolution_height" value="200"/>
                <capability name="lucas_capa" value="0"/>
            </group>
            <group id="magical_powers">
                <capability name="makes_good_coffee" value="false"/>
                <capability name="average_coffee_preparation_time" value="0"/>
            </group>
            <group id="new_group">
                <capability name="new_capa1" value="false"/>
                <capability name="new_capa2" value="0"/>
            </group>
        </device>
        <device user_agent="Nokia 20" fall_back="generic" id="nokia_generic_series20">
            <group id="display">
                <capability name="resolution_width" value="260"/>
                <capability name="resolution_height" value="3300"/>
            </group>
            <group id="new_group">
                <capability name="new_capa1" value="true"/>
                <capability name="new_capa2" value="34832798"/>
            </group>
        </device>
        <device user_agent="Nokia 30" fall_back="nokia_generic_series20"  id="nokia_generic_series30">
            <group id="wml_ui">
                <capability name="access_key_support" value="true"/>
            </group>
            <group id="display">
                <capability name="resolution_width" value="96"/>
                <capability name="resolution_height" value="65"/>
            </group>
        </device>
        <device user_agent="Nokia 40" fall_back="nokia_generic_series30"  id="nokia_generic_series40">
            <group id="display">
                <capability name="resolution_width" value="128"/>
                <capability name="resolution_height" value="128"/>
            </group>
        </device>
        <device user_agent="Nokia 60" fall_back="nokia_generic_series40"  id="nokia_generic_series60">
            <group id="wml_ui">
                <capability name="access_key_support" value="false"/>
            </group>
        </device>
        <device id="bialetti_ver61" user_agent="Bialetti 6.1" fall_back="generic">
            <group id="magical_powers">
                <capability name="makes_good_coffee" value="true"/>
                <capability name="average_coffee_preparation_time" value="5"/>
            </group>
            <group id="display">
                <capability name="resolution_width" value="190"/>
                <capability name="resolution_height" value="140"/>
                <capability name="lucas_capa" value="34832798"/>
            </group>
        </device>
    </devices> 
</wurfl>