Nosotros usamos de base el plugin WPtouch, que es el que provee la versión para el iPhone, y sobre este hicimos que tuviera una plantilla «adicional». En la función detectAppleMobile del archivo wptouch.php:

  • Hay un primer ciclo encargado de detectar los «agentes móviles» que deseamos usen la versión para el iPhone.
  • Si no es uno de estos hay un segundo ciclo que intentará ver si es otro agente al cual hay que mostrar la versión más sencilla para móviles, como Opera Mini, IE Mobile y otros navegadores raros menos populares
  • Si ninguno de los ciclo encontró un «agente móvil», entonces se asume que es un cliente de escritorio al que hay que mostrar la plantilla «normal» del sitio, la plantilla que ustedes ya conocen desde el rediseño del sitio

En código, dicha función quedará así:

function detectAppleMobile($query = '') {
	$container = $_SERVER['HTTP_USER_AGENT'];
	$useragents = array("iphone", "ipod", "aspen", "dream", 'android');
		$this->applemobile = false;
	foreach ($useragents as $useragent) {
			if (eregi($useragent, $container)) {
				$this->applemobile = true;
				$this->is_iphone = true;
		}
	}
	
	// if not iphone
	if ( !$this->applemobile ) {

	$browserAgents = "Elaine/3.0, Palm, EudoraWeb, Blazer, AvantGo, Windows CE, Cellphone, Small, MMEF20, Danger, hiptop, Proxinet, ProxiNet, Newt, PalmOS, NetFront, SHARP-TQ-GX10, SonyEricsson, SymbianOS, UP.Browser, UP.Link, TS21i-10, MOT-V, portalmmm, DoCoMo, Opera Mini, Palm, Handspring, Nokia, Kyocera, Samsung, Motorola, Mot, Smartphone, Blackberry, WAP, SonyEricsson, PlayStation Portable, LG, MMP,OPWV, Symbian, EPOC";
	$browserAgents = explode(',',$browserAgents);
	if(!empty($browserAgents)){
		foreach ($browserAgents as $key => $value){
			$browserAgents[$key] = trim($value);
		}
	}
	
	foreach ( $browserAgents as $userAgent ) {
		if(eregi($userAgent,$container)){
			$this->applemobile = true;
			$this->is_iphone = false;
			//return;
		}
	}
	
	} //if ( !$this->applemobile )
	$this->bnc_filter_iphone();
}

Una vez ejecutado esto, ya solo tenemos que ver el valor de $this->applemobile para saber si es un «agente móvil» y $this->is_iphone para saber si le vamos a mostrar la versión para el iphone o no.

Luego de esto, tomamos nuestra plantilla basada sobre MobilePress y la llevamos hacia el directorio de plantillas del WPtouch (si el plugin ya tiene esto): /wp-content/plugins/wptouch/themes/. Hecho esto ya solo tenemos que especificarle a WordPress el directorio de la plantilla que deseamos usar:

function get_stylesheet($stylesheet) {
	if ($this->applemobile && $this->desired_view == 'mobile') {
		if ( $this->is_iphone )
			return 'default'; // './wptouch/themes/default'
		else
			return 'pda'; // './wptouch/themes/pda'
	} else {
		return $stylesheet;
	}
}
      
function get_template($template) {
	$this->bnc_filter_iphone();
	if ($this->applemobile && $this->desired_view === 'mobile') {
		if ( $this->is_iphone )
			return 'default'; // './wptouch/themes/default'
		else
			return 'pda'; // './wptouch/themes/pda'
	} else {      
		return $template;
	}
}

El cambio de plantilla solo se hace si $this->applemobile tiene el valor true, de lo contrario se usará la que esté configurada desde WordPress.

Con estas modificaciones a estas 3 funciones en wptouch.php ya deberíamos tener funcionando las diferentes plantillas según el agente desde el cual nos visitan.

Compatibilidad con WP-Cache

Para los que usamos WP-Cache nos encontramos con el problema de que usar diferentes plantillas dinámicamente no funciona correctamente con el caché activo, hará que la página se guarde de acuerdo al visitante con el cual se generado; los siguientes visitantes verán la misma versión que el primero.

A pesar de que el autor de WPtouch ofrece una versión modificada de WP-Cache que debería corregir esto, no funciona. Si una página ya está guardada en caché con la versión «normal», todos verán esta versión sin importar que agente usen.

Nosotros decidimos modificar WP-Cache para que detecte que agente se está usando y decida se mostrará o no la página en cache, una modificación a wp-cache-phase1.php resuelve esto:

global $cache_rejected_user_agent;
if ( function_exists('apache_request_headers') ) {
	$headers = apache_request_headers();
	if ( isset($headers["User-Agent"]) ) {
		foreach ($cache_rejected_user_agent as $expr) {
			if ( strlen($expr) > 0 && stristr($headers["User-Agent"], $expr))
				return; // sale por completo de wp-cache
		}
	}
}

$cache_rejected_user_agent (definido en wp-cache-config.php) es un array con los nombres de los agentes móviles que deseamos no vean ninguna página en caché, y pase el control hacia WordPress. Como nuestro tráfico desde estos agentes es muy poco, no representa mayor esfuerzo para el servidor. El día que dicho trafico nos genere problemas, la mejor opción será especificar un directorio diferente para cada plantilla que usemos (controlado por $cache_path).

Bonus: Usar un dominio diferente al principal

Si han entrado a maestrosdelweb.com desde un móvil, verán que son redirigidos hacia maestrosdelweb.mobi, lo hicimos para darle algo de movimiento a dicho dominio y cumplir el propósito del TLD.

El primer paso es indicarle a WordPress (en el wp-config.php) que use un dominio diferente al configurado en la base de datos, según la petición:

if ( $_SERVER['HTTP_HOST'] == 'maestrosdelweb.mobi' || $_SERVER['HTTP_HOST'] == 'www.maestrosdelweb.mobi' ) {
	define('WP_HOME', 'http://maestrosdelweb.mobi');
	define('WP_SITEURL', 'http://maestrosdelweb.mobi');
}

(más detalles sobre estas variables en el Codex de WordPress)

Hecho eso, agregamos a la función detectAppleMobile() de wptouch.php otra condición para redirigir los móviles hacia el dominio .mobi:

if ( ($_SERVER['HTTP_HOST'] == 'maestrosdelweb.com' || $_SERVER['HTTP_HOST'] == 'www.maestrosdelweb.com') && $this->applemobile) {
		header('Location: http://maestrosdelweb.mobi'.$_SERVER['REQUEST_URI'] );
		die;
	}

Obviamente ya debimos haber detectado si es un agente móvil o no, con los ciclos mencionados al inicio de este post. Por último necesitamos redirigir cualquiera que esté entrando al dominio .mobi y que no sea desde uno de los agentes móviles. Esto lo hacemos en wp-cache-phase1.php justo después del ciclo mencionando anteriormente para wp-cache:

if ( ($_SERVER['HTTP_HOST'] == 'maestrosdelweb.mobi' || $_SERVER['HTTP_HOST'] == 'www.maestrosdelweb.mobi') ) {
		header('Location: http://www.maestrosdelweb.com'.$_SERVER['REQUEST_URI'],true,301);
		die;
}

Y con esto nuestro hack para el cambio de dominio estará listo.

Nos gustaría compartirles la versión final del plugin, ya combinada con MobilePress, pero dado que hicimos algunas personalizaciones a medida y es complicado mantener actualizaciones dependiendo de un tercero; preferimos contarles la historia completa de como reproducir ese cambio. A lo mejor alguien se anima a mantener dicha mezcla de plugins 😉