Mostrando entradas con la etiqueta frameworks. Mostrar todas las entradas
Mostrando entradas con la etiqueta frameworks. Mostrar todas las entradas

miércoles, 12 de marzo de 2008

Symfony vs Zend Framework. 4- ¿Cuál nos quedamos?

Artículos de la serie:
  1. Definición del problema
  2. Comencemos con Symfony
  3. Turno de Zend Framework
  4. ¿Cuál nos quedamos?
Después de que en la primera parte definieramos los requisitos de una pequeña aplicación y las implementásemos en los dos siguientes capítulos con los correspondientes frameworks, llega el momento de sacar unas cuantas conclusiones. Recordemos que el punto de vista de esta comparación es el de alguien que sólo ha dedicado unas cuantas horas a cada uno de los dos, así que debemos ser conscientes de que solo hemos visto la punta del iceberg y que tal vez por ello las conclusiones no sean del todo justas.

Forma de trabajo

En primer lugar hay ciertas diferencias a la hora de trabajar con ellos. Symfony hace uso de la linea de comandos para facilitarnos muchas tareas monótonas mintras que ZF todavía no lo incorpora. Cuando este último posea esta carácterística habrá que analizar si realmente equivaldría al otro en cuanto a funcionalidades. Por otro lado en Symfony tendremos que crear y retocar archivos YAML para ciertas cosas como validar formularios y como configuración de diversos aspectos.

A parte de esto, la forma de trabajar será muy parecida debido a que ambos responden a un patrón MVC y tendremos que recurrir continuamente a modificar clases relativas a acciones, revisar archivos plantilla, etc.

Curva de aprendizaje

Aquí toma clara ventaja ZF porque símplemente hemos de documentarnos a través de la guía de referencia para conocer las clases existentes y sus funciones. En Symfony, además de lo anterior, tendremos que familiarizarnos con Yaml, averiguar que podemos hacer y que no con los comandos de CLI y manejarnos por diferentes archivos de configuración, lo que implica familiarizarse con la estructura de archivos del proyecto.

La guerra de los plugins

Es posible encontrar una gran cantidad de plugins no oficiales para Symfony los cuales se pueden instalar, como no, haciendo uso de la linea de comando. Por otro lado ZF no distingue como plugins una serie de clases que tendrían que ver con la utilización de APIs externos, ya que forman parte de la distribución, pero sí que los identifica como servicios (Zend_Service_Amazon, Zend_Service_Flickr, etc) Es posible que nuestra elección deba centrarse en este aspecto si queremos comenzar un proyecto de tipo mashup y aquí Symfony tiene ventaja por la gran cantidad de recursos que pone a nuestra disposición.

Comandos sí o no

ZF necesita incorporar los comandos de CLI para llegar a la altura de Symfony, deberían darle un empujón definitivo a ese aspecto. De todos modos hay partidarios de no utilizarlos así que este hecho puede ser determinante para la gente que se posicione al respecto.

Otros aspectos

Otros puntos a favor de Symfony, aunque no he llegado a probarlos, son el soporte que proporciona para tests unitarios y funcionales, la integración de subversion y la sincronización de código entre los entornos de desarrollo, pruebas y producción.

Conclusiones

Desde mi punto de vista Symfony goza de ventaja sobre ZF por poseer los comandos de CLI , la gran cantidad de plugins exsitentes, el entorno de desarrollo con el menú flotante de información de debug, soporte para tests, etc.

Además de todo esto puede incluir a ZF como una biblioteca de clases. De hecho puede hacer esto mismo con otros frameworks. Para incluir ZF haríamos esto:

Declarar en settings.yml
.settings:
zend_lib_dir: /usr/local/zend/library/
Después extenderíamos la rutina autoload
.settings:
autoloading_functions:
- [sfZendFrameworkBridge, autoload]

Además Symfony cuenta con una gran comunidad que a parte de los plugins puede ofrecer algún extra interesante como Symfoclipse que nos permite usar los comandos de este a través de Eclipse en un menú contextual.



