miércoles, 20 de octubre de 2010

Jugando con Kumbia


Después del percance que comenté en la entrada anterior, he comenzado a recuperar parte de las cosas que perdí con mi DD. Entre las decenas de aplicaciones que normalmente uso, está por supuesto XAMPP. Me he descargado la última versión (la 1.7.3) la cual -entre otros cambios- viene con PHP 5.3.1. Instalé, hice algunas pruebas y todo bien.

El problema se presentó cuando fui a instalar kumbiaPHP. Me descargué la versión que tienen en el website y cuando intenté hacer algunas cosillas, prácticamente todas las pruebas fueron infructuosas. Lo primero que pensé fue que kumbia no era compatible con PHP 5.3.x, pero gracias al soporte que me dieron en @kumbiaPHP, pude resolver de manera muy sencilla los errores y en minutos tener a kumbia trabajando perfectamente con PHP5.3.1.

Con sólo cambiar algunos archivos es suficiente, pero yo preferí conectarme vía bazaar al repositorio del proyecto. De esta manera me aseguro de estar al día con los cambios que se hacen en el framework. Bazaar, es una buena herramienta para trabajar con proyectos de forma versionada, recomendaría utilizar esta vía. De todas formas, para el que no le guste esta opción, aquí dejo una copia de la biblioteca, en zip, de sólo descargar y usar.

Resuelto el problema con PHP, todo lo demás se mantiene tal como lo expliqué en entradas anteriores. Recomiendo nuevamente echar una pasada por el wiki, que tiene muy buenos tutoriales.

Antes de ponerme a trabajar en función de conectarme a twitter, postear, recibir tweets, etc, decidí hacer un ejercicio puro en kumbia, concretamente un CRUD, para una base de datos sencilla que utilizaré para almacenar datos de beisbol. Es lo que estaré mostrando en este post, y en varios posts siguientes.

Para no perder la costumbre, he revisado las plantillas que ofrece opendesigns.org, y me he quedado con wide-blue. Igual que he hecho antes, dentro del directorio app/public/css he creado un subdirectorio "wide-blue" para almacenar las hojas de estilo de la plantilla, y en app/public/img he creado también un "wide-blue" para las imágenes.

En la versión que tengo de kumbia, los directorios han sido ligeramente movidos. Ahora, dentro de views, existe un directorio llamado _shared, que contiene los subdirectorios errors, partials, scaffolds y templates, en los cuales almacenaremos nuestros códigos, de la misma forma que hicimos antes.

Dentro de _shared/templates, está la plantilla por defecto: default.phtml, recordemos es la plantilla por defecto para toda nuestra aplicación. En ese directorio podemos todas las plantillas que queramos y utilizarlas cuando sea necesario. Yo, sin embargo, me fui con default.phtml, cuyo contenido sustituí con el código de wide-blue, por supuesto, teniendo en cuenta las modificaciones necesarias para incluir imágenes, css, y el view::Content().

Entre los cambios más recientes de kumbia, está la forma en que se incluyen imágenes, enlaces, elementos de formularios, etc. Por eso, incluyo algunos códigos a continuación.

Para incluir correctamente los archivos css:

<?php Tag::css('wide-blue/style') ?>
<?php
echo Html::includeCss() ?>

En donde style.css es la hoja de estilo que se va a incluir, y está ubicada en el subdirectorio app/public/css/wide-blue.

Para incluir imágenes:

<?php echo Html::img("lvbp.jpg"); ?>

En el lugar que queramos mostrar el contenido específico, recordemos que debemos incluir:

<?php View::content(); ?>

Para incluir enlaces:

<?php echo Html::linkAction("enlace", 'Titulo') ?><br>

Conociendo estos códigos, podemos dejar nuestra plantilla lista para usar. Sobre la marcha iremos descubriendo nuevos elementos. Observe que el botón de búsqueda del banner superior es una imagen, y de momento no se ve. Luego explicaré con detalle el manejo de los formularios, por ahora sólo dejo el código que hay que sustituir por el código del submit-image para que funcione:

<?php
$args
= array('class="hledat"','type="image"');
echo
Form::submitImage('wide-blue/search-button.gif', $args);
?>


