Extension:MobileSkin

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual
Crystal Clear app error.png
MobileSkin

Release status: unstable

Implementation Skin
Description Automatically detect iPhone or other mobile devices to select a skin appropriate for the device (overrides user's preference for desktop without changing the user setting).
Author(s) Mark Daly (Chanurtalk)
Latest version 0.4 (2009-04-30)
MediaWiki 1.13.X
License GNU General Public License
Download See below
Hooks used
BeforePageDisplay

Translate the MobileSkin extension if it is available at translatewiki.net

Check usage and version matrix; code metrics
Also see Simple mobile skin auto change for a simple mobile skin detector that only requires adding a few lines to LocalSettings.php.

MobileSkin automatically detects the computer (device) requesting the page and determines if there is a skin that should be used instead. The user's preference is not changed, it simply becomes the user's default choice.

What can this extension do?[edit | edit source]

This extension automatically detects mobile devices using values in HTTP_USER_AGENT (browser identity) and changes the skin used to display the requested page. If HTTP_USER_AGENT does not contain any known mobile indicators (e.g. "iphone", "smartphone", "blackberry", "mobile", etc) the page will display with the user's default skin defined in his or her preferences.

If a mobile device is detected the extension uses the skin selected for that device type. For example, 'chick' is probably good for most mobile devices. You can, however, create new skins and direct MobileSkin to use those skins for different devices. The iPhone, for example, might use a different skin.

This extension allows users to have one username that automatically changes skin when the user is using a different type of device. This does assume a skin has been created and set up for each device type or a suitable skin already exists.

This extension does not use wurfl level detection.

Localization[edit | edit source]

This extension does not display any text to users or on the page; it simply changes the skin when displaying wiki pages based on the device. Thererefore, there is no 'MobileSkin.i18n.php' file to contain translations.

Usage[edit | edit source]

This extension operates without any additional tags or in-page instructions.

The class can be instantiated so other extensions can detect mobile devices or decide to include extensions if a mobile device - or not a mobile device - is requesting the page.

isMobile[edit | edit source]

This method simply indicates if this is a mobile device or not.

INPUT: no arguments

OUTPUT: boolean (true or false)

  • TRUE : mobile device of some kind requested the page
  • FALSE : page was not requested by a mobile device

EXAMPLE: Optionally include extensions for desktop-only use

$m = new MobileSkin;
if (!$m->isMobile()) require_once( "$IP/extensions/FCKeditor/FCKeditor.php" );

isIphone[edit | edit source]

This method works like isMobile() but checks to see if the device is an iPhone compatible device.

INPUT: no arguments

OUTPUT: boolean (true or false)

  • TRUE : iPhone requested the page
  • FALSE : page was not requested by an iPhone

EXAMPLE: Optionally include extensions for iPhone use

$m = new MobileSkin;
if ($m->isIphone()) {
	# iPhone specific actions go here
}

Change log[edit | edit source]

  • v0.4 2009-04-30 - fix bug in isSkinInstalled
  • v0.3 2009-04-30 - convert extension to a class
    • Remove $wgMobileSkinEnabled and $wgMobileSkinList settings
    • Move list of devices, skins, and HTTP_USER_AGENT patterns into class constructor
    • Split detection and change functions into separate "body" file
  • v0.2 2008-12-15 - initial beta release; basic functions
  • v0.1 2008-12-10 - initial test release (not posted to MediaWiki

Download instructions[edit | edit source]

Please cut and paste the code found below and place it in $IP/extensions/MobileSkin/. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php.

Installation[edit | edit source]

  1. Create and install any custom skins into the /skins folder. (optional)
  2. Install FCKeditor extension. (required for example usage)
  3. Create the /extensions/MobileSkin folder. (required)
  4. Create each file, as named below, in the /extensions/MobileSkin folder. (required)
  5. Edit MobileSkin.body.php to make any changes to the "mobileDevices" multi-dimensional array. (optional)
    Typically, this includes:
    1. Change skin names for each device to any new skins or existing skins you prefer on a device by device basis
    2. Add new devices with skin name and patterns to identify it
    3. Add new patterns as new phones become available
  6. Add the following code into LocalSettings.php: (required)
# Register the MobileSkin extension
require_once("$IP/extensions/MobileSkin/MobileSkin.php");

By default, all mobile devices uses the "chick" skin. If you create and install custom skin for the iPhone (for example), you should change the mapping to that skin.

User rights[edit | edit source]

This extension does not modify any user rights.

Code[edit | edit source]

MobileSkin.php[edit | edit source]

This file registers the extension.

<?php
## MobileSkin.php - Register the extension

# Needs to be called within MediaWiki; not standalone
if ( !defined('MEDIAWIKI') ) {
	echo("This is an extension to the MediaWiki package and cannot be run standalone.\n" );
	die(-1);
}
 
# Define the extension; allows us make sure the extension is used correctly
DEFINE( 'MOBILESKIN', 'MobileSkin' );
 
# Identify the extension, version, author, etc 
$wgExtensionCredits['parserhook'][] = array(
	'name'          =>      MOBILESKIN,
	'version'       =>      '0.4',
	'author'        =>      'Mark Daly',
	'url'           =>      'https://www.mediawiki.org/wiki/Extension:MobileSkin',
	'description'   =>      'Automatically switch skins based on user device without affecting user\'s preference'
);
 
# Set up extension and hook for the event handler (ev)
$wgHooks['BeforePageDisplay'][] = 'evMobileSkin_Setup';
 
# Pull in language/messages (if found)
if (file_exists(dirname(__FILE__) . '/MobileSkin.i18n.php'))
	$wgExtensionMessagesFiles['mobileskin'] = dirname(__FILE__) . '/MobileSkin.i18n.php';
 
# Pull in main code
require_once ( dirname(__FILE__) . '/MobileSkin.body.php' );
 
# Event handler
function evMobileSkin_Setup ( &$out, &$sk ) {
	$ms = new MobileSkin;
	return $ms->changeSkin( $out, $sk );
} # function evMobileSkin_Setup

# Additional functions for other extensions or LocalSettings.php
function is_mobile() {
	$m = new MobileSkin;
	return $m->isMobile();
} # function is_mobile

# Example use
function get_mobileName() {
	$m = new MobileSkin;
	return $m->getMobileDevice();
} # function get_mobileName

MobileSkin.body.php[edit | edit source]

This file contains the actual processing code that is called automatically by the extension event handler. In addition, there are some functions you can call for other reasons.

<?php
// MobileSkin.body.php
 
# Needs to be called within MobileSkin extension; not standalone
if ( !defined('MOBILESKIN') ) {
	echo("This is an extension to the MediaWiki MobileSkin extension and cannot be run standalone.\n" );
	die(-1);
}
 
class MobileSkin {
 
	var $defaultDevice;	// string containing name of default mobile device; usually "mobile"
	var $defaultSkin;	// skin to use when we have to punt
	var $mobileDevices;	// list of mobile devices, skins, and HTTP_USER_AGENT (browser) strings/patterns to look for
	var $mobileDebug;	// 0 = none; 1 = in/out of methods; 2 = full detail
 
//	##### CONSTRUCTOR #####
 
//	Get things set up.
	public function MobileSkin() {
 
	//	Set defaults
		$this->defaultDevice= 'mobile';
		$this->defaultSkin  = 'chick';
		$this->mobileDebug  = 2;
 
	//	Set up devices, skins, and patterns (list) to find
		$this->mobileDevices = array (
			array (	
				'device'	=> 'android', 
				'skin'		=> 'chick', 
				'patterns'	=> array ('android') 
			),
			array (	
				'device'	=> 'blackberry', 
				'skin'		=> 'chick', 
				'patterns'	=> array ('blackberry') 
			),
			array (	
				'device'	=> 'iphone', 
				'skin'		=> 'iphone', 
				'patterns'	=> array ('iphone', 'ipod') 
			),
			array (	
				'device'	=> 'mobile', 
				'skin'		=> 'mobile', 
				'patterns'	=> array (
					'176x220', '240x320', 
					'alcatel', 'amoi', 'audio', 'avant', 'benq', 'bird', 
					'cdm', 'chtml', 'compal', 
					'dbt', 'dddi', 'docomo', 'eric', 'gradi', 'hand', 'HTC', 
					'iemobile', 'j2me', 'java', 'jb', 'kdd', 'kg', 'lg', 
					'mib', 'midp', 'mitsu', 'mmm', 'mmp', 'mobi', 'mot-', 'moto', 'motorola', 
					'NEC', 'nokia', 'novarra', 'opwv', 
					'panasonic', 'pda', 'pg', 'philips', 'phone', 'pocket', 'pt', 'rover', 
					'sagem', 'samsung', 'sany', 'sch', 'SEC-', 'sendo', 'sgh', 'sharp', 
					'SIE-', 'smartphone', 'sony', 'sonyericsson', 'symbian', 
					'up.b', 'voda', 'vox', 'vx', 'wap', 'windows ce','wireless', 
					'xx' # last entry, no final comma
				) 
			),
			array (
				'device'	=> 'palm', 
				'skin'		=> 'chick', 
				'patterns'	=> array ('palm') 
			) #last entry, no final comma
		);
 
	}//function init
 
 
//	##### PUBLIC METHODS (functions) #####
 
//	Get the mobile device name, if any.
//	INPUT:	-nothing-
//	OUTPUT:	device name or empty string (which indicates it is not a [known] mobile device)
	public function getMobileDevice() {
		if (function_exists('wfDebug') && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileDevice()\n" );
 
		$returnValue = '';	// default: not a mobile device
		if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
			$returnValue = $this->defaultDevice;
		} elseif ((!$returnValue) && preg_match('/wap.|.wap/i',$_SERVER['HTTP_ACCEPT'])) {
			$returnValue = $this->defaultDevice;
		} else {	// check HTTP_USER_AGENT
			if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
				$browser = $_SERVER['HTTP_USER_AGENT'];
				if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
					wfDebug( "MobileSkin: browser is '$browser'\n" );
 
				foreach ($this->mobileDevices as $thisDevice) {
					if (strlen($returnValue) > 0) break;
					$deviceName = $thisDevice['device'];
					#$deviceSkin = $thisDevice['skin'];
					$deviceList = $thisDevice['patterns'];
					if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
						wfDebug( "MobileSkin: check device '$deviceName'\n" );
 
					foreach ($deviceList as $pattern) {
						if (strlen($returnValue) > 0) break;
						if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
							wfDebug( "MobileSkin: test pattern '$pattern'\n" );
 
						$stmp = '/' . strtolower(str_replace('/','',$pattern)) . '/i';
						if (preg_match($stmp, $browser)) {
							$returnValue = $deviceName;
						}
					} // for each pattern
				} // for each device
			}// browser string available
		}// not WAP
		if ((strlen($returnValue) > 0) && (function_exists('wfDebug')) && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileDevice() = '$returnValue'\n" );
		return strtolower($returnValue);
	}//function getMobileDevice
 
 
//	Get the mobile skin name, if any.
//	INPUT:	-nothing-
//	OUTPUT:	skin name or empty string (which indicates it is not a [known] mobile device)
	public function getMobileSkin( $deviceName ) {
		if (function_exists('wfDebug') && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileSkin()\n" );
 
		$returnValue = '';	// default: not a mobile device
		if (strlen($deviceName) > 0) {	// test a specific device
			foreach ($this->mobileDevices as $thisDevice) {
				if (strlen($returnValue) > 0) break;
				if ($deviceName == $thisDevice['device']) {
					$returnValue = $thisDevice['skin'];
				}
			} // for each device
 
		// OTHERWISE: check for skin using information from the actual device
		} elseif (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
			$returnValue = $this->defaultSkin;
		} elseif ((!$returnValue) && preg_match('/wap.|.wap/i',$_SERVER['HTTP_ACCEPT'])) {
			$returnValue = $this->defaultSkin;
		} else {	// check HTTP_USER_AGENT
			if ( isset($_SERVER['HTTP_USER_AGENT']) ) {
				$browser = $_SERVER['HTTP_USER_AGENT'];
				foreach ($this->mobileDevices as $thisDevice) {
					if (strlen($returnValue) > 0) break;
					#$deviceName = $thisDevice['device'];
					$deviceSkin = $thisDevice['skin'];
					$deviceList = $thisDevice['patterns'];
					foreach ($deviceList as $pattern) {
						if (strlen($returnValue) > 0) break;
						$stmp = '/' . strtolower(str_replace('/','',$pattern)) . '/i';
						if (preg_match($stmp, $browser)) {
							$returnValue = $deviceSkin;
						}
					} // for each pattern
				} // for each device
			}// browser string available
		}// not WAP
		if ((strlen($returnValue) > 0) && (function_exists('wfDebug')) && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: getMobileSkin() = '$returnValue'\n" );
		return strtolower($returnValue);
	}//function getMobileSkin
 
 
//	This function simply indicates if the device is a known mobile device or not (TRUE/FALSE).
	public function isMobile() {
		return (strlen($this->getMobileDevice()) > 0);
	}//function isMobile
 
//	This function indicates if the device is an iPhone or not (TRUE/FALSE).
	public function isIphone() {
		return ($thisMobileDevice() == 'iphone');
	}//function isIphone
 
 
//	Determine if the named skin code files can be found.
//	Actually looks on disk to see if the skin file is installed on the site.
	public function isSkinInstalled( &$skinName ) {
		$returnValue = false;	// skin was not found
		if (strlen(trim($skinName)) > 0) {
			$filename = 'skins/' . str_replace(' ','',ucwords(strtolower(trim($skinName)))) . '.php'; // typical name is first letter capitalized
			if (file_exists($filename)) $returnValue = true;
			if ((!$returnValue) && ($skinName == 'iphone')) { // special capitalization
				$filename = 'skins/iPhone.php';
				if (file_exists($filename)) $returnValue = true;
			}
		}
		return $returnValue;
	}//function isSkinInstalled
 
 
//	Actually change the skin if it is a mobile device.
	public function changeSkin( &$out, &$sk ) {
		global $wgUser;
 
		$returnValue = false;	// skin not changed
		if (function_exists('wfDebug') && ($this->mobileDebug > 0)) 
			wfDebug( "MobileSkin: changeskin()\n" );
 
		$sk = $wgUser->getSkin();	// initialize access to user's skin
		if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
			wfDebug( "MobileSkin: user selected skin is '$sk->getSkinName()'\n" );
 
		$deviceName = $this->getMobileDevice();
		if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
			wfDebug( "MobileSkin: device is '$deviceName'\n" );
 
		if (strlen($deviceName) > 0) {
			$skin = $this->getMobileSkin('');
			if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
				wfDebug( "MobileSkin: skin is '$skin'\n" );
 
			if (!$this->isSkinInstalled($skin)) {
				if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
					wfDebug( "MobileSkin: skin '$skin' is NOT INSTALLED; default $this->defaultSkin will be used\n" );
 
				$skin = $this->defaultSkin;
			}
 
			$sk = Skin::newFromKey($skin);	// temporarily change skin for this page
			if (function_exists('wfDebug') && ($this->mobileDebug > 1)) 
				wfDebug( "MobileSkin: user selected skin is '$sk->getSkinName()' ($skin)\n" );
 
			$returnValue = true;	// changed
		}
 
		return $returnValue;
	}//function changeSkin
 
}//class MobileSkin

MobileSkin.LocalSettings.php[edit | edit source]

This file contains up to date configuration settings for the extension. Copy this code into your LocalSettings.php file.

## MobileSkin.LocalSettings.php
# Copy the code below into LocalSettings.php

#####
# Add mobile skin selection

# Remove various skins from the User Preferences choices
# Keep: Classic (for safety); MonoBook; and anything new
#	$wgSkipSkins = array("chick", "cologneblue", "modern", "myskin", "nostalgia", "simple", "standard");

# Register the MobileSkin extension
	require_once("$IP/extensions/MobileSkin/MobileSkin.php");
 
#####
# Example use

## =====> FCK EDITOR MUST BE LAST EXTENSION <===== ##
# Add in a 'smart' editor for non-technical people
## Detect if user is on a mobile device; if they are do not enable the FCKEditor
	$mobile = new MobileSkin;
	if (!$mobile->isMobile()) require_once( "$IP/extensions/FCKeditor/FCKeditor.php" );
#	unset($mobile);	# clean up (optional)
## =====> FCK EDITOR MUST BE LAST EXTENSION <===== ##


See also[edit | edit source]