Artículos de la categoría Tutoriales

Diseñando nuestra web para el iPhone – Parte 3

Nota: Esta es la tercera parte del tutorial Diseñando nuestra web para el iPhone. Si no has leído las partes anteriores, es muy recomendable que lo hagas, comenzando por la primera. También os aviso de que si bien voy a explicar cómo diseñar para el iPhone, para comprender estos tutoriales son necesarios unos mínimos conocimientos de HTML y CSS, siendo recomendable tener alguna idea de Javascript (tampoco es necesario ser experto, ya que yo mismo soy un novato).

En esta parte me centraré por completo en el diseño de las cabeceras, aprovechando algunos atributos CSS únicos de Webkit que nos facilitarán tareas como redondear esquinas y crear degradados. Si recordáis dónde nos quedamos en la parte anterior, llegamos a ver diferentes ejemplos de cabeceras, de las cuales nos centraríamos en las que utilizan un sistema de navegación por pestañas y en las que imitan la interfaz de las aplicaciones nativas del iPhone.

Creando una cabecera con degradados y pestañas

Comenzaremos por la cabecera con degradados y pestañas. Yo seguiré el modelo de Yahoo, que podéis en la imagen de la izquierda. Podría haber seguido el modelo de Google, pero me parecía más simple y fácil de hacer.

La cabecera está formada por tres niveles diferentes. En el primero está el logotipo y un enlace hacia el correo, en el segundo están las pestañas y en el tercero está el buscador. Puede que no tengamos clara la utilidad del tercer nivel fuera de un buscador, pero realmente puede ser muy útil. Por ejemplo, podemos mostrar ahí las subpáginas que hay dentro de la pestaña, o si estamos diseñando para un blog, la lista de categorías del artículo, o simplemente, un buscador.

Así que en principio la cabecerá tendrá la siguiente estructura HTML:

<div id="header">
		<div id="logo_container">
			<!-- Aquí estará el logo -->
		</div>
		<div id="menu_container">
			<!-- Aquí estarán las pestañas -->
		</div>
		<div id="subheader">
			<!-- Aquí estará el buscador -->
		</div>
	</div>

Dicho esto, centrémonos en crear los degradados. Generalmente tendríamos que recurrir a imágenes, sin embargo, Webkit permite crear degradados mediante -webkit-gradient. Su sintaxis puede parecer algo compleja, así que veámosla con un ejemplo:

background: -webkit-gradient(linear, left top, left bottom, from(#FFF), to(#000));

Cada coma (,) separa un valor diferente. El primero indica de si se trata de un degradado lineal o radial. En este caso tomaremos el linela. El segundo valor indica la posición desde la que comienza: a la izquierda y arriba. El tercer valor indica dónde acaba: a la izquierda y abajo. El cuarto valor indica el color inicial: blanco. El quinto y último valor indica el color en el que acaba: negro. También podemos establecer colores intermedios, pero es algo más complejo.

Esto nos evita tener que crear una imagen con el degradado y agiliza la carga de la página.

Para crear las esquinas curvas, recurriremos a -webkit-border-radius para establecer un radio a todas las esquinas y -webkit-border-(top | bottom)-(left | right)-radius para especificar qué esquinas tendrán cierto radio.

#redondear_bordes {
-webkit-border-radius:4px; /* Todas las esquinas tendrán un radio de 4px */
-webkit-border-top-left-radius:4px; /* Sólo la esquina superior izquierda tendrá un radio de 4px */
-webkit-border-top-right-radius:4px; /* Sólo la esquina superior derecha tendrá un radio de 4px */
-webkit-border-bottom-left-radius:4px; /* Sólo la esquina inferior izquierda tendrá un radio de 4px */
-webkit-border-bottom-right-radius:4px; /* Sólo la esquina inferior derecha tendrá un radio de 4px */
}

Combinando esto con algo más de CSS e ingenio podemos lograr sin mucha dificultad algo como lo de la imagen que hay a continuación, que se crearía a partir del siguiente código HTML / CSS:

	<div id="header">
		<div id="logo_container">
			<!-- Aquí estará el logo -->
			<h1>Miweb.com</h1>
		</div>
		<div id="menu_container">
			<!-- Aquí estarán las pestañas -->
			<ul id="menu">
				<li class="selected"><a href="#">Inicio</a></li>
				<li><a href="#">Artículos</a></li>
				<li><a href="#">Páginas</a></li>
			</ul>
		</div>
		<div id="subheader">
			<!-- Aquí estará el buscador -->
		</div>
	</div>
body, div, h1 {  /* Reseteamos algunos estilos para que se ajuste correctamente el contenido */
	margin:0;
	padding:0;
}

#header {
	width:100%;
	height:150px;
background: -webkit-gradient(linear, left top, left bottom, f rom(#75B856), to(#4C7A06));
}

#logo_container {
	width:100%;
	height:50px;
}

#logo_container h1 {
	padding:8px;
	font-family:Helvetica;
	font-size:30px;
	color:#FFF;
}

#menu_container {
	width:100%;
	height:50px;
}

#menu {
	width:100%;
	height:50px;
	padding:0;
	margin:0;
	list-style:none;
}

#menu li {
	height:38px;
	margin:2px 5px 0 5px;
	padding:5px;
	float:left;
}

#menu li a {
	height:28px;
	padding:5px;
	font-family:Helvetica;
	font-size:20px;
	color:#FFF;
	text-decoration:none;
	font-weight:bold;
	display:block;
}

#menu li.selected {
	background: -webkit-gradient(linear, left top, left bottom, f rom(#FFF), to(#FEFEFE));
	-webkit-border-top-left-radius:6px;
	-webkit-border-top-right-radius:6px;
}

#menu li.selected a {
	color:#000;
}

