Symfony 1.4, la guía definitiva

4.1. Crear el esqueleto del módulo

Como se vio en el Capítulo 2, Symfony agrupa las páginas en módulos. Por tanto, antes de crear una página es necesario crear un módulo, que inicialmente no es más que una estructura vacía de directorios y archivos que Symfony puede reconocer.

La línea de comandos de Symfony automatiza la creación de los módulos. Sólo se necesita llamar a la tarea generate:module indicando como argumentos el nombre de la aplicación y el nombre del nuevo módulo. En el capítulo anterior se creó una aplicación llamada frontend. Para añadirle un módulo llamado contenido, se deben ejecutar los siguientes comandos:

$ cd ~/miproyecto
$ php symfony generate:module frontend contenido

>> dir+      ~/miproyecto/apps/frontend/modules/contenido/actions
>> file+     ~/miproyecto/apps/frontend/modules/contenido/actions/actions.class.php
>> dir+      ~/miproyecto/apps/frontend/modules/contenido/templates
>> file+     ~/miproyecto/apps/frontend/modules/contenido/templates/indexSuccess.php
>> file+     ~/miproyecto/test/functional/frontend/contenidoActionsTest.php
>> tokens    ~/miproyecto/test/functional/frontend/contenidoActionsTest.php
>> tokens    ~/miproyecto/apps/frontend/modules/contenido/actions/actions.class.php
>> tokens    ~/miproyecto/apps/frontend/modules/contenido/templates/indexSuccess.php

Además de los directorios actions/ y templates/ este comando crea tres archivos. El archivo que se encuentra en el directorio test/ está relacionado con las pruebas funcionales, que se ven en el Capítulo 15. El archivo actions.class.php (que se muestra en el listado 4-1) redirige la acción a la página de bienvenida del módulo por defecto. Por último, el archivo templates/indexSuccess.php está vacío.

Listado 4-1 - La acción generada por defecto, en actions/actions.class.php

<?php

class contenidoActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
    $this->forward('default', 'module');
  }
}

Nota Si se abre el archivo actions.class.php generado realmente, su contenido es mucho mayor que las pocas líneas mostradas anteriormente, incluyendo un montón de comentarios. Symfony recomienda utilizar comentarios de PHP para documentar el proyecto y por tanto añade a cada archivo de cada clase comentarios que son compatibles con el formato de la herramienta phpDocumentor.

En cada nuevo módulo, Symfony crea una acción por defecto llamada index. La acción completa se compone del método executeIndex de la acción y del archivo de su plantilla llamada indexSuccess.php. El significado del prefijo execute y del sufijo Success se explican detalladamente en los Capítulos 6 y 7 respectivamente. Por el momento se puede considerar que esta forma de nombrar a los archivos y métodos es una convención que sigue Symfony. Para visualizar la página generada (que se muestra en la figura 4-1) se debe acceder a la siguiente dirección en un navegador:

http://localhost/frontend_dev.php/contenido/index

En este capítulo no se utiliza la acción index, por lo que se puede borrar el método executeIndex() del archivo actions.class.php y también se puede borrar el archivo indexSuccess.php del directorio templates/.

Nota Symfony permite crear los módulos sin necesidad de utilizar la línea de comandos. Uno de esos métodos es crear manualmente todos los directorios y archivos necesarios. En otras ocasiones, las acciones y las plantillas de un módulo se emplean para manipular los datos de una tabla de la base de datos. Como el código necesario para crear, obtener, actualizar y borrar los datos casi siempre es el mismo, Symfony incorpora un mecanismo que permite generar de forma automática todo el código PHP de un módulo de este tipo. El Capítulo 14 contiene los detalles de esta técnica.

La página de índice generada automáticamente

Figura 4.1 La página de índice generada automáticamente

4.1.1. Añadir una página

En Symfony la lógica o código de las páginas se define en la acción y la presentación se define en las plantillas. Las páginas estáticas que no requieren de ninguna lógica necesitan definir una acción vacía.

4.1.1.1. Añadir una acción

En este ejemplo, la página que muestra el mensaje "¡Hola Mundo!" se puede acceder mediante una acción llamada ver. Para crearla, solamente es necesario añadir el método executeVer en la clase contenidoActions, como muestra el Listado 4-2.

Listado 4-2 - Añadir una acción es equivalente a añadir un método de tipo execute en la clase de la acción

<?php

class contenidoActions extends sfActions
{
  public function executeVer(sfWebRequest $request)
  {
  }
}

El nombre del método de la acción siempre es execute + Xxxxxxx + (), donde la segunda parte del nombre es el nombre de la acción con la primera letra en mayúsculas.

Por tanto, si ahora se accede a la siguiente dirección:

