A Basic Script to Switch Between Mobile and Desktop Layout

On this page a basic PHP script will be presented to switch between a mobile and desktop version of a webpage. The main target for creating this script was to present a working model that can be used for educational purposes. This way it may become clear how such an approach can be realized and students can experience the main functions that we like to emphasize as important, which are:

  • it automatically detects what kind of browser a visitor uses;
  • it presents the appropriate version of the webpage for desktop and mobile;
  • the automated presented desktop and mobile versions of the webpage will use the same filename (One Web);
  • the script allows the visitor to overrule this automatically determined choice;
  • the visitor’s preference will be stored in a cookie so that at a next visit with the same browser he does not need to use the switch again;
  • since this last function cannot be done without redirection there is a canonical link to the main version of the webpage present (One Web).

A working example of this script can be found here

The code

Click on the filenames below to see the code of the corresponding file and the companion instructions.

.htaccess

The .htaccess file needs the following code to set the cache-control for the stylesheets. Since cache-control for PHP needs to be set with PHP you will not find the cache-control settings for the webpages in the .htacces file below.

In case you don’t have access to put a .htacces file on your server, you will find special stylesheets below that contain the cache-control with PHP.

download
0001<ifModule mod_headers.c> 
0002 <FilesMatch ".(css)$">
0003 Header set Expires "Thu, 15 Apr 2040 20:00:00 GMT"
0004 Header set Content-Type "text/css; charset = utf-8"
0005 Header set Cache-Control "max-age = 1100"
0006 </FilesMatch>
0007</ifModule>

page.php

This webpage is a template for all the pages in the site. There is no need to bother about the canonical link, the script will automatically take care of it, same as for any duplicate page. The cookie will be automatically placed by the script as well, for all versions of the web page, desktop and mobile and duplicates.

The PHP code is kept out of the HTML as much as possible without losing the aim to make clear what needs to be done and how this can be done. This means there is some PHP in the webpages that can’t be left out:

  • See the comments inside the code of the webpage, don’t leave out to read them. The comments at line 9 are especially important and are about the PHP variable at line 10.
  • You can edit the value of the lifetime of the cookie in the PHP code at line 11. The companion comments explain how.
  • The switch for mobile/desktop looks like this:
    <?php echoSwitch('Desktop Page', 'Mobile Page'); ?>
    The content for either desktop or mobile can be placed between the single quotation marks. Here the content on desktop will be ‘Desktop Page’ and on mobile it will be ‘Mobile Page’. You can place this PHP code where ever you like in the content of the webpage, just make sure you paste it from the first < up to the close >. Any content outside of this code will be shown on both desktop and mobile.
  • At line 12 you will find the $maxage variable so that you can set the cache-control for each page as you like
  • At line 34 another PHP code begins that switches desktop/mobile content. If you look closely you will see that the single quotation marks as you can see them in the sample just mentioned, are missing inside the PHP code at line 34 and are replaced with HEREDOC notation. Read the comments that start at line 54 to learn more about this.