#subheader {
	width:100%;
	height:50px;
	background: -webkit-gradient(linear, left top, left bottom, f rom(#FEFEFE), to(#C0C0C0));
	border-bottom:1px solid #666;
}

Nota: He usado varias veces la palabra “f rom” en el código anterior. En realidad debería escribirse todo junto (sin el espacio entre la “f” y “rom”), pero no he podido unirlo y guardar el artículo, WordPress me devuelve un error. En fin, disculpad las molestias.

Como podéis ver, el resultado es muy similar al de Yahoo, aunque no he añadido el buscador, eso os lo dejo a vosotros.

Creando una cabecera que imite la de una aplicación nativa

El segundo tipo de cabeceras que vimos eran las que imitaban la barra de título de una aplicación nativa. Esta vez partiremos del diseño de Coosh, que podéis ver en la imagen de la izquierda.

Si bien Coosh trata de imitar la interfaz de una aplicación, lo cierto es que la barra de título está incompleta, faltan el título y el enlace hacia la siguiente página.

Así que partiremos de una estructura con un nivel y tres elementos: botón anterior, botón posterior y título de la página, que en HTML quedaría así:

<div id="header">
		<div id="back">
			<!-- Aquí estará el enlace hacia la página anterior -->
			<a href="#">Atr&aacute;s</a>
		</div>
		<div id="forward">
			<!-- Aquí estará el enlace hacia la siguiente página -->
			<a href="#">Adelante</a>
		</div>
		<div id="title">
			<!-- Aquí estará el título de la página -->
			<h1>Miweb.com</h1>
		</div>
	</div>

Bien, ahora mediante combinación de degradados y bordes curvos podemos imitar la interfaz de una aplicación sin demasiada dificultad y sin usar imágenes. Podríamos mejorar el aspecto mediante el uso de imágenes, pero estamos hablando de aprovechar al máximo las posibilidades del iPhone, así que las dejaremos para más adelante.

El resultado que podemos lograr lo tenéis a continuación, junto con el código CSS que lo logra.

body, div, h1 {  /* Reseteamos algunos estilos para que se ajuste correctamente el contenido */
	margin:0;
	padding:0;
}

#header {
	height:30px; /* Tomaremos una altura aceptable */
	padding:4px;
	background: -webkit-gradient(linear, left top, left bottom, f rom(#BEC8D6), to(#7A90AD));
	border-bottom:1px solid #6F7A86;
	clear:both;
}

#back {
	height:20px;
	margin:0 10px 0 0;
	padding:4px;
	float:left;
	border:1px solid #626C79;
	-webkit-border-radius:6px;
	background: -webkit-gradient(linear, left top, left bottom, f rom(#9AADC6), to(#5C7DA9), color-stop(0.5, #6584AD), color-stop(0.5, #5C7DA9));
}

#back a , #forward a{
	font-family:Helvetica;
	font-size:15px;
	font-weight:bold;
	text-decoration:none;
	text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.6);
	text-align:center;
	white-space: nowrap;
	color:#FFF;
}

#forward {
	height:20px;
	margin:0 0 0 10px;
	padding:4px;
	float:right;
	border:1px solid #626C79;
	-webkit-border-radius:6px;
	background: -webkit-gradient(linear, left top, left bottom, f rom(#9AADC6), to(#5C7DA9), color-stop(0.5, #6584AD), color-stop(0.5, #5C7DA9));
}

#title h1 {
	font-family:Helvetica;
	font-size:26px;
	font-weight:bold;
	text-decoration:none;
	text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.6);
	text-align:center;
	white-space: nowrap;
	color:#FFF;
}

Nota: Como antes, he usado varias veces la palabra “f rom” en el código anterior. En realidad debería escribirse todo junto (sin el espacio entre la “f” y “rom”), pero no he podido unirlo y guardar el artículo, WordPress me devuelve un error. En fin, disculpad las molestias.

Con esto ya podemos crear dos tipos diferentes de cabeceras, que era el objetivo de esta tercera parte. Como siempre, cualquier duda, sugerencia o pregunta, podéis hacerla en los comentarios.

2 Comentarios

Diseñando nuestra web para el iPhone – Parte 2

Nota: Esta es la segunda parte del tutorial Diseñando nuestra web para el iPhone. Si no has leído las partes anteriores, es muy recomendable que lo hagas, comenzando por la primera. También os aviso de que si bien voy a explicar cómo diseñar para el iPhone, para comprender estos tutoriales son necesarios unos mínimos conocimientos de HTML y CSS, siendo recomendable tener alguna idea de Javascript (tampoco es necesario ser experto, ya que yo mismo soy un novato).

En esta segunda parte nos centraremos en las medidas que debe tener nuestro diseño, detectar rotaciones (giros a la derecha o a la izquierda), definir un icono para nuestra web, personalizar el zoom máximo y daré unas pinceladas sobre la cabecera. Para ello revisaremos algunas páginas diseñadas específicamente para el iPhone, como Yahoo y Google (versión iPhone), deviantART, Coosh o Please fix the iPhone.

Medidas

Medidas de Safari en el iPhone

Medidas

Medidas de Safari en el iPhone (apaisado)

Medidas en horizontal

Vayamos por partes. Antes de comenzar a hacer nada debemos tener claro el tamaño que tendrá el diseño. En la imagen de la izquierda podéis ver las medidas de los diferentes contenidos que muestra el iPhone: la barra de estado (está siempre visible, tiene 20px de alto y ocupa siempre todo el espacio horizontal de la pantalla), el campo de la URL (se oculta al hacer scroll hacia debajo, ocupa todo lo posible en el eje horizontal y 60px en el vertical), la barra de botones (al igual que la barra de estado, no se puede ocultar, ocupa 44px en la vertical y todo lo posible en la horizontal), lo cual deja un espacio de 320px x 356px de contenido propio de la página (320 en el eje horizontal y 356 en el vertical).

Si colocamos el iPhone en posición horizontal (apaisado), algunas medidas variarán (ver imagen de la derecha): la barra de estado y el campo de la URL permanecen como antes, mientras que la barra de botones para a ocupar sólo 32px en el eje vertical, con lo cual el contenido visible ocupa un espacio de 480px x 208px.