Por contra ZF goza de la simplicidad de aprendizaje que hemos comentado anteriormente, la libertad a la hora de definir nuestras estructuras de archivos y la flexibilidad a la hora de instanciar clases que comentamos en el capítulo precedente.

Algo que podría hacer Zend Technologies para impulsar su framework sería integrarlo con el entorno PDT de Eclipse. Estaría muy bien encontrar en el menú de creación de proyectos algo así como "Nuevo proyecto Zend Framework" y que al elegirlo nos creara una estructura de archivos inicial para adelantarnos trabajo, además, es algo que ya incorpora Zend Studio. En segundo lugar, por supuesto, tiene que potenciar como sea a la comunidad de desarrolladores para que creen mas "clases servicio". Es cierto que están haciendo un gran esfuerzo y que ZF crece rápidamente, está ganando muchos adeptos y por tanto están surgiendo muchas webs que lo utilizan.


Estamos ante dos rivales destinados a luchar una larga batalla y aunque, para mí, uno tenga ventaja, estoy seguro de que el otro irá recortando la diferencia. Deberemos elegir uno u otro en función de las situación que nos encontremos: sí se desea simplicidad y no perder mucho tiempo en la fase de aprendizaje ZF será lo más apropiado. Por el contrario, Symfony es mucho más completo y dispone de muchos, muchos más plugins. Hoy por hoy si tuviera que escoger uno de ellos elegiría Symfony pero ya veremos dentro de unos meses.

sábado, 1 de marzo de 2008

Symfony vs Zend Framework. 3- Turno de Zend Framework

Artículos de la serie:
  1. Definición del problema
  2. Comencemos con Symfony
  3. Turno de Zend Framework
En el capítulo anterior vimos como implementar nuestra aplicación mediante Symfony, ahora llega el turno de Zend Framework (ZF)

ZF es bastante reciente y ha tenido un desarrollo muy intenso desde su concepción. En el momento de escribir estas líneas tenemos disponible la RC1 de la versión 1.5. Una de las novedades anunciadas a finales del año pasado fue la inclusión de comandos para facilitar la creación del modelo de al aplicación, etc. pero parece que finalmente no va a estar disponible o, al menos no he encontrado referencias posteriores sobre ello.

Documentándonos

Como siempre lo primero es buscar información. ZF no se queda cojo en cuanto a recursos en este aspecto: podemos recurrir a la web oficial, donde encontraremos accesos a la documentación del API, la guía de referencia, etc. También es interesante vigilar Zend developer Zone ya que podremos encontrar tutoriales sobre el framework.

Como nota curiosa destacar que muchas de las personas envueltas en su desarrollo cuentan con blogs interesantes en los que abordan, por ejemplo, características futuras.

De todos modos para nuestro experimento nos hemos basado en un tutorial bastante interesante en el que se ejemplifica como hacer una herramienta en la que dar de alta álbumes musicales. Lo interesante es que hasta ahora este tutorial se a venido actualizando con cada nueva versión de ZF. En la actualidad se corresponde con la versión 1.4.5.

http://akrabat.com/wp-content/uploads/getting-started-with-the-zend-framework_145.pdf


Preparativos

Antes de comenzar con el desarrollo tenemos que asegurarnos que nuestro apache tenga cargado modulo rewrite y permita el uso del mismo, así que buscaremos por nuestro httpd.conf y tal vez tengamos que descomentar la linea en la que aparece:

LoadModule rewrite_module modules/mod_rewrite.so (dependiendo de la version de apache)
También nos aseguraremos de tener la directiva AllowOverride All

Siguiendo el tutorial mencionado, vamos creando los directorios necesarios con los archivos .htaccess que básicamente nos serviran para prohibir el acceso al directorio o, en otros casos, para desactivar el modulo rewrite de Apache.

Base de datos

Nuestra base de datos fue creada durante el capítulo anterior así que nos ahorraremos este paso. De todos modos, en caso cotnrario el proceso sería el mismo al que la mayoría estamos acostumbrados: optaríamos por diseñar en phpMyAdmin, Mysql Workbench o similar.