download
0001<?php
0002/*
0003* This script has been written by Alex Pot of SmartScripts (www.smartscripts.nl)
0004* The detection of $_GET['m'] and $_COOKIE['m'] is an adapted version of a script by Phil Archer (http://philarcher.org/diary/2011/mobilecontentandstyle/)
0005* The lightweight class for detection of mobile browsers can be found here: http://code.google.com/p/php-mobile-detect/
0006* You are free to adapt and use this script for your own projects, on the one condition that you keep these credits intact
0007*/
0008 
0009//if your files are in the rootfolder of your site, $subdir has no value written between the quotation marks, like this ''; else you name the subdir, like so: '/namesubdir' (note it has a slash at the start, BUT NOT AT THE END!). This sample suggests to name the folder 'switch', this is the value used below. This is correct as long as the folder is placed in the root and not in a subfolder; else the value should be '/namesubfolder/switch'.
0010$subdir = '/switch'; //change this according to the name of the folder your files are in (see also instruction above)
0011$cookie_lifetime = 60*60*24*30; //you may change the numbers: sec x min x hrs x days = how long (in seconds) must the cookie with the user preference persist?
0012$maxage = 60; //this is the value (in seconds) for the max-age header that the switcher-script sends. This time will determine how long the version op the page in your browser cache will stay unrefreshed. Note: changes in the user preference for the lay-out will only become definitive after this number of seconds.
0013 
0014//==================== DON'T CHANGE PHP VARIABLES BELOW THIS LINE ==========================
0015 
0016$root = $_SERVER['DOCUMENT_ROOT'] . $subdir;
0017$file = __FILE__;
0018 
0019//include required by the mobile-desktop switch script:
0020include($root . '/inc/switcher.php');
0021?>
0022<DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"  "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
0023<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en">
0024<head>
0025  <title><?php echoSwitch('Desktop Page', 'Mobile Page'); ?></title>
0026  <link rel = "canonical" href = "<?php echo $full_path; ?>" />
0027  <link rel = "stylesheet" type = "text/css" href = "<?php echoSwitch('screen_styles', 'mobile_styles'); ?>.css" />
0028</head>
0029<body>
0030<p id = "mob_switch"><a href = "<?php echo $current_file['basename']; ?>?m = <?php echoSwitch('1', '0'); ?>"><?php echoSwitch('Mobile View', 'Desktop View'); ?></a> (changes will become definitive after a delay of <?php echo $maxage; ?> seconds or a reload of the page)</p>
0031<h1><?php echoSwitch('Desktop', 'Mobile'); ?> Presentation</h1>
0032<p>This static page represents the <?php echoSwitch('desktop', 'mobile'); ?> presentation of the resource available at <?php echo $full_path; ?>.</p>
0033<?php
0034echoSwitch(
0035<<<DESKTOP
0036 
0037<h2>Content with quotation marks</h2>
0038<p id = "sample">In 'reprehenderit' in voluptate lorem ipsum dolor sit amet: "consectetur adipisicing elit". Ut aliquip ex ea commodo consequat. Sed do eiusmod tempor incididunt cupidatat non proident, in reprehenderit in voluptate. Ut enim ad minim veniam, ullamco laboris nisi mollit anim id est laborum.</p>
0039<p>Eu fugiat nulla pariatur. Duis aute irure dolor lorem ipsum dolor sit amet, sunt in culpa. Velit esse cillum dolore excepteur sint occaecat qui officia deserunt. Eu fugiat nulla pariatur. Duis aute irure dolor in reprehenderit in voluptate ullamco laboris nisi.</p>
0040<p>Ut aliquip ex ea commodo consequat. Ut enim ad minim veniam, ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, in reprehenderit in voluptate excepteur sint occaecat. Ut aliquip ex ea commodo consequat. Duis aute irure dolor ut enim ad minim veniam, ullamco laboris nisi.</p>
0041 
0042DESKTOP
0043,
0044<<<MOBILE
0045 
0046<h2>Content with quotation marks</h2>
0047<p id = "sample">In 'reprehenderit' in voluptate lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut aliquip ex ea commodo consequat. Sed do eiusmod tempor incididunt cupidatat non proident, in reprehenderit in voluptate. Ut enim ad minim veniam, ullamco laboris nisi mollit anim id est laborum.</p>
0048 
0049MOBILE
0050); ?>
0051<p><a href = "page2.php">PAGE 2</a></p>
0052 
0053<!-- Read this comment about placing content with quotation marks:
0054 
0055Take a look above at for instance in line 26 where is written 'Desktop Page' and 'Mobile Page'. The text Desktop Page will be presented on desktop and the text Mobile Page on mobile. If you replace that text with a larger block of content, then that is the content that wil be presented instead. If that contant contains single quotation marks, you are in trouble: the browser will read these as PHP instead of the HTML you mean it to be.
0056 
0057If content has been placed via the PHP HEREDOC-notation (see the section above with the header 'Content with quotation marks'), then that way quotation marks in the content won't pose a problem anymore. As you can see in that section, that does contain these single quotation marks.
0058 
0059The HEREDOC-notation is done by replacing the start quotation marks with what is written instead at line 36 and at the end at line 43.
0060 
0061It is not impossible to place content in PHP code that uses single quotation marks like in the sample at line 26. All you need to do is place one backslash before any single quotation mark inside the content like this Tim\'s. This will make the browser present the content correctly. It may be clear that using HEREDOC-notation instead for larger pieces of content, is safer.
0062 
0063Note that PHP may use double quotation marks instead of single ones. In that case an HTML attribute like an ID or a class may cause similar problems. You can solve this with a backslash before the double quotaton marks like this id = \"test\".
0064 
0065By the way: you may use the same HEREDOC notations as many times as you like in one page. So DESKTOP and MOBILE as markers don't need to be unique. You may also use just D instead of DESKTOP and just M instead of MOBILE, or another variation, that's up to you, just keep the syntax similar.
0066 
0067End of comment -->
0068 
0069</body>
0070</html>