Cuando se diseña una web suele ser necesario tener en cuenta las diversas resoluciones de pantalla en las que se visualizará la página, sin embargo una de las cosas buenas para los diseñadores (y en algunos casos malas para los usuarios) es que la resolución es fija, así que basta con diseñar específicamente para estas medidas: nuestro diseño sólo se verá en un dispositivo un determinado navegador y una resolución de pantalla de 320px x 480px.

Detectando los giros, asignando icono y personalizando zoom

Al poderse girar el iPhone hay dos posibilidades: que se esté visualizando la página con el dispositivo en vertical o que se visualice con el iPhone en horizontal, lo cual hace que sea necesario detectar estos giros para poder mostrar u ocultar cierto contenido en cada caso.

Por ejemplo, si queremos que en la versión horizontal se vea algo más de contenido en los laterales (por aprovechar el espacio), será necesario detectar el cambio de posición y ajustar el diseño en consecuencia. Otro caso en el que necesitemos saber si se ha producido un giro es en el caso de los formularios: un campo de texto se puede alargar cuando el iPhone está en posición horizontal y se debe acortar cuando está en posición vertical, pura lógica.

Parar ello recurriremos a Javascript, con el cual podemos detectar fácilmente estos giros.

function updateOrientation()
{
	switch(window.orientation)
	{
		case 0:
			tamanio_cuadro_texto = "200px";
			tamanio_contenedor_a = "150px";
			break;
		case -90:
			tamanio_cuadro_texto = "360px";
			tamanio_contenedor_a = "300px";
			break;
		case 90:
			tamanio_cuadro_texto = "360px";
			tamanio_contenedor_a = "300px";
			break;
		case 180:
			tamanio_cuadro_texto = "200px";
			tamanio_contenedor_a = "150px";
			break;
		default:
			tamanio_cuadro_texto = "200px";
			tamanio_contenedor_a = "150px";
			break;
	}
	document.getElementById("cuadro_texto_1").style.width =  tamanio_cuadro_texto;
	document.getElementById("a").style.width =  tamanio_contenedor_a;
}

Es un código bastante sencillo, que se puede ampliar mucho más (el de arriba es sólo un pequeño ejemplo). Para hacer que funcione del todo tendremos que modificar la etiqueta body de nuestro HTML y añadirle los atributos onorientationchange y onLoad, que nos asegurarán que cada vez que se cargue la página o se cambie la orientación, se cambiará el tamaño por el adecuado (definido antes en el código Javascript), quedando así nuestra etiqueta body:

<body onorientationchange="updateOrientation();" onLoad="updateOrientation();">

Otro punto interesante para hacer única nuestra página web es asignarle un icono. En principio el iPhone no muestra ningún favicon en el navegador, pero al añadir un enlace a una web en la página de inicio, podemos indicarle al navegador que tome como icono una imagen específica, en lugar de una previsualización de la página web (que es lo que toma por defecto). Para esto usaremos la etiqueta link con el atributo rel establecido en apple-touch-icon:

<link rel="apple-touch-icon" href="http://10.0.1.3:8888/sumolari/wp-content/themes/sumolari/ipo/img/favicon.png"/>

Este icono debe ser una imagen con un tamaño cuadrado. No es necesario que le añadamos bordes curvos ni el toque luminoso, ya que los hará el iPhone directamente.

Por último, el iPhone permite hacer zoom en las páginas, sin embargo, como estamos diseñando específicamente para él, nos interesa mantenerlo bloqueado y ser nosotros quienes definamos el tamaño de las textos y los elementos. Con esto también logramos darle a la web un aspecto más similar al de una aplicación nativa. Para bloquear el zoom usaremos el meta-tag viewport, como en el siguiente ejemplo:

<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>

Si os fijáis, este meta-tag define varias cosas, como la anchura máxima (width – recordad que una cosa es hacer scroll vertical, cosa que ocurre muy a menudo en equipos tanto sobremesa como móviles, y otra hacer scroll vertical: queda mucho más “profesional” e integrado en la plataforma el que la web tenga scroll vertical pero carezca de horizontal, probadlo vosotros mismos y veréis como notáis el cambio), la escala inicial (initial-scale), la escala máxima (maximum-scale) y la posibilidad de escalar por parte del usuario (user-scalable).

Cabeceras

Ya llegamos a lo que es el diseño en sí. Este apartado lo completaré en la próxima parte, ya que hay bastantes cosas que explicar y me gustaría dejarles una parte sólo a ellas. Para adentrarnos en el tema de las cabeceras me gustaría proponeros 5 páginas diseñadas para el iPhone como ejemplo de diseños.

Como podéis ver, las 5 páginas se ajustan al tamaño horizontal del iPhone (que no al vertical). Las tres primeras páginas comparten el uso de pestañas, mientras que las dos últimas no hacen uso de ellas. La tercera página junto con la quinta intentan simular el aspecto de una aplicación nativa (usando parte del contenido visible para mostrar una barra de título similar a las de las aplicaciones nativas), mientras que la cuarta página utiliza un diseño más propio, siguiendo las líneas que utiliza el iPhone pero no intentando imitar tanto.

Así que deberemos decantarnos por un tipo de cabecera: con pestañas, simulando un aplicación nativa o que tenga un toque personal. A mí, de las que he visto hasta ahora, la que más me gusta es la de Yahoo. Creo que han dado en el clavo al mezclar un toque personal con el sistema de pestañas y la imitación (en parte) de la barra de título de una aplicación nativa.

Pero bueno, esto es todo por ahora. En la próxima parte me centraré por completo en lograr resultados parecidos a los de los ejemplos, es decir, me centraré en crear una cabecera con pestañas y una que simule la barra de título de una aplicación nativa.

Un comentario

Diseñando nuestra web para el iPhone – Parte 1