Bootstrap

De nuevo siguiendo el tutorial no tenemos mas que copiar un poco de código para llegar a tener nuestro index.php despachando todas las peticiones en el directorio raíz de nuestra aplicación. En nuestro caso finalmente quedo así:
<?php
error_reporting
(E_ALL|E_STRICT);
date_default_timezone_set('Europe/London');
set_include_path('.' . PATH_SEPARATOR . './library'

. PATH_SEPARATOR . './application/models/'. PATH_SEPARATOR . get_include_path());
include
"Zend/Loader.php";
Zend_Loader::loadClass('Zend_Controller_Front');

Zend_Loader::loadClass('Zend_Config_Ini');
Zend_Loader::loadClass('Zend_Registry');
Zend_Loader::loadClass('Zend_Db');

Zend_Loader::loadClass('Zend_Db_Table');
// load configuration
$config = new Zend_Config_Ini('./application/config.ini', 'general');

$registry = Zend_Registry::getInstance();
$registry->set('config', $config);
// setup database
$db = Zend_Db::factory($config->db->adapter,
$config->db->config->toArray());
Zend_Db_Table::setDefaultAdapter($db);

// setup controller
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setBaseUrl('/zf/bloggart/');
$frontController->setControllerDirectory('./application/controllers');
// run!
$frontController->dispatch();


Vemos que queda estructurado en una primera zona donde se cargan las clases a utilizar mediante la instrucción

Zend_Loader
::loadClass('miclase');


A continuación se carga y se registra un pequeño archivo de configuración (config.ini) que en nuestro caso sólo inicializa el acceso a la base de datos.

$config = new Zend_Config_Ini('./application/config.ini', 'general');

En tercer lugar viene la instanciación de la base de datos

$db = Zend_Db::factory($config->db->adapter,
$config->db->config->toArray());
Zend_Db_Table::setDefaultAdapter($db);


Después se prepara el ojeto controlador de la aplicación indicado el directorio raíz de la misma y el directorio donde encontraremos los archivos controloadores.

$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setBaseUrl('/zf/bloggart/');
$frontController->setControllerDirectory('./application/controllers');


Por ultimo escribiremos la instrucción que despacha las peticiones a nuestra aplicación.

$frontController->dispatch();

Hasta aquí podríamos haber agradecido algún comando que nos hiciera casi todo esto ya que parece algo rutinario y mecánico. Por otro lado, al no tener esa ayuda, obtenemos una gran flexibilidad a la hora de definir nuestra estructura de directorios.

Modelo y acciones

Nuestro modelo se encontrará en /application/models y tendrá dos archivos: Articulo.php y Comentario.php Una vez más nadie habrá creado por nosotros esos archivos pero para nuestros propósitos serán muy simples. En el caso de Articulo.php será:

<?php
class Articulo extends Zend_Db_Table
{
protected
$_name = 'blog_articulo';
}
?>

y Comentario.php será análogo.

Básicamente estamos creando las clases que contendrán todos los datos de las tablas de la base de datos del mismo nombre. Conseguimos esto haciendo que hereden de la clase Zend_Db_Table que por supuesto es nativa de ZF.

