Ejemplo de web adaptada a moviles

De KumbiaPHP Framework Wiki

INTRODUCCION

A continuacion voy a poner un ejemplo de como adaptar nuestra web (o parte de ella) a smartphones como iPhone o basados en Android, gracias al MVC de KumbiaPHP.

Veremos dos formas distintas de hacer el acceso a nuestra web movil:

  • usando un subdominio. Ejemplo: Si se quiere acceder a la web adaptada, se accede a http://m.example.com
  • usando la detección del navegador. En este caso, se detecta el navegador/sistema operativo del cliente y se le muestra la web adaptada.

Personalmente prefiero la primera pero como hay quien prefiere la segunda, he creado una librería que nos permita utilizar ambas.

IMPORTANTE: El siguiente código es para Spirit Beta1, que como sabeis es suficiente estable como para desarrollar aplicaciones con ella. En Spirit Beta2 este ejemplo NO SIRVE.


PUNTO DE PARTIDA

Partimos de una aplicacion muy simple en la que se muestra un mensaje junto con la fecha y hora. Espero no haber pecado de simpleza.

/app/controllers/test_controller.php

<?php
class TestController extends ApplicationController
{
  public function index()
  {
    $this->mensaje = "Este mensaje se recibe desde el metodo ".$this->action_name." del controller ".$this->controller_name;
    $this->hora = date('Y-m-d'); 
  }
}

/app/views/templates/default.phtml

<html>
  <head>
    <title>Plantilla por defecto</title>
  </head>

  <body>
    <h1>Contenido</h1>
    <?php View::Content(); ?>
  </body>
</html>

/app/views/test/index.phtml

<p>Mensaje: <?php echo $mensaje; ?></p>
<p>Hora: <?php echo $hora; ?></p>


PREPARANDO LOS CAMBIOS

Bien, lo primero que necesitamos para nuestra "web reducida" es una plantilla distinta. En nuestro caso de ejemplo será simple: he cambiado el color de fondo, quitado el H1 y ajustado el viewport.

/app/views/templates/mobile.phtml

<html>
  <head>
    <title>Plantilla por defecto para movil</title>
  </head>

  <body bgcolor="gray">
    <b>Contenido</b>
    <?php View::Content(); ?>
  </body>
</html>


Ahora, hay que crear una vista distinta para el método index. Esta vista será la que se muestre junto con la plantilla adecuada. Para esto, vamos a crear una subcarpeta llamada mobile dentro de la carpeta de vistas del controller. En esta carpeta se deben ir metiendo las vistas de cada método igual que hacemos siempre, pero sólo de las versiones reducidas.

/app/views/test/mobile/index.phtml

<b>Mensaje:</b> <?php echo $mensaje; ?><br />
<b>Hora:</b> <?php echo $hora; ?> 
<i>Esta pagina esta optimizada para dispositivos moviles</i>


LIBRERIA AUXILIAR

He creado una librería auxiliar, que nos ayudará con la detección del dispositivo de dos formas distintas: en base a la URL o en base a la detección del navegador.

/app/libs/mobile.php

<?php
class Mobile {
	public static function mobileURL() {
		// Lista de URLs
		$mobile_urls = array( "m.example.com", "mobile.example.com" );

		// Se busca el dominio en el array
	    	return in_array(strtolower($_SERVER['HTTP_HOST']), $mobile_urls);	
	}

	public static function mobileBrowser() {
		$mobile_browser = '0';

		//$_SERVER['HTTP_USER_AGENT'] -> el agente de usuario que está accediendo a la página.
		if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone)/i',strtolower($_SERVER['HTTP_USER_AGENT']))) {
		    $mobile_browser++;
		}

		//$_SERVER['HTTP_ACCEPT'] -> Indica los tipos MIME que el cliente puede recibir. 
		if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')>0) or
		    ((isset($_SERVER['HTTP_X_WAP_PROFILE']) or isset($_SERVER['HTTP_PROFILE'])))) {
		    $mobile_browser++;
		}

		$mobile_ua = strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
		$mobile_agents = array(
		    'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
		    'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
		    'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
		    'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
		    'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
		    'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
		    'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
		    'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
		    'wapr','webc','winw','winw','xda','xda-');

		//buscar agentes en el array de agentes
		if(in_array($mobile_ua, $mobile_agents)) {
		    $mobile_browser++;
		}

		//$_SERVER['ALL_HTTP'] -> Todas las cabeceras HTTP
		if(strpos(strtolower($_SERVER['ALL_HTTP']),'OperaMini')>0) {
		    $mobile_browser++;
		}
		if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0) {
		    $mobile_browser=0;
		}

		return $mobile_browser;
	}
}
?>


CAMBIANDO EL CONTROLLER

Ya tenemos nuestra aplicacion, nuestra plantilla y vista adaptadas, y la librería que nos permite detectar el navegador y/o la URL de acceso. Solo nos queda juntar las piezas.

Primero, vamos a hacer el ejemplo con detección por subdomínio, que es la más fácil de probar desde nuestro ordenador. Lo que haremos sera cargar la librería Mobile y preguntar al método mobileURL. Si el resultado es positivo, cambiaremos el template y la vista usando los métodos de KumbiaPHP.

Para cambiar el template, lo que tenemos que hacer es cambiar el atributo template y decirle al controller que utilice el conjunto de vistas mobile, es decir, todas aquellas que estan dentro de la subcarpeta /app/views/test/mobile.

Dejamos el controlador así:

/app/controllers/test_controller.php

<?php
class TestController extends ApplicationController {
  public function index() {
    $this->mensaje = "Este mensaje se recibe desde el metodo ".$this->action_name." del controller ".$this->controller_name;
    $this->hora = date('Y-m-d'); 
  
    // Si la URL de acceso es "mobile", cargamos la plantilla/vista adecuada
    Load::lib("mobile");
    if (Mobile::mobileURL()) {
      $this->template="mobile";
      $this->set_response("mobile");
    }
}

Ahora, podemos visitar nuestra app, en su URL normal http://example.com, así como en la web reducida http://m.example.com para ver las diferencias. Recomiendo hacer la visita desde un smartphone para ver la diferencia en poner el <meta> del viewport y sin él.

Si somos de los que preferimos hacer la detección del navegador y obligar al usuario a que vea ese tipo de web, solo tenemos que cambiar el método al que preguntamos de la librería Mobile:

Dejamos el controlador así:

/app/controllers/test_controller.php

<?php
class TestController extends ApplicationController {
  public function index() {
    $this->mensaje = "Este mensaje se recibe desde el metodo ".$this->action_name." del controller ".$this->controller_name;
    $this->hora = date('Y-m-d'); 
  
    // Si la URL de acceso es "mobile", cargamos la plantilla/vista adecuada
    Load::lib("mobile");
    if (Mobile::mobileBrowser()) {
      $this->template="mobile";
      $this->set_response("mobile");
    }
}


CONCLUSIONES

Como se ha visto, hemos creado una plantilla y una vista alternativas para un método bien simple, las cuales son usadas para ofrecer una vista distinta de nuestra aplicacion web. Nos hemos apoyado en una librería externa para hacer la detección, con lo que también hemos visto la forma de incluir nuestras propias librerías y extender funcionalidades.

A modo de resumen de lo visto:

  • Crear y usar librerías externas a nuestra aplicacion web.
  • Trabajar con los métodos set_response() y el atributo template para cambiar nuestra vista


Espero que el ejemplo haya servido de base para hacer algo más grance.


Saludos, Soukron