El iPhone y el iPod Touch disponen de un navegador realmente bueno para tratarse de dispositivos móviles. Mobile Safari muestra las páginas web prácticamente igual que lo haría su versión de escritorio, lo que hace que en muchos casos no sea necesario hacer un diseño específico de nuestra web para estos dispositivos.

Sin embargo, el tamaño de la pantalla del iPhone y del iPod Touch (a partir de ahora hablaremos sólo de iPhone para abreviar) hace que se nos haga incómodo navegar, teniendo que hacer zoom en múltiples ocasiones, lo que entorpece bastante la navegación. Afortunadamente, adaptar nuestra página web al iPhone es una tarea relativamente sencilla y gracias a Mobile Safari podemos lograr hacer que nuestra web tenga el aspecto de una aplicación nativa del iPhone.

Como podréis adivinar por el título, el tutorial está dividido en partes (que iré redactando poco a poco y publicando una vez las haya acabado de escribir). Esta primera parte la dedicaré a explicar cómo preparar nuestro entorno de desarrollo.

Servidor local

Antes de ponernos a diseñar necesitaremos instalar un servidor en nuestro equipo. Hay muchas opciones, sin embargo yo me quedaría con Apache + MySQL + PHP (conocido como WAMP, MAMP o LAMP, dependiendo de si se utiliza Windows, Mac o Linux).

En Windows solía usar WampServer, una aplicación gratuita y fácil de instalar y administrar, y ahora en Mac utilizo la versión gratuita de Mamp. Como hace tiempo que no toco Linux, lo dejaré de lado en este tutorial. De todos modos, más adelante veréis que algunas de las herramientas útiles para comprobar nuestro diseño no están disponibles para Linux (algunas ni siquiera para Windows).

Una vez instalado el servidor, basta con que accedamos a localhost, 127.0.0.1 o nuestra dirección IP. Los tres métodos deberían mostrarnos exactamente lo mismo.

Mobile Safari

Configurando Safari

Configurando Safari

Ya tenemos el servidor local, con lo que podemos trabajar con MySQL y PHP y si nuestro CMS está escrito en PHP, podremos instalarlo en nuestro servidor local y diseñar directamente para él (yo, por ejemplo, suelo diseñar directamente para WordPress). Ahora necesitamos un navegador que funcione de forma similar a Mobile Safari para comprobar nuestro trabajo, y para ello tenemos 3 opciones diferentes.

Si disponemos de un iPhone lo tenemos muy fácil. En la barra de direcciones basta con introducir la IP de nuestro equipo servidor y listo. Recordad que ambos dispositivos deben estar en la misma red.

En caso de que no dispongamos de un iPhone pero sí de un Mac, tenemos la opción de hacernos desarrolladores para el iPhone, con lo cual tendremos acceso al iPhone Simulator, un simulador del iPhone que, adivinad… tiene Mobile Safari, con lo que podremos probar nuestros diseños en una simulación del iPhone. No es una opción demasiado interesante si no somos desarrolladores, pero si ya lo somos, siempre tenemos la posibilidad de usar el simulador para probar páginas web en lugar de aplicaciones.

Por último, tenemos la opción de usar Safari cambiando el agente de usuario por el del iPhone. Esto es algo que se puede hacer también en otros navegadores, sin embargo como Safari y Mobile Safari parten del mismo motor de renderizado, es más conveniente usar estos, ya que así nos aseguramos de que lo que vemos durante las pruebas es lo más parecido al resultado final.

Un diseño sólo para iPhone

Bien, ahora ya podemos comenzar a diseñar para el iPhone y lo primero que deberíamos hacer es asegurarnos de que nuestro diseño especial sólo se use en el iPhone. Para ello recurriremos al tutorial que publiqué la semana pasada sobre cómo detectar navegadores mediante PHP. De momento nuestro diseño podría comenzar así:

function is_browser($name, $version='') {
	$user_agent = $_SERVER['HTTP_USER_AGENT']; // Cargamos el UserAgent en una variable
	$wtr = false; // Esta variable es la que indica si se ha accedido con el navegador que buscamos o no. Por defecto es false, sólo cambia si se accede con el navegador buscado
	$wtmb = ''; // Esta variable almacena el navegador del dispositivo móvil (sólo si buscamos un navegador de dispositivo móvil, esto no incluye ni Android ni iPod ni iPhone)
	// Primero veamos a quién buscamos y luego comprobemos si es él
	switch ($name) {
		// Caso Internet Explorer
		case 'IE':
			if (strrpos($user_agent, "MSIE") === false) {} else {
				if ($version != '') {
					if (strrpos($user_agent, 'MSIE '.$version) === false) {} else { $wtr = true; }
				} else {
					$wtr = true;
				}
			}
			break;
		// Caso Firefox
		case 'FF': if (strrpos($user_agent, "Firefox") === false) {} else { $wtr = true; } break;
		// Caso Opera
		case 'OP': if (strrpos($user_agent, "Opera") === false) {} else { $wtr = true; } break;
		// Caso Konqueror
		case 'KQ': if (strrpos($user_agent, "Konqueror") === false) {} else { $wtr = true; } break;
		// Caso Chrome
		case 'CH': if (strrpos($user_agent, "Chrome") === false) {} else { $wtr = true; } break;
		// Caso Safari
		case 'SF': if (strrpos($user_agent, "Safari") === false) {} else { $wtr = true; } break;
		// Caso iPod
		case 'IPD': if (strrpos($user_agent, "iPod") === false) {} else { $wtr = true; } break;
		// Caso iPhone
		case 'IPH': if (strrpos($user_agent, "iPhone") === false) {} else { $wtr = true; } break;
		// Caso iPod o iPhone
		case 'IPO':
			if (strrpos($user_agent, "iPod") === false) {} else { $wtr = true; }
			if (strrpos($user_agent, "iPhone") === false) {} else { $wtr = true; }
			break;
		// Caso Android
		case 'AD': if (strrpos($user_agent, "Android") === false) {} else { $wtr = true; } break;
		// Caso navegador móvil
		case 'MB':
			$mua = array(
				'PIE4' => 'compatible; MSIE 4.01; Windows CE; PPC; 240x320',
				'PIE4_Smartphone' => 'compatible; MSIE 4.01; Windows CE; Smartphone;',
				'PIE6' => 'compatible; MSIE 6.0; Windows CE;',
				'Minimo' => 'Minimo',
				'OperaMini' => 'Minimo',
				'AvantGo' => 'AvantGo',
				'Plucker' => 'Plucker',
				'NetFront' => 'NetFront',
				'SonyEricsson' => 'SonyEricsson',
				'Nokia' => 'Nokia',
				'Motorola' => 'mot-',
				'BlackBerry' => 'BlackBerry',
				'WindowsMobile' => 'Windows CE',
				'PPC' => 'PPC',
				'PDA' => 'PDA',
				'Smartphone' => 'Smartphone',
				'Palm' => 'Palm'
			);
			foreach($mua as $nav => $ua){ if(strstr($user_agent, $ua) != false) { $wtmb = $nav; } }
			if ($wtmb != '') { $wtr = true; }
			break;
		// Caso genérico
		default: $wtr = false; break;
	}
	return $wtr;
}

