Going Truly “Adaptive” With ExpressionEngine

Posted

I like simple. That’s why my current approach to designing and building “adaptive” or “responsive” ExpressionEngine sites avoids add-ons, subdomains, redirects or Javascript. Moreover, I’ve been focussing on delivering a truly adaptive experience that goes beyond CSS media queries. So, if you’re a newbie looking for an easy way to take your adaptive websites to the next level, give this a try.

CSS media queries. Good but not great

Initially for me, “adaptive” was all about showing, hiding and manipulating elements using CSS3 media queries for different resolutions. Definitely a step in the right direction. The big problem with this approach alone though is that end users (I’m thinking specifically of smart phone users on slow data connections) still have to download an entire page – including the hidden elements. Doesn’t sound very adaptive to me. We can do better right?

Global variables to the rescue

I use a device detection script to set a global variable of “full” or “mobile”. Try adding the following to your config.php:

global $assign_to_config;
if( ! isset($assign_to_config['global_vars']))
{
	$assign_to_config['global_vars'] = array();
}

$useragent = $_SERVER['HTTP_USER_AGENT']; // Let's do some device detection
if (preg_match('/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)))
$master_global = array(
	'global:site_version'      => 'mobile'
);
else
$master_global = array(
	'global:site_version'      => 'full'
);

$assign_to_config['global_vars'] = array_merge($assign_to_config['global_vars'], $master_global); // global var arrays
$config = array_merge($config); // config setting arrays

Learn more about config setup by downloading Focus Lab’s Master Config Setup.

Now we can get seriously adaptive. Instead of that long horizontal navigation menu you’re using for desktop users, how about a simple dropdown (select) form for mobile users? Create two snippets – {sn_menu_full} and {sn_menu_mobile} – and pop your horizontal menu in the first one; your dropdown in the second. Now, in your template just add:

{sn_menu_{global:site_version}}

Because global variables are parsed early, {global:site_version} will be replaced with either “full” or “mobile”, and your template will just display the appropriate snippet.

You can use conditionals too.

{if global:site_version=='full'}
Add some extra markup that you only want desktop users to see.
{/if}

These are just two examples, but you can probably begin to imagine all the adaptive fun you can have!

You don’t need a suite of devices to test your adaptiveness either. For a quick peek at your mobile site just resize your browser window, open config.php and change ‘global:site_version’ => ‘full’ to ‘global:site_version’ => ‘mobile’.

How do you roll?

As always, I’d love the community’s thoughts on this approach, and how they’re currently tackling the adaptive web. Please don’t think any of this applies to the DesignKarma website! As is always the case, this website languishes whilst I’m busy applying the latest technologies and techniques to client sites. I know, I know, poor excuse…

ClientKarma

Thrilled with the outcome of this project. The identity and website have given my new business a real head-start.