En cuanto a las acciones, quedará definidas dentro de /application/controllers/ Para el ejemplo se han creado IndexController.php y ComentarioController.php. El primero corresponde a las acciones que muestran, crean, modifican y borran artículos. El segundo hace el mismo papel pero para los comentarios. Como ejemplo aquí está el código de las acciones del index:
<?php
class IndexController extends Zend_Controller_Action
{
function
init()
{
$this->view->baseUrl = $this->_request->getBaseUrl();
Zend_Loader::loadClass('Articulo');
}
function
indexAction()
{
$this->view->title = "Janfri Bloggart";
$articulo = new Articulo();
$this->view->articulos = $articulo->fetchAll(null,'idarticulo desc');
}

function
addAction()
{
$this->view->title = "Añadir artículo nuevo";
if (
$this->_request->isPost()) {
Zend_Loader::loadClass('Zend_Filter_StripTags');
$filter = new Zend_Filter_StripTags();
$titulo = $filter->filter($this->_request->getPost('titulo'));
$titulo = trim($titulo);
$cuerpo = trim($filter->filter($this->_request->getPost('cuerpo')));
if (
$titulo != '' && $cuerpo != '') {
$data = array(
'titulo' => $titulo,
'cuerpo' => $cuerpo,
);
$articulo = new Articulo();
$articulo->insert($data);
$this->_redirect('/');

return;
}
}

$articulo = new Articulo();
$this->view->articulo = $articulo->createRow();
// additional view fields required by form
$this->view->action = 'add';
$this->view->buttonText = 'Add';
}

function
editAction()
{
$this->view->title = "Editar artículo";
$articulo = new Articulo();
if (
$this->_request->isPost()) {
Zend_Loader::loadClass('Zend_Filter_StripTags');
$filter = new Zend_Filter_StripTags();
$idarticulo = (int)$this->_request->getPost('idarticulo');
$titulo = $filter->filter($this->_request->getPost('titulo'));
$titulo = trim($titulo);
$cuerpo = trim($filter->filter($this->_request->getPost('cuerpo')));
if (
$idarticulo !== false) {
if (
$titulo != '' && $cuerpo != '') {
$data = array(
'titulo' => $titulo,
'cuerpo' => $cuerpo,
);
$where = 'idarticulo = ' . $idarticulo;
$articulo->update($data, $where);
$this->_redirect('/');
return;
} else {
$this->view->articulo = $articulo->fetchRow('idarticulo='.$idarticulo);
}
}
} else {
// album id should be $params['id']
$idarticulo = (int)$this->_request->getParam('id', 0);

if (
$idarticulo > 0) {
$this->view->articulo = $articulo->fetchRow('idarticulo='.$idarticulo);
}
}
// additional view fields required by form
$this->view->action = 'edit';
$this->view->buttonText = 'Update';
}

}

Las plantillas

Ahora convertiremos nuestro único archvo HTML en plantillas .phtml que colocaremos en la ruta /application/views/ El trabajo a realizar es muy parecido al que se hizo en el capítulo anterior:
  • Preparamos dos plantillas para la cabecera y el pie de cada página.
  • Una plantilla para el bloque lateral derecho que en una aplicación real tendríamos que trabajar más, pero aquí queda como código estático.
  • Para organizarnos creamos un directorio para las plantillas relacionadas con los artículo y otro para los comentario. En cada uno de ellos tendremos index.phtml, add.phtml, edit.phtml y delete.phtml. Además las plantillas de creación y edición llaman a otra auxiliar que contiene única y exclusivamente el html relativo al formulario.
Como muestra aquí tenemos:

index.phtml
<?php echo $this->render('header.phtml'); ?>
<div id="content">
<?php foreach($this->articulos as $articulo) : ?>
<div class="post">
<h2 class="title"><a href="#"><?php echo $this->escape($articulo->titulo);?></a></h2>
<div class="entry"><?php echo $this->escape($articulo->cuerpo);?></div>
<p class="meta"><span class="posted">Posted by <a href="#">Someone</a>
on December 17, 2007</span> <a href="<?php echo $this->baseUrl; ?>/index/edit/id/<?php echo $articulo->idarticulo;?>" class="permalink">Editar</a>
<a href="<?php echo $this->baseUrl; ?>/comentario/index/id/<?php echo $articulo->idarticulo;?>" class="comentarios">Commentarios</a></p>
</div>
<a href="<?php echo $this->baseUrl; ?>/index/delete/id/<?php echo $articulo->idarticulo;?>">Delete</a>
<?php endforeach; ?></div>
<!-- end #content -->
<?php echo $this->render('lateral.phtml'); ?>
<p><a href="<?php echo $this->baseUrl; ?>/index/add">Añadir nuevo artículo</a></p>
<?php echo $this->render('footer.phtml'); ?>