if (is_browser('IPO')) {
/* Diseño especial para el iPhone / iPod Touch */
} else {
/* Diseño general para el resto de navegadores */
}

Y esto es todo de momento.

Más adelante…

En las próximas partes comenzaremos a diseñar para el iPhone. Explicaré desde cómo aprovechar las posibilidades de Mobile Safari para ahorrarnos trabajo (por ejemplo, creando degradados con CSS en lugar de con imágenes) hasta qué medidas usar, cómo detectar rotaciones del dispositivo (si está en vertical u horizontal)… en resumen, cómo simular la interfaz de una aplicación.

Eso sí, habrá unas cuantas partes más. En principio no tengo decidido cuántas habrá en total (ya he comentado al principio que no las tengo escritas), así que podéis pedir en los comentarios que me centre en alguna cosa en especial.

Un comentario

Conocer la versión que se usa del CMS de un sitio web es algo muy útil para los hackers, ya que sabiendo este dato pueden revisar los cambios que hay entre dicha versión y las siguientes, con lo que pueden saber las vulnerabilidades que presenta la página en pocos minutos.

Por defecto WordPress muestra este número en varios sitios, y en AyudaWordPress han publicado un pequeño código que lo oculta de cualquier lugar donde aparezca. El código es bastante simple, y aplica un filtro a la función que muestra el número de la versión, no devolviendo nada en lugar de devolver el contenido filtrado.

Añadiendo este código al archivo functions.php de nuestro theme, ocultaremos el número de la versión y haremos nuestro blog más seguro. Desde luego, la solución es increíblemente senzilla e inteligente :) .

//Elimina referencias a la version de WordPress
function quitar_version_wp() {
return '';
}
add_filter('the_generator', 'quitar_version_wp');
No hay comentarios

Detectando navegadores con PHP

Saber el navegador con el que se accede a nuestras páginas web es algo muy útil. Lo podemos utilizar para cargar algo de CSS / Javascript específico para un navegador (como por ejemplo, para evitar errores con IE6), también lo podemos usar para cargar una página completamente distinta en navegadores antiguos y, ¿por qué no? para mostrar una página específica para móviles.

Ya he comentado este tema en otras ocasiones, pero esta vez ampliaré el rango de navegadores a detectar, concretamente nos centraremos en Internet ExplorerFirefox, SafariOpera, Konqueror, Chrome, iPod Touch, iPhone, Android (vale, estos tres no son navegadores, pero en estos casos me refiero a detectar el sistema operativo) o cualquier tipo de navegador para móvil.

En esta ocasión crearemos una función que acepte dos parámetros: el navegador que queremos buscar y la versión específica que buscamos (si es que buscamos alguna versión en especial). Para el primer parámetro, usaremos una serie de identificadores:

Identificador Navegador
IE Internet Explorer
FF Firefox
SF Safari
OP Opera
KQ Konqueror
CH Chrome
IPD iPod
IPH iPhone
IPO iPod / iPhone
AD Android
MB Navegador de móvil

Sobre la versión del navegador, sólo nos centraremos en las versiones de Internet Explorer.

La función seguirá la siguiente estructura:

  1. Cargamos en una variable el agente de usuario del visitante.
  2. Mediante un bucle foreach determinamos en qué navegador buscamos.
  3. Mediante la función strrpos comprobamos si el agente de usuario se corresponde con el del navegador que buscamos.
  4. Sólo si buscamos Internet Explorer: Detectamos si se ha accedido con la versión que hemos establecido (si es que hemos establecido alguna versión).
  5. Sólo si buscamos un navegador móvil: Buscamos alguno de los diversos agentes de usuario que tienen los diferentes navegadores para móviles.
  6. Devolvemos el valor true si se ha detectado el navegador en cuestión y false si no se ha detectado, a través de una variable que tiene por defecto el valor false y sólo cambia a true al detectarse el navegador.

