Creación de un sitio web con PHP, MySQL y jQuery Mobile, Parte 2

Esta es la segunda parte de un tutorial de dos partes, en el que usamos PHP, MySQL y jQuery mobile para construir una tienda web de computadora simple. En la parte anterior creamos los modelos y los controladores, y esta vez escribiremos nuestras vistas.

jQuery móvil

Primero, digamos algunas palabras sobre la biblioteca que usaremos. jQuery mobile es una biblioteca de interfaz de usuario que se asienta sobre jQuery y brinda soporte para una amplia gama de dispositivos en forma de widgets listos para usar y un entorno de desarrollo táctil. Todavía está en versión beta, pero actualizar a la versión oficial 1.0 será tan simple como intercambiar una URL de CDN.

La biblioteca se basa en la mejora progresiva. Usted, como desarrollador, solo debe preocuparse por generar el HTML correcto, y la biblioteca se encargará del resto. jQuery mobile hace uso de HTML5 data- atributos y, al agregarlos, le indica a la biblioteca cómo debe representar su marcado.

En este tutorial, usaremos algunos de los componentes de la interfaz que nos brinda esta biblioteca:listas, barras de encabezado y pie de página y botones, todos los cuales se definen mediante el rol de datos atributos, que verá en uso en la siguiente sección.

Vistas de representación

Las vistas son archivos PHP, o plantillas, que generan código HTML. Son impresos por los controladores usando render() función auxiliar. Tenemos 7 vistas en uso para este sitio web - _category.php , _producto.php , _header.php , _footer.php , categoría.php , inicio.php y error.php , que se comentan más adelante. Primero, aquí está render() función:

incluye/ayudantes.php

/* These are helper functions */

function render($template,$vars = array()){

    // This function takes the name of a template and
    // a list of variables, and renders it.

    // This will create variables from the array:
    extract($vars);

    // It can also take an array of objects
    // instead of a template name.
    if(is_array($template)){

        // If an array was passed, it will loop
        // through it, and include a partial view
        foreach($template as $k){

            // This will create a local variable
            // with the name of the object's class

            $cl = strtolower(get_class($k));
            $$cl = $k;

            include "views/_$cl.php";
        }

    }
    else {
        include "views/$template.php";
    }
}

El primer argumento de esta función es el nombre del archivo de plantilla en las vistas/ carpeta (sin el .php extensión). El siguiente es un arreglo con argumentos. Estos se extraen y forman variables reales que puede usar en su plantilla.

Hay una forma más de llamar a esta función:en lugar de un nombre de plantilla, puede pasar una matriz con objetos. Si recuerda la última vez, esto es lo que se devuelve al usar find() método. Básicamente, si pasa el resultado de Category::find() para renderizar , la función recorrerá la matriz, obtendrá los nombres de clase de los objetos dentro de ella e incluirá automáticamente el _category.php plantilla para cada uno. Algunos frameworks (Rails por ejemplo) llaman a estos parciales.

Las Vistas

Comencemos con la primera vista:el encabezado. Puede ver que esta plantilla es simplemente la parte superior de una página HTML5 normal con código PHP intercalado. Esta vista se usa en home.php y categoría.php para promover la reutilización de código.

incluye/vistas/_header.php

<!DOCTYPE html>
<html>
    <head>
    <title><?php echo formatTitle($title)?></title> 

    <meta name="viewport" content="width=device-width, initial-scale=1" /> 

    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css" />
    <link rel="stylesheet" href="assets/css/styles.css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"></script>
</head>
<body> 

<div data-role="page">

    <div data-role="header" data-theme="b">
        <a href="./" data-icon="home" data-iconpos="notext" data-transition="fade">Home</a>
        <h1><?php echo $title?></h1>
    </div>

    <div data-role="content">

En la sección de encabezado incluimos jQuery y jQuery mobile del CDN de jQuery, y dos hojas de estilo. La sección del cuerpo es donde se pone interesante. Definimos un div con el data-role="page" atributo. Esto, junto con el data-role="content" div, son los dos elementos que la biblioteca requiere que estén presentes en todas las páginas.

El rol de datos="encabezado" div se transforma en una barra de encabezado. El tema de datos atributo elige uno de los 5 temas estándar. En su interior tenemos un enlace al que se le asigna un icono de inicio, y tiene su texto oculto. jQuery Mobile viene con un conjunto de iconos entre los que puede elegir.