Como se puede observar usamos $this-&gt;render($plantilla); para incluir el código de otra plantilla.

add.phtml que es exáctamente igual que edit.phtml



<?php echo $this->render('header.phtml'); ?>
<div id="content">
<h2><?php echo $this->escape($this->title); ?></h2>
<?php echo $this->render('index/_form.phtml'); ?>
</div>
<!-- end #content -->
<?php echo $this->render('lateral.phtml'); ?>
<?php
echo $this->render('footer.phtml'); ?>

y por último _form.phtml

<form action="<?php echo $this->baseUrl ?>/index/<?php
echo $this->action; ?>" method="post">
<div>
<label for="artist">Título</label>
<input type="text" name="titulo"
value="<?php echo $this->escape(trim($this->articulo->titulo));?>"/>
</div>
<div>
<label for="title">Cuerpo</label>
<textarea name="cuerpo" cols="60" rows="30">
<?php echo $this->escape($this->articulo->cuerpo);?>
</textarea>
</div>
<div id="formbutton">
<input type="hidden" name="idarticulo" value="<?php echo $this->articulo->idarticulo; ?>" />
<input type="submit" name="add"
value="<?php echo $this->escape($this->buttonText); ?>" />
</div>
</form>



Conclusiones

Una de las cosas que más me ha llamado la atención sobre ZF es su capacidad para ofrecer alternativas para hacer una misma cosa. Por ejemplo nos encontraremos con que podremos instanciar clases llamando en su constructor a unos cuantos parámetros o sustituyendo a estos por un único parámetro en forma de array asociativo que habremos preparado previamente.

La desventaja de no estar asistidos por comandos de shell se convierte en un punto a favor de la flexibilidad de la jerarquía de archivos, es decir, tendremos total poder de decisión para estructurar los archivos de nuestra aplicación.

Al final la forma de trabajo termina siendo bastante parecida a nuestro caso anterior, nos queda todo bastante estructurado según los principios del patrón MVC.

De nuevo nos quedamos con las sensación de haber rascado superficialmente algo que podría llegar a ser muy potente en caso de tener que hacer una aplicación más compleja.

domingo, 17 de febrero de 2008

Symfony vs Zend Framework. 2- Comencemos con Symfony

Artículos de la serie:
  1. Definición del problema
  2. Comencemos con Symfony
En el capitulo anterior planteamos una pequeña aplicación para comparar Symfony y Zend Framework. En este parte empezaremos con el primero de los citados no sin antes recordar que, aunque pueda parecerlo en ciertos momentos, esto no es un tutorial ya que no se citan todos y cada uno de los paso dados para llegar a la aplicación final.

Antes de nada... ¡a leer!

Partiendo de unos conocimientos nulos sobre Symfony, si rebuscamos un poco en su portal web, encontraremos una par de cosas interesantes para hacernos a la idea de cómo empezar a trabajar.

http://www.symfony-project.org/tutorial/1_0/my-first-project
http://www.symfony-project.org/book/1_0/

El primero de los enlaces es un tutorial rápido en el que curiosamente se desarrolla un ejemplo muy similar al nuestro. Es obvio que ha resultado bastante útil a la hora de hacer esta prueba. Las principales diferencias con nuestro caso son:
  • Nuestro requerimiento de utilizar una base de datos MySQL.
  • El diseño de nuestras tablas, que no aprovecha las ventajas de las nomenclaturas predefinidas para los ficheros YAML.
  • Nuestro diseño gráfico que aplicamos de una forma bastante realista (como si un equipo de diseño nos lo entregara maquetado)
El segundo enlace es un libro que podremos consultar en formato html, obtenerlo impreso o, incluso, en formato PDF traducido al español gracias a librosweb.es Si bien no es necesario leerlo por completo para realizar este ejemplo de aplicación, no vendrá mal darle un vistazo rápido y tenerlo a mano para consultar alguna duda.

Además de esto tendremos toda la documentación habitual sobre el API a la que podremos recurrir cuando lo necesitemos