La Base de Datos

Supongo que ya tenemos nuestra plantilla funcional (es bueno comprobar que sea así). Ahora voy a explicar algo que no había explicado antes, y es el manejo de la base de datos. Mi base de datos de beisbol, que es con la que trabajaré en este post y en los siguientes, está almacenada en PostgreSQL.

Lo primero que debemos configurar es el archivo databases.ini (ubicado en app/config/) con nuestros datos. Como estamos haciendo pruebas, utilizo la base de datos de "development", que en mi caso dejé así:

[development]
host = localhost
username = beisbol
password = beisbolistico
name = mibeisbol
type = pgsql

Evidentemente el nombre de usuario, password y nombre de la base de datos depende de cada quien. Lo más importante que hay que notar es el tipo de manejador de BD (pgsql).


Manos a la obra

Voy a comenzar con un ejemplo muy muy simple. Una tabla country, donde voy a almacenar nombres de paises, y una abreviatura. Asumo que todo el que lea este artículo, está en capacidad de crear roles en postgres, crear bases de datos y agregar/editar tablas, así que me limito a dejar el código de la tabla country:

CREATE TABLE country
(
id serial NOT NULL,
country_name character varying(128),
country_3166 character varying(16),
CONSTRAINT pk_country PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE country OWNER TO beisboluser;

En country_name guardaremos el nombre del país, en country_id la abreviatura según el estándar ISO 3166 y nuestra clave primaria será id.

Teniendo nuestra tabla lista, necesitamos crear un modelo para manejar esa tabla. Los modelos se almacenan dentro de app/models. Allí crearemos nuestro country.php, cuyo contenido será el siguiente:

<?php
class Country extends ActiveRecord
{
public function
getCountries($page, $ppage=20)
{
return
$this->paginate("page: $page", "per_page: $ppage");
}
}
?>

Nuestra clase contiene sólo una función (getCountries()), que utilizaremos luego para traer los elementos de nuestra tabla country.

Ese es nuestro modelo, ahora vamos a crear nuestro controlador. Ya hemos trabajado con controladores, sin embargo, recuerdo que deben ir en el directorio app/controllers. Así que creamos nuestro country_controller.php allí. NOTA: el "_controller" en el nombre, es obligatorio.

Me he basado en el ejemplo Beta2 CRUD para realizar nuestro controlador. El código es el siguiente:

<?php

Load
::models('country');

class
CountryController extends ApplicationController {


public function
index($page=1)
{
$country = new Country();
$this->listCountries = $country->getCountries($page);
}

public function
create()
{
if(
Input::hasPost('country'))
{
$country = new Country(Input::post('country'));
if(!
$country->save()){
Flash::error('Falló Operación');
}else{
Flash::valid('Operación exitosa');
Input::delete();
}
}
}

public function
edit($id = NULL)
{
$country = new Country();
if(
$id != NULL)
$this->country = $country->find($id);

if(
Input::hasPost('country'))
{

if(!
$country->update(Input::post('country'))){
Flash::error('Falló Operación');
} else {
Flash::valid('Operación exitosa');
return
Router::redirect();
}
}
}

public function
del($id = NULL)
{
if (
$id) {
$country = new Country();
if (!
$country->delete($id)) {
Flash::error('Falló Operación');
}else{
Flash::valid('Operación exitosa');
}
}
return
Router::redirect();
}
}
?>

Bastante sencillo de digerir con una sola ojeada. Hemos incluido una función index() en la que mostraremos todos los países que tengamos en la base de datos, utilizando la función getCountries() del modelo. También hemos incluido funciones de creación, edición y eliminación.

Podemos prestar atención a como utilizamos Input, para manejar la información que nos llega de la capa de Vista (por ejemplo: Input::hasPost, Input::post, etc).

También podemos observar como utilizamos las funciones save(), update() y delete() sobre una instancia de nuestro modelo. Recordemos que uno de los pilares de kumbia es el concepto de Active Record, el cual facilita las operaciones básicas sobre nuestros modelos. Por ello, no fue necesario programar estas funciones, sino que kumbia ya sabe que hacer en cada caso.

En este punto, ya tenemos nuestro modelo y nuestro controlador listo, sólo nos falta crear las vistas. Recordemos que para las vistas debemos crear un subdirectorio con el nombre de nuestro elemento en app/views, y dentro de él, incluiremos un archivo con extensión .phtml por cada acción que queramos realizar.

Lo que vamos a hacer es crear un index, en el que mostraremos una tabla con todos los elementos que se encuentren en nuestra tabla y le incluiremos un enlace a la página de eliminación y edición. Yo trabajé un poco el ejemplo, para obtener un resultado más vistoso. Este el código de nuestro index.phtml:

<div class="content">
<?php echo View::content(); ?>
<h3>Countries</h3>

<?php echo Html::linkAction("create", 'New') ?>

<table>
<col class="first-column" />
<col span="3" />
<col class="last-column" />
<tr class="first-row">
<th>Name</th>
<th>Abbreviation</th>
<th></th>
<th></th>
</tr>
<?php foreach ($listCountries->items as $item) : ?>

<tr>
<td><?php echo $item->country_name ?></td>
<td><?php echo $item->country_3166 ?></td>
<td><?php echo Html::linkAction("edit/$item->id/", 'Edit') ?></td>
<td><?php echo Html::linkAction("del/$item->id/", 'Delete') ?></td>
</tr>

<?php endforeach; ?>
</table>

</div>

El código se explica solo. Para fijar lo explicado al principio, observe como se trabajan los enlaces (pregúntese cómo haría para incluir un enlace a una acción de otra entidad).

Observe el foreach. Lo que está haciendo es recorrer los elementos que se encuentren en el arreglo listCountries, creado en el controlador y por cada uno, escribir una fila de una tabla en HTML. Si vemos el resultado en el navegador, lógicamente veremos sólo el encabezado de nuestra tabla, porque aún no hemos ingresado datos. Es lo que haremos a continuación en nuestro archivo create.phtml:

<div class="content">
<?php View::content(); ?>
<h3>Add Country</h3>

<?php echo Form::open(); ?>

<br>
<label>Name
<?php echo Form::text('country.country_name'); ?></label>

<br>
<label>Abbreviation
<?php echo Form::text('country.country_3166'); ?></label>

<?php echo Form::submit('Add'); ?>

<?php echo Form::close() ?>
</div>

Aquí nos centraremos en el uso de formularios. La manera de marcar el inicio es mediante la función Form::open(). Más adelante, agregamos dos campos de texto mediante Form::text(), luego un botón submit (Form::submit) y finalmente cerramos mediante Form::close().

observe el nombre que le estamos colocando a cada uno de nuestros imputs (country.country_name y country.country_3166). Antes del punto va el nombre de nuestra entidad, y luego del punto, el campo correspondiente en base de datos. De esta manera, kumbia sabrá que hacer cuando invocamos en nuestro controlador la función save().

Con estas dos vistas, nuestra aplicación debe estar funcionando. En la siguiente entrada seguiremos trabajando con formularios, incluiremos otros elementos, incluyendo el submit-image que comentamos al comienzo. Como práctica, el lector puede realizar la vista de edición, tomando como referencia el ejemplo mostrado en Beta 2 CRUD.

Así termino esta entrada, espero que todo haya quedado claro. También a manera de práctica, el lector puede hacer lo que hicimos en este ejemplo con una tabla para guardar canales de TV.

Hasta la próxima!

4 comentarios:

Anónimo dijo...

Puedes pasar los $atrs como string tambien y queda asi:

Anónimo dijo...

Se comio el php.
Queda asi:
echo Form::submitImage('wide-blue/search-button.gif', 'class="hledat" type="image"');

Marco dijo...

Correcto, es exactamente lo mismo. Siempre tiendo a crear más variables, cuestión de gustos.

Saludos

foxmulder79 dijo...

Buen post a pesar del tiempo creo que nadie ha hecho algo mejor, tan claro. sobre todo para este FW que tiene poca documentacion o una enredo en la internet para conseguir cual es la que esta vigente. porque puede que consigas documentacion pero tal vez no sirva para la versión que estes usando.

Publicar un comentario