Finalmente todo esto traducido a PHP quedaría así:

	function is_browser($name, $version='') {
		$user_agent = $_SERVER['HTTP_USER_AGENT']; // Cargamos el UserAgent en una variable
		$wtr = false; // Esta variable es la que indica si se ha accedido con el navegador que buscamos o no. Por defecto es false, sólo cambia si se accede con el navegador buscado
		$wtmb = ''; // Esta variable almacena el navegador del dispositivo móvil (sólo si buscamos un navegador de dispositivo móvil, esto no incluye ni Android ni iPod ni iPhone)
		// Primero veamos a quién buscamos y luego comprobemos si es él
		switch ($name) {
			// Caso Internet Explorer
			case 'IE':
				if (strrpos($user_agent, "MSIE") === false) {} else {
					if ($version != '') {
						if (strrpos($user_agent, 'MSIE '.$version) === false) {} else { $wtr = true; }
					} else {
						$wtr = true;
					}
				}
				break;
			// Caso Firefox
			case 'FF': if (strrpos($user_agent, "Firefox") === false) {} else { $wtr = true; } break;
			// Caso Opera
			case 'OP': if (strrpos($user_agent, "Opera") === false) {} else { $wtr = true; } break;
			// Caso Konqueror
			case 'KQ': if (strrpos($user_agent, "Konqueror") === false) {} else { $wtr = true; } break;
			// Caso Chrome
			case 'CH': if (strrpos($user_agent, "Chrome") === false) {} else { $wtr = true; } break;
			// Caso Safari
			case 'SF': if (strrpos($user_agent, "Safari") === false) {} else { $wtr = true; } break;
			// Caso iPod
			case 'IPD': if (strrpos($user_agent, "iPod") === false) {} else { $wtr = true; } break;
			// Caso iPhone
			case 'IPH': if (strrpos($user_agent, "iPhone") === false) {} else { $wtr = true; } break;
			// Caso iPod o iPhone
			case 'IPO':
				if (strrpos($user_agent, "iPod") === false) {} else { $wtr = true; }
				if (strrpos($user_agent, "iPhone") === false) {} else { $wtr = true; }
				break;
			// Caso Android
			case 'AD': if (strrpos($user_agent, "Android") === false) {} else { $wtr = true; } break;
			// Caso navegador móvil
			case 'MB':
				$mua = array(
					'PIE4' => 'compatible; MSIE 4.01; Windows CE; PPC; 240x320',
					'PIE4_Smartphone' => 'compatible; MSIE 4.01; Windows CE; Smartphone;',
					'PIE6' => 'compatible; MSIE 6.0; Windows CE;',
					'Minimo' => 'Minimo',
					'OperaMini' => 'Minimo',
					'AvantGo' => 'AvantGo',
					'Plucker' => 'Plucker',
					'NetFront' => 'NetFront',
					'SonyEricsson' => 'SonyEricsson',
					'Nokia' => 'Nokia',
					'Motorola' => 'mot-',
					'BlackBerry' => 'BlackBerry',
					'WindowsMobile' => 'Windows CE',
					'PPC' => 'PPC',
					'PDA' => 'PDA',
					'Smartphone' => 'Smartphone',
					'Palm' => 'Palm'
				);
				foreach($mua as $nav => $ua){ if(strstr($user_agent, $ua) != false) { $wtmb = $nav; } }
				if ($wtmb != '') { $wtr = true; }
				break;
			// Caso genérico
			default: $wtr = false; break;
		}
		return $wtr;
	}

Finalmente el uso es muy sencillo, basta con verificar el valor que devuelve la función, de modo que si buscamos, por ejemplo, a Opera, usaríamos el siguiente código:

if (is_browser('OP')) {
/* Código específico para Opera */
} else {
/* Código para el resto de navegadores */
}
2 Comentarios

Haz que WordPress cargue los frameworks desde servidores externos

WordPress utiliza varios frameworks Javascript para hacer diversos efectos y mejorar a interfaz, además de que algunos themes se aprovechan de esto para añadir mejoras al diseño utilizando funciones que ofrecen estos frameworks. Recurrir a estos métodos ocasiona un aumento del tiempo de carga de la página y del ancho de banda consumido por el servidor al enviar los archivos solicitados al usuario, sin embargo, podemos hacer que WordPress cargue estos archivos desde servidores externos que nos reducen el ancho de banda gastado y que, en algunos casos, son más rápidos que nuestro servidor. Además, usar este método también nos permite cargar automáticamente la versión más actualizada de los diversos frameworks, evitando tener que volver a subir las nuevas versiones a nuestro servidor.

En este artículo me centraré en jQuery, jQuery UI y Prototype, los frameworks que utiliza actualmente Sumolari.com, pero antes de hacer que WordPress cargue los archivos desde servidores externos (usaremos los de Google), veremos primero el método general.

wp_deregister_script, wp_register_script y wp_enqueue_script

WordPress tiene varias funciones para gestionar el código Javascript que se carga en cada página. Esta funciones permiten, a grandes rasgos, añadir un script con un nombre identificatorio (del cual se definen la URL del archivo, las dependencias, la versión o incluso si se puede cargar en el pie de página o no), eliminarlo o cargarlo.

Para el primero de todos los usos, recurriremos a la función wp_register_script. Esta función tiene 5 parámetros: $handle, $src, $deps, $ver e $in_footer.

wp_register_script( $handle, $src, $deps, $ver, $in_footer );

La primera de todas debe contener el nombre identificatorio del script. Yo recomiendo usar nombres coherentes, así evitamos posibles problemas al usar muchos scripts y no distinguir unos de otros por su nombre.

El segundo parámetro de la función indica la URL del archivo a cargar. Tanto el primer parámetro como éste son obligatorios, los otros tres son opcionales y son, por orden de aparición, la matriz que indica las dependencias (estas dependencias se deben indicar usando el nombre identificatorio del script correspondiente), la versión del archivo a cargar (se utiliza para evitar problemas con la caché y demás, pero en muchos casos basta con dejarlo en blanco) y si el script se puede cargar al final de la página o no.

La función wp_deregister_script es la que elimina un script previamente registrado. Esto nos permitirá eliminar los script registrados por WordPress y añadir los nuestros modificados. El uso sería el siguiente:

wp_deregister_script( $handle );

La función wp_enqueue_script es la que le indica a WordPress que debe cargar cierto script. Admite los mismos parámetros que wp_register_script, sólo que en la primera, a diferencia de la segunda, el nombre identificatorio le indica a la función qué script debe cargar (ya que esta función no registra ningún script) y sólo usará los demás parámetros en caso de no existir el script solicitado.

El uso es el siguiente:

wp_enqueue_script( $handle ); // Mínimo
wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer ); // Parámetros opcionales

Tenéis más información sobre estas funciones en el Codex de WordPress.

Dicho lo cual ya podemos pasar a aplicar lo visto hasta ahora.