Diseñando la BD

Recordamos el diseño comentado en el capítulo anterior según el cual un artículo podía tener muchos comentarios de lectores:



En Symfony tentemos que plasmar nuestros diseños en YAML, así que para el diagrama anterior el archivo schema.yml correspondiente sería:
propel:
blog_articulo:
_attributes: { phpName: Articulo }
idarticulo: { type: integer, required: true, primaryKey: true, autoIncrement: true }
titulo: varchar(255)
cuerpo: longvarchar
fecha_creacion: {timestamp}
blog_comentario:
_attributes: { phpName: Comentario }
idcomentario: { type: integer, required: true, primaryKey: true, autoIncrement: true }

idarticulo: { type: integer, foreignTable: blog_articulo, foreignReference: idarticulo, onDelete:cascade }
author: varchar(255)
email: varchar(255)
body: longvarchar
fecha_creacion: {timestamp}

Una vez más hay que recordar que había una forma más fácil de hacer esto y es realmente la recomendable, consiste en usar ciertos nombres de campos preestablecidos para claves primarias, claves externas y campos de fecha. La siguiente definición se correspondería con ello:

propel:
blog_articulo:
_attributes: { phpName: Articulo }
id:
titulo: varchar(255)
cuerpo: longvarchar
created_at:
blog_comentario:
_attributes: { phpName: Comentario }
id:
articulo_id:
author: varchar(255)
email: varchar(255)
body: longvarchar

created_at:

Después de ejecutar este paso es natural pensar que alguien que se adentre en este framework deberá familiarizarse con el lenguaje YAML y con Propel. Esto incrementa un poco la curva de aprendizaje. Como anécdota basta decir que el que escribe esto perdió bastante tiempo hasta conseguir hacer funcionar el fichero YAML mostrado anteriormente y todo por culpa de un salto de linea que pasaba inadvertido.

Cargando el resultado en mysql

Como ya tenemos nuestro fichero de descripción de la base de datos, continuaremos generando las clases de nuestro modelo, que quedará alojado en sf_sandbox/lib/model/ y nos permitirá actuar con la base de datos sin utilizar sentencias SQL.

php symfony propel-build-model

Si como es nuestro caso la aplicación parte desde cero y no tenemos la base de datos creada en nuestro servidor, nos vendrá bien utilizar el siguiente comando para generar el archivo de intrucciones SQL que podremos utilizar más tarde:

php symfony propel-build-sql

Gracias al archivo generado y disponible en la ruta data/sql/lib.model.schema.sql podremos importar el diseño de la base de datos a nuestro servidor MySQL. Para ello usaremos la linea de comandos, la opcion restaurar de MySQL Administrator, PHPMyAdmin, etc. Alternativamente podríamos utilizar la instruccion:

php symfony propel-insert-sql

Esta instrucción es útil si lo tenemos todo bien configurado con Symfony para que actúe sobre el serividor MySQL ya que por defecto generará una base de datos SQLite. De hecho en nuestro caso ha sido necesario modificar la configuración para poder trabajar con MySQL.

Un poco de magia

Los formularios de creación, modificación y eliminación de datos, suelen ser una tarea bastante tediosa y monótona. Por suerte Symfony nos puede librar casi por completo de ello, y decimos casí porque es cierto que siempre terminaremos retocando algo de los formularios. Esto lo conseguimos en nuestro caso haciendo lo siguiente:

php symfony propel-generate-crud frontend articulo Articulo
php symfony propel-generate-crud frontend comentario Comentario
php symfony clear-cache

Modulos y acciones

Llegados a este punto tenemos gran parte de la lógica interna de nuestra aplicación desarrollada. Gracias a los comandos que acabamos de ejecutar, dentro del directorio frontend/modules tendremos creados los módulos articulo y comentario. Cada uno de ellos contiene los directorios actions y templates. De momento nos ocuparemos del primero, donde encontraremos el fichero actions.class.php En este fichero se nos ha creado una clase que contiene todas las acciones del módulo y que por supuesto podremos modificar según nuestras necesidades.