Las etiquetas de cierre (y la barra de pie de página) residen en _footer.php ver:

incluye/vistas/_footer.php

 </div>

    <div data-role="footer" id="pageFooter">
        <h4><?php echo $GLOBALS['defaultFooter']?></h4>
    </div>
</div>

</body>
</html>

Nada demasiado elegante aquí. Solo tenemos un div con data-role="footer" atributo, y dentro de él imprimimos el $defaultFooter accesible globalmente variable, definida en includes/config.php .

Ninguno de los puntos de vista anteriores son impresos directamente por nuestros controladores. En cambio, son utilizados por category.php y casa.php :

incluye/vistas/inicio.php

<?php render('_header',array('title'=>$title))?>

<p>Welcome! This is a demo for a ...</p>
<p>Remember to try browsing this ...</p>

<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
    <li data-role="list-divider">Choose a product category</li>
    <?php render($content) ?>
</ul>

<?php render('_footer')?>

Si recuerda, la vista de inicio se representó en el controlador de inicio. Allí pasamos una matriz con todas las categorías, que está disponible aquí como $content . Entonces, lo que hace esta vista es imprimir el encabezado y el pie de página, definir una vista de lista móvil jQuery (usando el atributo de rol de datos) y generar el marcado de las categorías pasadas por el controlador, usando esta plantilla (usada implícitamente por renderizar() ):

index.php/views/_category.php

<li <?php echo ($active == $category->id ? 'data-theme="a"' : '') ?>>
<a href="?category=<?php echo $category->id?>" data-transition="fade">
    <?php echo $category->name ?>
    <span class="ui-li-count"><?php echo $category->contains?></span></a>
</li>

Observe que tenemos un $category Variable de PHP que apunta al objeto real para el que se está generando esta vista. Esto se hace en las líneas 24/25 de la función render. Cuando el usuario haga clic en uno de los enlaces generados por el fragmento anterior, será llevado a /?category=someid url, que mostrará el category.php vista, dada a continuación.

<?php render('_header',array('title'=>$title))?>

<div class="rightColumn">
    <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="c">
        <?php render($products) ?>
    </ul>
</div>

<div class="leftColumn">
    <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
        <li data-role="list-divider">Categories</li>
        <?php render($categories,array('active'=>$_GET['category'])) ?>
    </ul>
</div>

<?php render('_footer')?>

Este archivo también usa las vistas de encabezado, pie de página y _categoría, pero también presenta una columna con productos (pasados ​​por el controlador de categoría). Los productos se renderizan utilizando _product.php parcial:

<li class="product">
    <img src="assets/img/<?php echo $product->id ?>.jpg" alt="<?php echo $product->name ?>" />
    <?php echo $product->name ?> <i><?php echo $product->manufacturer?></i>
    <b>$<?php echo $product->price?></b>
</li>

Como tenemos una imagen como el primer hijo de los elementos li, jQuery mobile la muestra automáticamente como una miniatura de 80 px.

Una de las ventajas de usar los componentes de la interfaz definidos en la biblioteca es que se escalan automáticamente al ancho del dispositivo. Pero, ¿qué pasa con las columnas que definimos arriba? Tendremos que diseñarlos nosotros mismos con un poco de magia CSS3:

activos/css/estilos.css

media all and (min-width: 650px){

    .rightColumn{
        width:56%;
        float:right;
        margin-left:4%;
    }

    .leftColumn{
        width:40%;
        float:left;
    }

}

.product i{
    display:block;
    font-size:0.8em;
    font-weight:normal;
    font-style:normal;
}

.product img{
    margin:10px;
}

.product b{
    position: absolute;
    right: 15px;
    top: 15px;
    font-size: 0.9em;
}

.product{
    height: 80px;
}

Usando una consulta de medios, le decimos al navegador que si el área de visualización es más ancha que 650 px, debe mostrar las columnas una al lado de la otra. Si no es así (o si el navegador no admite consultas de medios), se mostrarán uno encima del otro, el comportamiento habitual de "bloqueo".

¡Hemos terminado!

En la segunda y última parte de este tutorial, escribimos nuestras opiniones para aprovechar las maravillosas funciones de jQuery mobile. Con un esfuerzo mínimo de nuestra parte, pudimos describir las funciones de nuestro marcado y crear fácilmente un sitio web móvil completo.