http://localhost/frontend_dev.php/contenido/ver

Symfony mostrará un mensaje de error indicando que la plantilla verSuccess.php no existe. Se trata de un error normal por el momento, ya que las páginas siempre están formadas por una acción y una plantilla.

Nota Las URL (no los dominios) distinguen mayúsculas y minúsculas, y por tanto, también las distingue Symfony (aunque el nombre de los métodos en PHP no distingue mayúsculas de minúsculas). De esta forma, si se accede por ejemplo desde el navegador a la acción veR o vEr, Symfony devuelve un error de tipo 404 Página no encontrada).

4.1.1.2. Añadir una plantilla

La acción espera una plantilla para mostrarse en pantalla. Una plantilla es un archivo que está ubicado en el directorio templates/ de un módulo, y su nombre está compuesto por el nombre de la acción y el resultado de la misma. El resultado por defecto es success (exitoso), por lo que el archivo de plantilla que se crea para la acción ver se llamará verSuccess.php.

Se supone que las plantillas sólo deben contener código de presentación, así que procura mantener la menor cantidad de código PHP en ellas como sea posible. De hecho, una página que muestre "¡Hola, mundo!" puede tener una plantilla tan simple como la del Listado 4-3.

Listado 4-3 - La plantilla contenido/templates/verSuccess.php

<p>¡Hola, mundo!</p>

Si necesitas ejecutar algún código PHP en la plantilla, es mejor evitar la sintaxis usual de PHP, como se muestra en el Listado 4-4. En su lugar, es preferible escribir las plantillas utilizando la sintaxis alternativa de PHP, mostrada en el Listado 4-5, para mantener el código entendible para personas sin conocimientos de PHP. De esta forma, no sólo el código final estará correctamente indentado, sino que además ayudará a mantener el código complejo de PHP en la acción, dado que sólo las estructuras de control (if, foreach, while y demás) poseen una sintaxis alternativa.

Listado 4-4 - La sintaxis tradicional de PHP, buena para las acciones, pero mala para las plantillas

<p>¡Hola, mundo!</p>
<?php

if ($prueba)
{
  echo "<p>".time()."</p>";
}

?>

Listado 4-5 - La sintaxis alternativa de PHP, buena para las plantillas

<p>¡Hola, mundo!</p>
<?php if ($prueba): ?>
  <p><?php echo time(); ?></p>
<?php endif; ?>

Nota Una buena regla para comprobar si la sintaxis de la plantilla es lo suficientemente legible, es que el archivo no debe contener código HTML generado por PHP mediante la función echo, ni tampoco llaves. Y en la mayoría de los casos, al abrir una etiqueta <?php, debería cerrarse con ?> en la misma línea.

4.1.2. Transfiriendo información de la acción a la plantilla

La tarea de la acción es realizar los cálculos complejos, obtener datos, realizar comprobaciones, y crear o inicializar las variables necesarias para que se presenten o se utilicen en la plantilla. Symfony hace que los atributos de la clase de la acción (disponibles vía $this->nombreDeVariable en la acción), estén directamente accesibles en la plantilla en el ámbito global (vía $nombreVariable). Los listados 4-6 y 4-7 muestran cómo pasar información de la acción a la plantilla.

Listado 4-6 - Configurando un atributo de acción dentro de ella para hacerlo disponible para la plantilla

<?php

class contenidoActions extends sfActions
{
  public function executeVer(sfWebRequest $request)
  {
    $hoy = getdate();
    $this->hora = $hoy['hours'];
  }
}

Listado 4-7 - La plantilla tiene acceso directo a los atributos de la acción

<p>¡Hola, Mundo!</p>
<?php if ($hora >= 18): ?>
  <p>Quizás debería decir buenas tardes. Ya son las <?php echo $hora ?>.</p>
<?php endif; ?>

El uso de etiquetas cortas de apertura (<?=, equivalente a <?php echo) no se recomienda para aplicaciones web profesionales, debido a que el servidor web de producción puede ser capaz de entender más de un lenguaje de script, y por tanto, confundirse. Además, las etiquetas cortas de apertura no funcionan con la configuración por defecto de PHP y necesitan de ajustes en el servidor para ser activadas. Por último, a la hora de lidiar con XML y la validación, fallará inmediatamente porque <? tiene un significado especial en XML.

Nota La plantilla es capaz de acceder a algunos datos sin necesidad de definir variables en la acción. Cada plantilla puede invocar métodos de los objetos $sf_context, $sf_request, $sf_params y $sf_user. Esos métodos contienen datos relacionados con el contexto actual, la petición y sus parámetros, y la sesión. Más adelante se muestra cómo utilizarlos de manera eficiente.