Sin entrar mucho en detalle, en nuestro modulo articulos tendremos, en el fichero actions.class.php, la clase articuloActions que contendrá, entre otras, las siguientes funciones:
  • executeList: muestra el listado de artículos utilizando la plantilla listSuccess.php
  • executeShow: muestra un determinado artículo utilizando la plantilla showSuccess.php
  • etc.
Por poner un ejemplo nosotros hemos modificado executeList para que muestre los artículos por orden descendente de fecha:
public function executeList()
{

$this
->nombreModul=$this->getModuleNam();
$c=new Criteri();
$c->addDescendingOrderByColum(ArticuloPeer::FECHA_CREACION);
$thi->articulos = ArticuloPeer::doSelect($c
);
}

Adaptando nuestro diseño inicial

En la introducción a esta serie escogimos el diseño Pluralism. Es el momento de adaptarlo a nuestra aplicación, para ello tomaremos el archivo css (style.css) y lo copiaremos en la ruta /web/css. Para hacer que nuestra web lo lea añadiremos la siguiente linea al archivo layout.php que se encuentra en /apps/frontend/templates/

php echo stylesheet_tag('style') ;

Por supuesto insertaremos esta linea antes del fin de la etiqueta html head.

Después de esto remaquetamos nuestro layout.php copiando el código html proporiconado por Pluralism. Es decir que añadimos las capas wrapper y todo lo que necesitemos para obtener el resultado esperado. Mostraremos parte del código:
<body>
<div id="wrapper">
<div id="wrapper2">
<div id="header">
<div id="logo">
<h1&gt
<?php echo link_to('Janfri Bloggart', '@homepage')?></h1>
</div>
<div id="menu">
<ul>
<li&gt
<?php echo link_to('Crear entrada','articulo/create')?></li>
<li&gt
<?php echo link_to('Lists de articulos','articulo/list')?></li>
</ul>
</div>
</div>
<!-- end #header -->
<div id="page">
<div id="content">
<?php echo $sf_data->getRaw('sf_content')?>
</div>


Observese que introducimos un link a la home como título y que en la zona de menús dejamos dos links más.

Con la instrucción $sf_data->getRaw('sf_content') mostramos la información correspondiente a la acción invocada del módulo actual.

Para mostrar el listado de títulos de posts recientes nos hemos ayudado creando una plantilla auxiliar llamada _articulos_listado.php que hemos hubicado en modules/articulo/templates/ Este tipo de plantillas se incluyen mediante la instrucción inclde_partial:

include_partial('articulo/articulos_listado',array('articulos'=>$articulos
));

Por lo demás, el trabajo en la capa de presentación se basa en modificar las plantillas existentes, por ejemplo, a la hora de dar de alta un artículo hemos cambiado el "select" cargado con los artículos existentes por un input hidden con el valor del articulo a comentar. De otro modo: Simfony es listo pero no perfecto. Nos ha proporcionado un formulario de creación de comentarios en el que podríamos elegir el artículo a comentar mediante un "select" pero no era lo que queríamos. También hemos ampliado los textarea que nos ha creado para el cuerpo de los artículos y los comentarios, por citar otro ejemplo.











Conclusiones


Tras todo lo comentado anteriormente llegamos a la conclusión de que en eso más o menos consiste el trabajo básico. Debemos modificar las acciones y las plantillas hasta conseguir los resultados deseados. Todo ello después de haber hecho un buen diseño de tablas y haber ejecutado los comandos que nos preparan todos los archivos. Fácil y rapido una vez te acostumbras al árbol de archivos, configuraciones, etc. No se le puede pedir más.

Además es de agradecer que Symfony diferencia entre el entorno de desarrollo y el de producción, ofreciendo en el primero bastante información útil a través de un menú flotante en nuestra propia página web. Podermos inspeccionar el valor de variables, mensajes de log, consultas SQL realizadas (a través de Propel), etc.