Cargando jQuery, jQuery UI y Prototype desde los servidores de Google

Una pequeña aclaración antes de comenzar: podemos cargar cualquier script de WordPress (lista completa) desde cualquier servidor, de hecho veréis como no es nada complicado hacerlo.

Los scripts están alojados en los servidores de Google, que ofrecen una buena velocidad y se actualizan con cada nueva versión. También almacenan versiones antiguas de los frameworks, con lo que podemos optar por cargar una versión actualizada, la última o una más antigua.

El proceso para cargar los scripts es el siguiente:

  1. Eliminamos (des-registramos) el script correspondiente a los frameworks jQuery, jQuery UI y Prototype de WordPress
  2. Registramos de nuevo los tres scripts anteriores, cambiando la URL de los archivos
  3. Cargamos los scripts recién registrados

Esto en código quedaría así:

// jQuery
		wp_deregister_script('jquery'); // Des-registramos jQuery
		wp_register_script('jquery', ("http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"), false, ''); // Registramos de nuevo jQuery, con la URL de la última versión del framework alojada en el servidor de Google
		wp_enqueue_script('jquery'); // Cargamos jQuery

		// jQuery-UI
		wp_deregister_script('jquery-ui-core'); // Des-registramos jQuery-UI
		wp_register_script('jquery-ui-core', ("http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"), false, ''); // Registramos de nuevo jQuery-UI, con la URL de la última versión del framework alojada en el servidor de Google
		wp_enqueue_script('jquery-ui-core'); // Cargamos jQuery-UI

		// Prototype
		wp_deregister_script('prototype'); // Des-registramos Prototye
		wp_register_script('prototype', ("http://ajax.googleapis.com/ajax/libs/prototype/1/prototype.js"), false, ''); // Registramos de nuevo Prototype, con la URL de la última versión del framework alojada en el servidor de Google
		wp_enqueue_script('prototype'); // Cargamos Prototype

Como veis, no tiene mucho misterio y es muy fácil ampliarlo a otros scripts. Como siempre, cualquier duda o sugerencia la podéis hacer en los comentarios.

Nota: La versión que carga por defecto WordPress de jQuery incluye una llamada a la función  jQuery.noConflict, por lo que en el primer script que utilice jQuery deberemos hacer una llamada a esta función para asegurar que todos los scripts funcionen correctamente.

Un comentario

Ocultando artículos y categorías del loop de WordPress

Nota: Para entender este tutorial son necesarios unos conocimientos básicos de PHP (sobretodo de matrices) y de WordPress (para saber las IDs del contenido y el lugar donde poner el código).

Hay veces en las que queremos ocultar ciertos artículos o categorías del loop de WordPress (el bucle principal que se encarga de mostrar el contenido de la página). En estos casos podemos recurrir a diversos métodos, como comprobar dentro del propio bucle si el artículo está en cierta categoría o tiene una ID determinada. Sin embargo, estos métodos no se pueden aplicar a plugins porque estos no pueden modificar código del bucle, así que debemos buscar un método diferente.

Mostrando $wp_query

Mostrando $wp_query

Durante el desarrollo de la versión 0.4 de WP Carousel me topé con este problema, y decidido a superarlo, tomé la vía probablemente más radical: modificar la variable $wp_query. Esta variable almacena toda la información referente a las consultas a la Base de Datos, incluyendo el contenido consultado, los filtros aplicados, el orden. De hecho, si imprimimos esta variable, obtendremos un resultado enorme, que podéis ver en parte en la imagen de la izquierda.

Alterando el contenido de esta variable se pueden hacer multitud de cosas, sin embargo nos centraremos en ocultar contenido del bucle.

Si nos fijamos en la variable, veremos que es una matriz. Los índices que nos interesan son los siguientes: category__not_in, tag__not_in y post__not_in. Son unos índices con unos nombres realmente descriptivos, ¿verdad? El primero nos permite eliminar categorías del bucle, el segundo nos permite eliminar etiquetas y el último nos permite eliminar artículos individuales.

El contenido de estos índices debe ser una matriz, la cual almacenará en todos los casos las IDs del contenido a ocultar. Veamos de forma práctica cómo ocultaríamos las categorías 3, 19 y 62 del bucle:


$wp_query->query_vars['category__not_in'] = array(3, 19, 62);

$wp_query->query($wp_query->query_vars);

La primera línea está clara, pero, ¿y la segunda? Se trata de una llamada a la función query(), que vuelve a realizar la consulta y elimina el contenido previamente guardado. Antes he comentado que esta variable almacena resultados de las consultas, así que es necesario limpiar la variable de resultados antiguos y rellenarla de nuevos, de otro modo no siempre funcionaría el código.

Este código no funciona en cualquier lugar de WordPress. Si pensamos con un poco de lógica, llegaremos a la conclusión de que debemos poner el código antes del bucle (porque si lo ponemos después, ya se habrá mostrado el contenido y no habrá nada que filtrar). Pero, ¿en qué lugar añadirlo? Bien, realmente se puede añadir en cualquier lugar antes del bucle. En el archivo functions.php del theme, en un plugin por separado (como ocurre con WP Carousel) o incluso justo antes del bucle. Eso sí, dependiendo de en qué lugar ponemos el código, la segunda línea (que actualiza los resultados) será necesaria u opcional. Por comodidad, podéis dejarla siempre, aumentará el número de consultas a la Base de Datos, pero cómo se hará uso de esta función en determinadas ocasiones, no es demasiado preocupante.

Pasemos a otro ejemplo: ocultemos los artículos con la etiqueta con ID 54.


$wp_query->query_vars['tag__not_in'] = array(54);

$wp_query->query($wp_query->query_vars);

Otro ejemplo bastante claro. Por último sólo nos quedaría ocultar artículos. Estoy seguro de que ya adivináis cómo se ocultarían los artículos con IDs 1, 7 y 42:


$wp_query->query_vars['post__not_in'] = array(1, 7, 42);

