Detector Family Tutorial

dmolsen edited this page Aug 14, 2012 · 12 revisions

Detector Families allow developers to organize browsers that share certain traits into groupings. With families a developer can test for the group a browser belongs to rather than each individual feature that browser may support when displaying content. The family is returned as $ua->family and is generated on every request. This allows you to include per-session and per-request results when defining families.

Default Families

The default install of Detector will categorize browsers into one of three families. They are: tablet, mobile-advanced, mobile-basic, and desktop. families.json, which stores the family configuration, can be found in the config/ directory. The only difference between mobile-advanced and mobile-basic is that the former checks for support of csstransforms. The default set of groupings is not overly detailed and you may want to tweak it.

Families Aren't Just for Mobile vs Desktop

One thing should be made clear. Families don't have to be limited to mobile versus desktop groupings. Desktop browsers can also be categorized by features or user-agent information (e.g. Internet Explorer). Families are very flexible and their are a lot of features to play with.

Defining Families for Bots and Browsers That Don't Support JavaScript or Cookies

The primary use case for families so far seems to be with templating. You can make sure that search engine bots and those browsers that don't support JavaScript or cookies get a classified with a particular family for templating simply by editing config/config.ini. Set noJSCookieFamilySupport to true and supply the family names for the other options listed there (e.g. noJSSearchFamily).

Allowing Mobile Users Access to a "Full Site" Look via Families

Another case of using families with templating is to give mobile users access to your "full site." You can override any family simply by appending the request variable family=[familyname] to the page request. So you can append ?family=desktop to a "full site" link allowing mobile users to get the desktop family templates instead of the mobile templates. This feature can be turned on by editing config/config.ini and setting switchFamily to true.

Please note: the family value from the request variable is saved in session so that any future requests reflect the family choice. To reset the family value stored in session simply use ?family=clear-family and the family will again be calculated on each page load.

Creating Your Own Families

Let's use the default config as our base. It's fairly straightforward. The keys (e.g. mobile-advanced) will be the names of our families and the attributes (e.g. isMobile) are what's going to be tested by Detector.

{
    "tablet": {
         "isTablet": true
    },
    "mobile-advanced": { 
         "isMobile": true,
         "features": [ "csstransforms" ]
    },
    "mobile-basic": { 
         "isMobile": true
    },
    "desktop": {
         "isComputer": true
    }
}

Two important points:

  • each attribute that is tested for a family must return true for Detector to classify a browser as belonging to that family. So think of each comma (,) as an && when separating attributes.
  • families should be ordered from your most specific set of tests to the most general set of tests.

So to create your own family simply add a key and object that will hold the attributes you want to test. Let's say we want to group iOS devices:

{
    "tablet": {
        "isTablet": true
    },
    "mobile-ios": {

    },
    "mobile-advanced": { 
         "isMobile": true,
         "features": [ "csstransforms" ]
    },
    "mobile-basic": { 
         "isMobile": true
    },
    "desktop": {
         "isComputer": true
    }
}

But obviously you'll need to add attributes to test for iOS support...

Attributes That Can Tested

Any item that appears in the core profile, extended profile or from the per-request cookie can be tested in families. For the most part, any attribute that is generated by ua-parser-php and is related to the user-agent will be tested like the isMobile test. Some other examples:

"os": "iOS"
"browserFull": "Chrome 16.0.912"
"device": "Palm Pixi"

For those attributes that are browser attributes and sussed out by Modernizr they should be tested in the features array. Detector checks for a large number of these features. Simply separate each feature you want to test with a comma. Again, each comma should be treated as an &&. An example:

"features": ["cssanimations","indexeddb","deviceorientation"]

So in our example to test for iOS support we could expand it to be:

{
    "tablet": {
         "isTablet": true
    },
    "mobile-ios": {
         "os": "iOS",
    },
    "mobile-advanced": { 
         "isMobile": true,
         "features": [ "csstransforms" ]
    },
    "mobile-basic": { 
         "isMobile": true
    },
    "desktop": {
         "isComputer": true
    }
}

But let's say we want also want to check for Blackberry support. Using && all the time doesn't provide the most flexibility...

Operators

Their are three simple operators that can be used when building families. They are:

  • ! to test if a value is false and thus return true for the test
  • || to test if at least one of the options in the list is available
  • = to test if a feature matches a certain value

These operators can be used for attributes or the feature tests. Some examples:

// will return `true` for any OS result that _doesn't_ match iOS
"os": "!iOS" 

// will return `true` for any OS result that matches _either_ iOS or Blackberry
"os":  "iOS||Blackberry" 

// will return `true` if _either_ cssgradients and cssanimations are available _and_ indexeddb _isn't_ available
"features": [ "cssgradients||cssanimations", "!indexeddb"] 

At the moment their aren't any features in the default install of Detector that would require the = operator but it is available just in case.

So for our final example we'll rename the family to mobile-ios-bb and test for the availability of either OS:

{
    "tablet": {
         "isTablet": true
    },
    "mobile-ios-bb": {
         "os": "iOS||Blackberry",
    },
    "mobile-advanced": { 
         "isMobile": true,
         "features": [ "csstransforms" ]
    },
    "mobile-basic": { 
         "isMobile": true
    },
    "desktop": {
         "isComputer": true
    }
}

And that's how you can go about building a family for Detector.