page2.php

This page is created by duplicating the page above. Just make sure that any new webpage that you create will be a duplicate of that page as well and you will be fine. Don’t forget to fill in the page title for desktop and mobile. There is no need to bother about the canonical link, the script will take care of it. Also the cookie will be placed by the script.

download
0001<?php
0002/*
0003* This script has been written by Alex Pot of SmartScripts (www.smartscripts.nl)
0004* The detection of $_GET['m'] and $_COOKIE['m'] is an adapted version of a script by Phil Archer (http://philarcher.org/diary/2011/mobilecontentandstyle/)
0005* The lightweight class for detection of mobile browsers can be found here: http://code.google.com/p/php-mobile-detect/
0006* You are free to adapt and use this script for your own projects, on the one condition that you keep these credits intact
0007*/
0008 
0009//if your files are in the rootfolder of your site, $subdir has no value written between the quotation marks, like this ''; else you name the subdir, like so: '/namesubdir' (note it has a slash at the start, BUT NOT AT THE END!). This sample suggests to name the folder 'switch', this is the value used below. This is correct as long as the folder is placed in the root and not in a subfolder; else the value should be '/namesubfolder/switch'.
0010$subdir = '/switch'; //change this according to the name of the folder your files are in (see also instruction above)
0011$cookie_lifetime = 60*60*24*30; //you may change the numbers: sec x min x hrs x days = how long (in seconds) must the cookie with the user preference persist?
0012$maxage = 60; //this is the value (in seconds) for the max-age header that the switcher-script sends. This time will determine how long the version op the page in your browser cache will stay unrefreshed. Note: changes in the user preference for the lay-out will only become definitive after this number of seconds.
0013 
0014//==================== DON'T CHANGE PHP VARIABLES BELOW THIS LINE ==========================
0015 
0016$root = $_SERVER['DOCUMENT_ROOT'] . $subdir;
0017$file = __FILE__;
0018 
0019//include required by the mobile-desktop switch script:
0020include($root . '/inc/switcher.php');
0021?>
0022<DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"  "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
0023<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en">
0024<head>
0025  <title><?php echoSwitch('Desktop Page 2', 'Mobile Page 2'); ?></title>
0026  <link rel = "canonical" href = "<?php echo $full_path; ?>" />
0027  <link rel = "stylesheet" type = "text/css" href = "<?php echoSwitch('screen_styles', 'mobile_styles'); ?>.css" />
0028</head>
0029<body>
0030<p id = "mob_switch"><a href = "<?php echo $current_file['basename']; ?>?m = <?php echoSwitch('1', '0'); ?>"><?php echoSwitch('Mobile View', 'Desktop View'); ?></a> (changes will become definitive after a delay of <?php echo $maxage; ?> seconds or a reload of the page)</p>
0031<h1><?php echoSwitch('Desktop', 'Mobile'); ?> Presentation of page 2</h1>
0032<p>This static page represents the <?php echoSwitch('desktop', 'mobile'); ?> presentation of the resource available at <?php echo $full_path; ?>.</p>
0033<?php
0034echoSwitch(
0035<<<DESKTOP
0036 
0037<h2>Lorem Ipsum</h2>
0038<p>Eu fugiat nulla 'pariatur'. Ut aliquip ex ea commodo consequat. Ullamco laboris nisi sunt in culpa qui officia deserunt. Excepteur sint occaecat cupidatat non proident, ut enim ad minim veniam. In reprehenderit in voluptate sunt in culpa velit esse cillum dolore. Mollit anim id est laborum. Quis nostrud exercitation ut enim ad minim veniam, ut aliquip ex ea commodo consequat. Excepteur sint occaecat ut labore et dolore magna aliqua. Ut enim ad minim veniam, duis aute irure dolor velit esse cillum dolore. Ullamco laboris nisi ut labore et dolore magna aliqua. Excepteur sint occaecat sunt in culpa eu fugiat nulla pariatur. Ut aliquip ex ea commodo consequat. Ut enim ad minim veniam, ut labore et dolore magna aliqua. Sed do eiusmod tempor incididunt excepteur sint occaecat lorem ipsum dolor sit amet. Consectetur adipisicing elit, in reprehenderit in voluptate sunt in culpa. Sed do eiusmod tempor incididunt ullamco laboris nisi ut enim ad minim veniam.</p>
0039 
0040DESKTOP
0041,
0042<<<MOBILE
0043 
0044<h2>Lorem Ipsum</h2>
0045<p>Eu fugiat nulla 'pariatur'. Ut aliquip ex ea commodo consequat. Ullamco laboris nisi sunt in culpa qui officia deserunt. Excepteur sint occaecat cupidatat non proident, ut enim ad minim veniam. In reprehenderit in voluptate sunt in culpa velit esse cillum dolore. Mollit anim id est laborum. Quis nostrud exercitation ut enim ad minim veniam, ut aliquip ex ea commodo consequat.</p>
0046 
0047MOBILE
0048); ?>
0049<p><a href = "page.php">HOME</a></p>
0050</body>
0051</html>