$wp_query->query($wp_query->query_vars);

Realmente no tiene mucha complicación, pero antes de acabar el tutorial debeís tener en cuenta un par de cosas:

  1. La variable $wp_query almacena contenido importante, y es recomendable hacer una copia de la variable para poder restaurarla más adelante, algo como:
    $wp_query_old = $wp_query;

    Así en caso de detectar un error en las modificaciones realizadas a la matriz, el script puede recuperar el contenido original.

  2. Modificar la consulta en ciertas páginas puede dañar el resultado, sobretodo cuando se visualiza una página individual o un artículo en solitario. Es recomendable modificar la matriz sólo cuando estamos en el index del blog (donde nos interesa ocultar o mostrar artículos).
  3. Este método sólo es adecuado para plugins. Si quisiéramos modificar nuestro theme, tenemos a nuestra disposición métodos aún más fáciles y menos intrusivos que éste.
  4. ¡No ocultemos contenido sin avisar antes al usuario! Todos estos cambios son invisibles para el usuario medio, y más de uno se llevaría una desagradable sorpresa al ver desaparecer sus artículos misteriosamente del índice de su blog.

Dicho esto, ahora es cosa vuestra experimentar. Tenéis más información sobre los índices que podéis modificar en esta página (aunque habla de una función diferente, muchos de los parámetros son equivalentes a los índices de la matriz).

Si tenéis problemas o dudas, preguntad en los comentarios.

2 Comentarios

Mac OS X incorpora TextEdit, un procesador de textos al estilo de WordPad (el que viene por defecto en Windows), que aunque en principio parece ser más básico y tener menos funciones, realmente oculta muchas de sus posibilidades.

En el videotutorial que teneís a continuación (creado por K-tuin) se explica cómo añadir imágenes, vídeos o archivos PDF a nuestros documentos de texto.

No hay comentarios

Integrando WP Carousel en cualquier theme

Theme por defecto de WP Carousel 0.4

Theme por defecto de WP Carousel 0.4

Nota: Este tutorial está destinado a los diseñadores de themes de WordPress y para poder entenderlo del todo son necesarios conocimientos básicos de PHP.

Desde la versión 0.4 de WP Carousel, los carruseles admiten themes, y claro, esto da mucho juego a los diseñadores, que con un poco de ingenio y creatividad, pueden hacer maravillas. También permite darle al carrusel un toque más acorde con el diseño de nuestros blogs, aunque claro, es posible que al distribuir nuestro theme con soporte de WP Carousel muchos usuarios se pierdan a la hora de instalar un segundo theme para WP Carousel.

Sin embargo, en la versión 0.4.0.1 añadí un parámetro muy útil a la función wp_carousel() (encargada de mostrar el carrusel): el parámetro $mode. Este parámetro acepta tres valores: show, get y array. El primero es que se toma por defecto y muestra el carrusel. El segundo devuelve el código HTML generado por el theme, mientras que el tercero devuelve una matriz con el contenido y la configuración del carrusel. Entonces disponemos de dos métodos diferentes para integrar WP Carousel en nuestro theme: llamándolo estableciendo el parámetro $mode en get (y reemplazando código) o llamándolo estableciendo el parámetro $mode en array, para más adelante crear un theme muy similar a los normales de WP Carousel, sólo que almacenado en la carpeta de nuestro theme e inseleccionable desde la página de opciones de WP Carousel.

Veamos cómo hacerlo.

Lo primero que haremos será crear una variable que almacene la matriz que devuelve wp_carousel() con el parámetro $mode establecido en array. Podemos crearla dentro de una función, en el archivo functions.php o directamente en el archivo correspondiente de nuestro theme (header.php, index.php, etc).

A continuación cargamos en nuevas variables la configuración del carrusel y sus elementos. La matriz que hemos obtenido antes tiene 3 índices: CONFIG, que almacena la configuración, ITEMS, que almacena los elementos e ID, que almacena la ID del carrusel (aunque ésta debemos definirla nosotros, así que no es de mucha utilidad).

He creado la variable $c_id para que el mismo código de un theme normal de WP Carousel sirva en nuestro theme especial y he tomado el valor del índice ID de la matriz del primer paso para hacer uso de éste, aunque podríamos haberlo tomado del valor que usamos como primer parámetro de la función wp_carousel().

A continuación utilizo la función eval() para crear la función encargada de cargar el código Javascript necesario para iniciar el carrusel. La siguiente línea tan sólo carga la función en el pie de página del theme.

Por último, cargamos el archivo wp-carousel-theme.php, que es el que contiene el theme en mi ejemplo. El código que podéis ver a continuación es el que utilizo para integrar WP Carousel en Portal Colorido 2.0.

$carousel_array = wp_carousel(ID_DEL_CARRUSEL, 'array');
$carousel_config = $carousel_array['CONFIG'];
$carousel_items = $carousel_array['ITEMS'];
$c_id = $carousel_array['ID'];
eval('if (!function_exists("wp_carousel_load_carousel_'.$c_id.'_js_code")) { function wp_carousel_load_carousel_'.$c_id.'_js_code() { wp_carousel_load_carousel_js('.$c_id.'); } }');
add_action('wp_footer', 'wp_carousel_load_carousel_'.$c_id.'_js_code');
require_once('wp-carousel-theme.php');

El archivo wp-carousel-theme.php contiene un theme normal de WP Carousel, la única diferencia es que la matriz $config en este caso es $carousel_config, al igual que la matriz $items es $carousel_items. Podéis seguir este tutorial para crear el theme de WP Carousel.

Como veis, no tiene demasiada complicación y no difiere demasiado del sistema general de creación de themes de WP Carousel.

Un comentario

Hoy han publicado en AyudaWordPress dos vídeos (de una duración total de 4 horas), creados por Cristian Eslava donde se explica desde cómo instalar WordPress en un servidor local hasta cómo crear el theme en sí.

http://www.vimeo.com/7450076 http://www.vimeo.com/7562212
No hay comentarios