El precio para disfrutar de todo esto es el aprendizaje, tal vez mayor que con otros competidores ya que además del API, tendremos que tener conocimientos sobre YAML y Propel.

En definitiva dan ganas de seguir poniendo a prueba a Symfony ya que es una forma diferente de trabajar con PHP pero es el momento de comenzar con Zend.

martes, 12 de febrero de 2008

Symfony vs Zend Framework. 1- Definición del problema

Desde hace un par de años están tomando mucho auge diversos frameworks en PHP: Prado, Tigermouse, Symfony, CodeIgniter... Realmente hay una gran variedad de ellos haciendo difícil la tarea de elegir uno. Por si éramos pocos, durante el año pasado surgió Zend Framework (ZF en adelante) con todo el apoyo de la compañía que lleva las riendas del desarrollo del intérprete PHP.
Parecía que ZF iba a desplazar a todos los demás, pero entonces llegó Yahoo y anunció la adopción de Symfony para desarrollar Del.icio.us. Podríamos decir, con permiso de los demás, que la partida huele a tablas entre ambos al menos mediáticamente.

Todo esto invita a hacer una comparativa y la haremos desde el punto de vista de alguien que nunca ha utilizado ninguno de ellos. Para ello haremos una aplicación bastante simple: un blog (puede que no sea muy original) y partiendo de un diseño común la escribiremos utilizando ambos frameworks.

En principio dedicaremos capítulos diferentes a cada uno de los frameworks y, aunque no hay intención de que tengan estructura de tutorial, detallaremos bastantes de los pasos seguidos para la implementación. En la última parte comentaremos las conclusiones a las que lleguemos.

La aplicación

Simplificaremos bastante la aplicación, contemplando las siguientes historias a desarrollar.

1- El blogger escribe, edita o borra artículos.
2- El lector lee artículos
3- El lector añade comentarios a un artículo.



No incluiremos procesos de autenticación de usuarios.

Por supuesto el diseño de la BD será el mismo para ambos casos y responderá a este esquema:


Aclararemos aquí que seremos estrictos con el nombre de los campos. Como se verá mas adelante nos resultaría más fácil llamar id a los campos clave de cada tabla, de lo contrario nos veremos obligados, por ejemplo en el caso de Symfony, a extender las definiciones de nuestros campos en los ficheros yaml. Lo mismo ocurriría si llamásemos created_at a los campos fecha_creacion.


En cuanto a la capa de presentación elegiremos un diseño de la web freecsstemplates Para ello buscaremos uno que se adecue a la siguiente disposición:



Hay bastantes donde elegir. Nosotros nos quedaremos con Pluralism ya que cumple con nuestras características deseadas.



Así pues, a partir de nuestros casos de uso y con el diseño elegido, tenemos las siguientes páginas a desarrollar:

  • Listado de posts. En él se podrán leer directamente el cuerpo de los posts recientes y aprovechando la maquetación de pluralism tendremos un listado de posts (de sus títulos) inmediatamente antes del pie. Ya que no hay validación de usuarios colocaremos cerca de este bloque el enlace que nos permitirá crear una entrada nueva.
  • Edición de posts. Aquí se crearán, modificarán y borrarán los artículos. Será un entorno muy básico sin edición WYSIWYG, etc.
  • Añadir comentarios. Al igual que antes será un entorno muy simple.


Otras consideraciones a tener en cuenta


Por lo general no abarcaremos detalles de carácter avanzado como la instalación o la posibilidad de utilizar plugins porque simplemente nos pondremos en el caso más práctico: hacer una aplicación que funcione.

Por supuesto se intentará que ambas versiones sean lo más similares posible en aspecto y funcionamiento.

Versiones utilizadas

Usaremos el recién horneado Zend Framework 1.5 (que sigue siendo una beta en el momento de escribir esto) y el paquete Sandbox de Symfony 1.0 que en teoría tiene todo lo necesario para comenzar una aplicación como esta.
Como base de datos haremos uso de MySQL en ambas aplicaciones.

Powered by ScribeFire.