screen_styles.css

Write your CSS for the desktop version of your webpages in this stylesheet. If you want to change the name of the file, you can change the link in the webpage in the PHP code at line 28. If your server does not allow you to put an .htaccess file, you need to use the stylesheet below, screen_styles.php, instead. Read more about this at ‘Download the files’.

download
0001body {font-family:sans-serif; color:black; background-color:#ccf}

screen_styles.php

This stylesheet is meant for those who cannot put an .htaccess file on their server. Write your CSS for the desktop version of your webpages in this stylesheet below the PHP code. Leave this PHP code in top of the stylesheet untouched, it contains the Cache-Control header instead of writing it in .htaccess. If you want to change the name of the file, you can change the link in the webpage in the PHP code at line 28. See below at ‘Download the files’ for additional instructions.

download
0001<?php
0002header("Content-Type: text/css; charset = utf-8");
0003header("Cache-Control: max-age = 36000");
0004?>
0005 
0006body {font-family:sans-serif; color:black; background-color:#ccf}

mobile_styles.css

Write your CSS for the mobile version of your webpages in this stylesheet. If you want to change the name of the file, you can change the link in the webpage in the PHP code at line 28. If your server does not allow you to put an .htaccess file, you need to use the stylesheet below, mobile_styles.php, instead. Read more about this at ‘Download the files’.

download
0001body {font-family:sans-serif; color:#ccf; background-color:black}
0002a {color:red}

mobile_styles.php

This stylesheet is meant for those who cannot put an .htaccess file on their server. Write your CSS for the mobile version of your webpages in this stylesheet below the PHP code. Leave this PHP code in top of the stylesheet untouched, it contains the Cache-Control header instead of writing it in .htaccess. If you want to change the name of the file, you can change the link in the webpage in the PHP code at line 28. See below at ‘Download the files’ for additional instructions.

download
0001<?php
0002header("Content-Type: text/css; charset = utf-8");
0003header("Cache-Control: max-age = 36000");
0004?>
0005body {font-family:sans-serif; color:#ccf; background-color:black}
0006a {color:red}

inc/switcher.php

This script is developed in teamwork with and for the Mobile Web and Apps Best Practices Training of W3C Online Training.

download
0001<?php
0002/*
0003* This script has been written by Alex Pot of SmartScripts (www.smartscripts.nl)
0004* The detection of $_GET['m'] and $_COOKIE['m'] is an adapted version of a script by Phil Archer (http://philarcher.org/diary/2011/mobilecontentandstyle/)
0005* The lightweight class for detection of mobile browsers can be found here: http://code.google.com/p/php-mobile-detect/
0006* You are free to adapt and use this script for your own projects, on the one condition that you keep these credits intact
0007*/
0008 
0009if (!isset($root)) {
0010 header("HTTP/1.0 404 Not Found"); //hide existence of this file
0011 die;
0012}
0013 
0014header("Vary: User-Agent, Accept");
0015 
0016//construct the base url (including the directory, but not the file name):
0017$base = "http://" . $_SERVER['SERVER_NAME'] . preg_replace("/[^\/]*(\?.*)?$/", "", $_SERVER['REQUEST_URI']);
0018 
0019$mobile_browser = 0;
0020$display_mode_changed = false;
0021 
0022if (isset($_GET['m']) && in_array($_GET['m'], Array("0", "1"))) { // We have a value directly from the user that we need to store
0023  setcookie('m', $_GET['m'], time()+$cookie_lifetime);	// Although we may already have a cookie, the value may
0024  $_COOKIE['m'] = $_GET['m'];						// have changed so we'll store it anyway. Also update $_COOKIE array.
0025 
0026  if ($_GET['m'] == "1")$mobile_browser++;
0027 
0028  $display_mode_changed = true;
0029}
0030 
0031elseif (isset($_COOKIE['m']) && $_COOKIE['m'] == "1") {// If we have a cookie set to 1 or if we have
0032 $mobile_browser++;								// just set it to 1, we want the mobile view
0033}
0034 
0035elseif (isset($_COOKIE['m']) && $_COOKIE['m'] == "0") { //forced Desktop View
0036  $mobile_browser = 0;
0037}
0038 
0039else {						// No indication of user preference
0040  include($root . "/inc/mobile_detection_class.php");	// include the detector script
0041  $detect = new Mobile_Detect();
0042 $mobile_browser = $detect->isMobile(); //returns 0 or 1
0043}		//OK, we're done. We know which version we want so let's return it
0044 
0045 
0046if (!$display_mode_changed)header("Cache-Control: max-age = " . $maxage);				// Set cache control before we go any further
0047else {
0048 //force a quicker refresh of (only) the current page after the visitor has changed the display mode manually:
0049 header("Expires: ".gmdate("D, d M Y H:i:s")." GMT"); // Always expired
0050 header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");// always modified
0051 header("Cache-Control: no-cache, must-revalidate, max-age = 0");// HTTP/1.1
0052 header("Pragma: nocache");// HTTP/1.0
0053 header("Cache-Control: max-age = 0"); //force refresh of this page
0054}
0055 
0056$current_file = pathinfo($file);
0057$full_path = $base . $current_file['basename'];
0058 
0059function echoDesk ($text) {
0060 global $mobile_browser;
0061 if ($mobile_browser == 0 ) {
0062  echo $text;
0063 }
0064}
0065 
0066function echoMobile ($text) {
0067 global $mobile_browser;
0068 if ($mobile_browser > 0 ) {
0069  echo $text;
0070 }
0071}
0072 
0073function echoSwitch ($desktoptext, $mobiletext) {
0074 global $mobile_browser;
0075 if ($mobile_browser > 0 ) {
0076  echo $mobiletext;
0077 }
0078 else echo $desktoptext;
0079}

inc/mobile_detection_class.php

The lightweight class for detection of mobile browsers device detection script below can also be found at http://www.opensource.org

download
0001<?php
0002 
0003/**
0004 * Mobile Detect
0005 *
0006 * @license    http://www.opensource.org/licenses/mit-license.php The MIT License
0007 * @version    SVN: $Id: Mobile_Detect.php,v 1.1 2011/07/06 14:40:34 phila Exp $
0008 */
0009 
0010class Mobile_Detect {
0011 
0012 protected $accept;
0013 protected $userAgent;
0014 
0015 protected $isMobile     = false;
0016 protected $isAndroid    = null;
0017 protected $isBlackberry = null;
0018 protected $isIphone = null;
0019 protected $isOpera      = null;
0020 protected $isPalm       = null;
0021 protected $isWindows    = null;
0022 protected $isGeneric    = null;
0023 
0024 protected $devices = array(
0025  "android"       => "android",
0026  "blackberry"    => "blackberry",
0027  "iphone"        => "(iphone|ipod)",
0028  "opera"         => "opera mini",
0029  "palm"          => "(avantgo|blazer|elaine|hiptop|palm|plucker|xiino)",
0030  "windows"       => "windows ce; (iemobile|ppc|smartphone)",
0031  "generic"       => "(kindle|mobile|mmp|midp|o2|pda|pocket|psp|symbian|smartphone|treo|up.browser|up.link|vodafone|wap)"
0032 );
0033 
0034 
0035 public function __construct () {
0036  $this->userAgent = $_SERVER['HTTP_USER_AGENT'];
0037  $this->accept    = $_SERVER['HTTP_ACCEPT'];
0038 
0039  if (isset($_SERVER['HTTP_X_WAP_PROFILE'])|| isset($_SERVER['HTTP_PROFILE'])) {
0040   $this->isMobile = true;
0041  } elseif (strpos($this->accept,'text/vnd.wap.wml') > 0 || strpos($this->accept,'application/vnd.wap.xhtml+xml') > 0) {
0042   $this->isMobile = true;
0043  } else {
0044   foreach ($this->devices as $device => $regexp) {
0045    if ($this->isDevice($device)) {
0046     $this->isMobile = true;
0047    }
0048   }
0049  }
0050 }
0051 
0052 
0053 /**
0054  * Overloads isAndroid() | isBlackberry() | isOpera() | isPalm() | isWindows() | isGeneric() through isDevice()
0055  *
0056  * @param string $name
0057  * @param array $arguments
0058  * @return bool
0059  */
0060 public function __call ($name, $arguments) {
0061  $device = substr($name, 2);
0062  if ($name == "is" . ucfirst($device)) {
0063   return $this->isDevice($device);
0064  } else {
0065   trigger_error("Method $name not defined", E_USER_ERROR);
0066  }
0067 }
0068 
0069 
0070 /**
0071  * Returns true if any type of mobile device detected, including special ones
0072  * @return bool
0073  */
0074 public function isMobile () {
0075  return ($this->isMobile) ? 1 : 0;
0076 }
0077 
0078 
0079 protected function isDevice ($device) {
0080  $var    = "is" . ucfirst($device);
0081  $return = $this->$var === null ? (bool) preg_match("/" . $this->devices[$device] . "/i", $this->userAgent) : $this->$var;
0082 
0083  if ($device != 'generic' && $return == true) {
0084   $this->isGeneric = false;
0085  }
0086 
0087  return $return;
0088 }
0089}

Download the files

All files mentioned above are available in an archive: zip-archive.

About the PHP

According the PHP there are two things worth mentioning:

  • For the use of the script your server needs to support PHP 5.
  • To keep the script out of the HTML as much as possible for this basic method, you will find the main part of the script in the folder named ‘inc’, where it is split up in two parts: one is the device detection and the other one is responsible for the switch between presentation of the mobile or desktop version of the webpage.

Version with .htaccess

For those among you that have the rights to put a .htaccess on the server, you need to do the following:

  • Write your CSS in the files named desktop_styles.css and mobile_styles.css.
  • You can delete the files named desktop_styles.php and mobile_styles.php

Version without .htaccess

For those among you that are not allowed to work with .htaccess on the server, you need to do the following:

  • Change the link in the web page(s) to the stylesheets from .css to .php
  • Write your CSS in the files named desktop_styles.php and mobile_styles.php. Be careful to leave the PHP code in the beginning of the stylesheets untouched.
  • You can delete the files named desktop_styles.css and mobile_styles.css
  • You can delete the .htaccess file

To complete the download there is a readme file included.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>