Kohana es un framework de PHP5 que sigue la arquitectura MVC (Modelo-Vista-Controlador). Hay varias razones por las que deberías elegir Kohana, pero las principales son seguridad, ligereza y simplicidad. En este tutorial, introduciré sus características principales y, con una simple demostración, mostraré cuánto tiempo Kohana puede ahorrarte potencialmente.
Paso 1: ¿Qué es Kohana?
Kohana es un framework de PHP5 que sigue la arquitectura MVC. MVC mantiene separadas la lógica de la presentación. Esto permite crear un código más limpio y ahorrar tiempo en la búsqueda de errores. Para los que no estén familiarizados con esta arquitectura:
- Un modelo representa datos sobre los que la aplicación opera. Normalmente es una base de datos.
- Una vista contiene el código de presentación como HTML, CSS y JavaScript.
- Un controlador interpreta la entrada del usuario y redirige al modelo y/o vista.
- Altamente seguro
- Extremadamente ligero
- Breve curva de aprendizaje
- Utiliza el patrón MVC
- 100% compatible con la codificación UTF-8
- Arquitectura débilmente acoplada
- Extremadamente fácil de extender
Paso 2: Descargando Kohana
Empecemos. Visita la página oficial de Kohana y haz click sobre la caja verde de la esquina derecha para descargar la última versión. Todas las bibliotecas, asistentes y vistas de Kohana están incluidos en el paquete de descarga por defecto, pero puedes seleccionar módulos extra, herramientas de terceros, y los lenguajes que desees. Para el propósito de este tutorial, el paquete por defecto será suficiente. Haz click en "Download Kohana!" para iniciar la descarga.
Paso 3: Instalando Kohana
Una vez que se ha terminado la descarga:- Descomprimir el zip
- Renombrar la carpeta "Kohana_vx.x.x" (x.x.x=número de versión) a "kohana" y súbela a la carpeta raíz de tu servidor web.
- Edita el fichero de configuración global application/config/config.php de esta forma:
$config['site_domain'] = 'localhost/kohana';
- Si estás usando un sistema unix (linux, MacOSX), las subcarpetas de la instalación podrían haber perdido sus permisos durante la descompresión del zip. Haz un
chmod
a 755 de todas ellas ejecutandofind . -type d -exec chmod 755 {} \;
desde la carpeta raíz de la instalación de Kohana. - Asegúrate de que application/logs y application/cache no sean de sólo lectura. Haz
chmod
a 666 sobre ellas. - Ahora, apunta el navegador a http://localhost/kohana/ . Automáticamente, el framework llamará a
install.php
y comprobará los requerimientos con el servidor.
- Servidor con soporte de Unicode
- PHP con una versión igual o posterior a la 5.2.3
- Un servidor HTTP. Sugiero XAMPP, que es una herramienta sencilla todo-en-uno para instalar MySQL, PHP y Perl.
- Una base de datos (MsSQL, MySQL, MySQLi, PostgreSQL, PDOSqlite).
- PCRE
- iconv
- mcrypt
- SPL
Si alguna de las pruebas falla, deberás corregirla antes de continuar.
Si todas las comprobaciones tienen éxito, dirígete a la carpeta de Kohana y elimina o renombra el archivo
install.php
. Recarga la página en el navegador y verás una página de bienvenida como esta:Paso 4: Configurando Kohana
Kohana está preparado para funcionar. No se necesita realizar ninguna configuración. Este framework es genial, ¿no te parece? Vamos a ver un poco de código, sígueme.Paso 5: El primer proyecto con Kohana
Los tutoriales de programación tradicionales empiezan con el ejemplo "hello world". Pero yo creo que una aplicación simple puede dar una idea clara de cómo funciona el framework. Vamos a construir un gestor de colecciones de CDs -- sólo como divertida demostración. Antes de empezar a escribir código es necesaria una introducción breve a la distribución de carpetas de Kohana.Nuestra aplicación se ubicará en la carpeta application. En esta carpeta hay varias subcarpetas pero sólo necesitamos lo siguiente para nuestro proyecto:
- config guarda los archivos de configuración codificados como simples arrays estáticos.
- controllers guarda nuestra clase de controladores personalizada
- models guarda nuestra clase de modelos personalizada
- views guarda nuestro archivos personalizados escritos en HTML (o cualquier lenguaje de markup o scripts necesarios para mostrar los datos y los controles de interfície para el usuario)
La carpeta system guarda el núcleo de Kohana y herramientas como bibliotecas (library), asistentes (helper) y archivos de configuración predefinidos. En este proyecto vamos a usar algunas bibliotecas y algunos asistentes - buenas herramientas para acelerar tu trabajo.
La carpeta assets no pertenece a Kohana por defecto. Yo la he creado para guardar archivos estáticos como CSS, JS o imágenes. Después mostraré como incluirlos en el proyecto.
La carpeta modules es el lugar donde guardar las colecciones reusables de archivos relacionados que unidos aportan una funcionalidad particular a una aplicación. El módulo de autenticación de usuarios, ofrecido por el equipo Kohana, es un ejemplo de módulo.
Ésta es una muy breve introducción al sistema de archivos de Kohana, pero es suficiente para los propósitos de este tutorial. No quiero aburrirte con más teoría.
Paso 6: La base de datos del proyecto
He seleccionado MySQL para mi proyecto, pero recuerda que Kohana soporta igualmente MsSQL, MySQLi, PostgreSQL, o PDOSqlite. Crea una base de datos llamada "cd_collection" o elige el nombre que prefieras, y ejecuta la siguiente SQL mediante phpMyAdmin o cualquier herramienta para administrar la base de datos.
CREATE TABLE `albums` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) collate utf8_bin NOT NULL,
`author` varchar(50) collate utf8_bin NOT NULL,
`genre_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `genre_id` (`genre_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=19 ;
INSERT INTO `albums` (`id`, `name`, `author`, `genre_id`) VALUES
(2, 'Lines, Vines And Trying Times', 'Jonas Brothers', 16),
(3, 'The E.N.D.', 'The Black Eyed Peas', 16),
(4, 'Relapse', 'Eminem', 18),
(5, 'Monuments And Melodies', 'Incubus', 1),
(6, 'Thriller', 'Michael Jackson', 16),
(7, 'Back in Black', 'AC/DC', 4),
(8, 'The Dark Side of the Moon', 'Pink Floyd', 4),
(9, 'Bat out of Hell', 'Meat Loaf', 4),
(10, 'Backstreet Boys', 'Millennium', 16),
(11, 'Rumours', 'Fleetwood Mac', 4),
(12, 'Come on Over', 'Shania Twain', 16),
(13, 'Led Zeppelin IV', 'Led Zeppelin', 4),
(14, 'Jagged Little Pill', 'Alanis Morissette', 4),
(15, 'Sgt. Pepper''s Lonely Hearts Club Band', 'The Beatles', 16),
(16, 'Falling into You', 'Cv©line Dion', 16),
(17, 'Music Box', 'Mariah Carey', 16),
(18, 'Born in the U.S.A.', 'Bruce Springsteen', 4);
CREATE TABLE `genres` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) collate utf8_bin NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=22 ;
INSERT INTO `genres` (`id`, `name`) VALUES
(1, 'Alternative Rock'),
(2, 'Blues'),
(3, 'Classical'),
(4, 'Rock'),
(5, 'Country'),
(6, 'Dance'),
(7, 'Folk'),
(8, 'Metal'),
(9, 'Hawaiian'),
(10, 'Imports'),
(11, 'Indie Music'),
(12, 'Jazz'),
(13, 'Latin'),
(14, 'New Age'),
(15, 'Opera'),
(16, 'Pop'),
(17, 'Soul'),
(18, 'Rap'),
(20, 'Soundtracks'),
(21, 'World Music');
ALTER TABLE `albums`
ADD CONSTRAINT `genre_inter_relational_constraint` FOREIGN KEY (`genre_id`) REFERENCES `genres` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Como puedes ver, el SQL crea dos tablas, álbumes y géneros, y los puebla con algunos datos. La última sentencia SQL agrega una restricción para la clave ajena
"genre_id"
.La estructura de la base de datos es muy simple y no necesita mayor explicación:
Ahora, debes decirle a Kohana dónde está tu base de datos y cómo acceder a ella. Edita el archivo de configuración global system/config/database.php de esta forma:
$config['default'] = array
(
'benchmark' => TRUE,
'persistent' => FALSE,
'connection' => array
(
'type' => 'mysql',
'user' => 'root',
'pass' => 'root',
'host' => 'localhost',
'port' => FALSE,
'socket' => FALSE,
'database' => 'cd_collection'
),
'character_set' => 'utf8',
'table_prefix' => '',
'object' => TRUE,
'cache' => FALSE,
'escape' => TRUE
);
Este código le dice a Kohana que se conecte a una base de datos MySQL llamada
"cd_collection"
en localhost con el nombre de usuario "root"
y la clave "root"
. Debes cambiarlas de acuerdo con tu configuración de servidor de base de datos.Paso 7: Creando el controlador
Creémos nuestro primer controlador. Recuerda estas convenciones:- el nombre de archivo del controlador debe estar en minúsculas, por ejemplo
album.php
- la clase controlador debe coincidir con su nombre de archivo pero iniciada con mayúscula y debe añadir
_Controller
, por ejemplo Album_Controller - Debe tener la clase
Controller
como padre
http://hostname/carpeta_de_kohana/index.php/controller/function
Echa un vistazo a este simple controlador.
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Album_Controller extends Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
echo "My first controller";
}
}
PHP5 OOP (programación orientada a objetos) es un prerrequisito. Para aprender más sobre ello, puedes leer aquí.
La función constructor, llamada
__construct
, inicializa la clase y llama al constructor padre. La función index
es la función por defecto, por lo que será usada si llamamos al controlador sin especificar una función (por ejemplo, http://localhost/index.php/kohana/album. Tras el nombre del controlador no hay ninguna función, la función de índice será llamada por defecto).Dadas estas reglas básicas, enfoquémonos en la aplicación. El controlador de album implementa todas las acciones para la gestión de colección de álbumes. Este controlador nos permite crear un nuevo álbum, mostrar los álbumes guardados en la base de datos, actualizar un álbum o borrar un álbum.
Crea un archivo llamado
album.php
en application/controllers/ y pega los siguiente:
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Album_Controller extends Controller
{
private $album_model;
private $genre_model;
private $list_view;
private $create_view;
private $update_view;
public function __construct()
{
parent::__construct();
$this->album_model = new Album_Model;
$this->genre_model = new Genre_Model;
$this->list_view = new View('list');
$this->update_view = new View('update');
$this->create_view = new View('create');
}
public function index()
{
$this->show_albums_list();
}
private function show_albums_list()
{
$albums_list = $this->album_model->get_list();
$this->list_view->set('albums_list',$albums_list);
$this->list_view->render(TRUE);
}
public function show_create_editor()
{
$this->create_view->set('genres_list',$this->get_genres_list());
$this->create_view->render(TRUE);
}
public function show_update_editor($id)
{
$album_data = $this->album_model->read($id);
$this->update_view->set('album_id',$album_data[0]->id);
$this->update_view->set('name',$album_data[0]->name);
$this->update_view->set('author',$album_data[0]->author);
$this->update_view->set('genre_id',$album_data[0]->genre_id);
$this->update_view->set('genres_list',$this->get_genres_list());
$this->update_view->render(TRUE);
}
public function create()
{
$album_data=array(
'name' => $this->input->post('name'),
'author' => $this->input->post('author'),
'genre_id' => $this->input->post('genre_id')
);
$this->album_model->create($album_data);
url::redirect('album');
}
public function update()
{
$album_data = array(
'name' => $this->input->post('name'),
'author' => $this->input->post('author'),
'genre_id' => $this->input->post('genre_id')
);
$this->album_model->update($this->input->post('album_id'),$album_data);
url::redirect('album');
}
public function delete($id)
{
$this->album_model->delete($id);
url::redirect('album');
}
private function get_genres_list()
{
$db_genres_list = $this->genre_model->get_list();
$genres_list = array();
if(sizeof($db_genres_list) >= 1)
{
foreach($db_genres_list as $item)
{
$genres_list[$item->id] = $item->name;
}
}
return $genres_list;
}
}
Déjame explicar lo que hace este código.
Se declaran cinco variables miembro al inicio:
private $album_model;
private $genre_model;
private $list_view;
private $create_view;
private $update_view;
Estos miembros son privados porque quiero limitar su visibilidad sólo a esta clase.
En el método
construct
los objetos de modelo y vista son creados usando los cinco miembros:
$this->album_model = new Album_Model;
$this->genre_model = new Genre_Model;
$this->list_view = new View('list');
$this->update_view = new View('update');
$this->create_view = new View('create');
Para crear un objeto modelo usa esta sintaxis:
$obj_name = new Name_Model;
Para crear un objeto vista, usa esta sintaxis:
$obj_name = new View('view_filename_without_extension');
Ahora hay dos objetos para acceder al modelo de álbum y género, y tres objetos para acceder a las vistas necesarias para generar la presentación.
El método
index
llama al método show_albums_list
que lista todos los álbumes guardados en la base de datos.$albums_list = $this->album_model->get_list();
$this->list_view->set('albums_list',$albums_list);
$this->list_view->render(TRUE);
En este método puedes ver cómo el modelo y la vista objeto son usada para acceder a métodos relativos.
"get_list"
es un método del modelo (lo veremos luego) que devuelve todos los álbumes guardados en la base de datos. El resultado se guarda en el array "$album_list"
. Para pasar el array de resultados del controlador a la vista, el método "set"
del objeto vista es llamado. Este método requiere dos parámetros: una nueva variable vacía (album_list
) contiene datos de una variable existente ($album_list
). Ahora la nueva variable vacía "album_list"
contine el array $album_list
(veremos después como mostrar su contenido en la vista). El método "render"
, con el parámetro TRUE
, es necesario para generar datos para el navegador.El método
show_create_editor
muestra la interfície de usuario para insertar un nuevo álbum.1. $this->create_view->set('genres_list',$this->get_genres_list());
$this->create_view->render(TRUE);
La lista de géneros es pasada a la vista.
El método
show_update_editor
muestra la interfície de usuario para actualizar un álbum existente.
$album_data = $this->album_model->read($id);
$this->update_view->set('album_id',$album_data[0]->id);
$this->update_view->set('name',$album_data[0]->name);
$this->update_view->set('author',$album_data[0]->author);
$this->update_view->set('genre_id',$album_data[0]->genre_id);
$this->update_view->set('genres_list',$this->get_genres_list());
$this->update_view->render(TRUE);
"read"
es un método del modelo (lo veremos después) que devuelve datos ($album_data
) del álbum con un identificador igual a $id
. Entonces, cada elemento del álbum de datos devuelto es pasado a la vista.El método
create
recibe datos para un nuevo álbum a partir de la vista y guarda los datos recibidos en la base de datos.$album_data=array(
'name' => $this->input->post('name'),
'author' => $this->input->post('author'),
'genre_id' => $this->input->post('genre_id')
);
$this->album_model->create($album_data);
url::redirect('album');
$album_data
es un array que contiene los datos POST
de la vista. Para guardar el álbum, el array se pasa al método del modelo create
. La última línea es una llamada a un método asistente. Los asistentes (helpers) son funciones que te asisten en el desarrollo. Las clases asistente son automáticamente cargadas por Kohana. Los asistentes se declaran como métodos estáticos de una clase, por lo que no hay necesidad de instanciar la clase. En este caso, el método "redirect"
del asistente "url"
es llamado y le dice a Kohana que redirija el navegador al controlador de álbum. Esto evita una nueva inserción (por ejemplo, al pulsar F5).Los métodos
update
(actualizar) y delete
(borrar) funcionan de la misma forma que create
.El último método
get_genres_list
obtiene la lista de géneros del modelo ($db_genres_list
) y construye un nuevo array ($genres_list
) para el control de selección (select) en las vistas.$db_genres_list = $this->genre_model->get_list();
$genres_list = array();
if(sizeof($db_genres_list) >= 1)
{
foreach($db_genres_list as $item)
{
$genres_list[$item->id] = $item->name;
}
}
return $genres_list;
Paso 8: Creando el modelo para el proyecto
Creemos los modelos para nuestra aplicación web. Conviene recordar las convenciones indicadas anteriormente a la hora de crear las clases. A continuación está el código para el modelo del álbum. Crea un archivo llamadoalbum.php
en application/models/ y pega en él el siguiente código:Todos los métodos de los modelos usan la sintaxis del constructor de consultas (Query builder). Esta herramienta de Kohana acelera el tiempo de desarrollo con bases de datos y simplifica la creación de consultas.
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Album_Model extends Model
{
private $album_table;
private $genre_table;
public function __construct()
{
parent::__construct();
$this->album_table = 'albums';
$this->genre_table = 'genres';
}
public function read($id)
{
$this->db->where('id', $id);
$query = $this->db->get($this->album_table);
return $query->result_array();
}
public function delete($id)
{
$this->db->delete($this->album_table, array('id' => $id));
}
public function update($id,$data)
{
$this->db->update($this->album_table, $data, array('id' => $id));
}
public function create($data)
{
$this->db->insert($this->album_table, $data);
}
public function get_list()
{
$this->db->select('albums.id as id,albums.name as name,albums.author as author, genres.name as genre');
$this->db->from($this->album_table);
$this->db->join($this->genre_table,'genres.id','albums.genre_id');
$query = $this->db->get();
return $query->result_array();
}
}
Dos variables miembro son declaradas al inicio de la clase:
private $album_table;
private $genre_table;
Estos miembros son privados porque quiero limitar la visibilidad sólo a esta clase. Son los contenedores de los nombres de las tablas de la base de datos.
La primera línea en el método del constructor carga la biblioteca de base de datos de Kohana en
$this->db
. En las dos siguientes líneas, se inicializan las dos variables miembro.parent::__construct();
$this->album_table = 'albums';
$this->genre_table = 'genres';
La consulta en el método
read
recupera los registros de álbum que tengan un cierto identificador ("$id"
).$this->db->where('id', $id);
$query = $this->db->get($this->album_table);
return $query->result_array();
La consulta en el método
delete
elimina la fila de la tabla de álbumes que tenga un cierto identificador ("$id"
).$this->db->delete($this->album_table, array('id' => $id));
La consulta en el método
update
actualiza la fila de la tabla de álbumes que tenga un cierto identificador ("$id"
) con los nuevos valores del array "$data"
.$this->db->update($this->album_table, $data, array('id' => $id));
El array
"$data"
debe contener nombres de registros como claves del array, y sus valores como valores del array. El array debe tener esta forma:$data = array(
'name' => 'album_name',
'author' => 'author_name',
'genre_id' => 'genre_id'
);
La consulta en el método
get_list
recupera todas las filas de álbumes.$this->db->select('albums.id as id,albums.name as name,albums.author as author, genres.name as genre');
$this->db->from($this->album_table);
$this->db->join($this->genre_table,'genres.id','albums.genre_id');
$query = $this->db->get();
return $query->result_array();
Ahora el modelo para los géneros. Crea un archivo llamado
genre.php
en application/models/ y pega el siguiente código en él:<?php defined('SYSPATH') OR die('No direct access allowed.');
class Genre_Model extends Model
{
private $genre_table;
function __construct()
{
parent::__construct();
$this->genre_table = 'genres';
}
function get_list()
{
$query = $this->db->get($this->genre_table);
return $query->result_array();
}
}
Este modelo es muy simple, por lo que no malgasteré tiempo comentándolo. Los modelos y el controlador están preparados para funcionar. Ahora trabajemos sobre las vistas.
Paso 9: Creando la vista del proyecto
Las vistas son archivos que contienen la capa de presentación de la aplicación. Su propósito es mantener esta información separada de la lógica de la aplicación para facilitar la reusabilidad y mantener el código limpio. Para este proyecto se necesitan tres vistas: una para listar la colección de álbumes, otra para crear un nuevo álbum, y otra para editar un álbum existente.Crea un archivo llamado
list.php
en application/views/ y pega el siguiente código en él:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<?php
echo html::stylesheet(array
(
'assets/css/style'
),
array
(
'screen'
), FALSE);
?>
<title>CD COLLECTION</title>
</head>
<body>
<?php
echo html::image('assets/images/add.png');
echo html::anchor('album/show_create_editor', 'Add new album');
?>
<table class="list" cellspacing="0">
<tr>
<td colspan="5" class="list_title">CD Collection</td>
</tr>
<tr>
<td class="headers">Album name</td>
<td class="headers">Author</td>
<td colspan='3' class="headers">Genre</td>
</tr>
<?php
foreach($albums_list as $item)
{
echo "<tr>";
echo "<td class='item'>".$item->name."</td>";
echo "<td class='item'>".$item->author."</td>";
echo "<td class='item'>".$item->genre."</td>";
echo "<td class='item'>".html::anchor('album/delete/'.$item->id,html::image('assets/images/delete.png'))."</td>";
echo "<td class='item'>".html::anchor('album/show_update_editor/'.$item->id,html::image('assets/images/edit.png'))."</td>";
echo "</tr>";
}
?>
</table>
</body>
</html>
Esta vista muestra una página html que contiene una lista de todos los álbumes. Esta lista ha sido creada usando un bucle
foreach
que imprime la información en una tabla html. Para cada fila de álbum, hay dos imágenes: una "cruz roja" y una "libro de bolsillo". Enlazan respectivamente al método delete
y al método update
del controlador. Ambos pasan el identificador del álbum al controlador usando una petición GET
. Sobre la lista hay un botón para crear un nuevo álbum. En este código también se usa un asistente html ofrecido por Kohana que acelera las operaciones para escribir páginas html.Creémos ahora un archivo llamado
create.php
en application/views/.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<?php
echo html::stylesheet(array
(
'assets/css/style'
),
array
(
'screen'
), FALSE);
?>
<title>CD COLLECTION</title>
</head>
<body>
<?php echo form::open('album/create'); ?>
<table class='editor'>
<tr>
<td colspan='2' class='editor_title'>Create new album</td>
</tr>
<?php
echo "<tr>";
echo "<td>".form::label('name', 'Name: ')."</td>";
echo "<td>".form::input('name', '')."</td>";
echo "</tr>";
echo "<tr>";
echo "<td>".form::label('author', 'Author: ')."</td>";
echo "<td>".form::input('author', '')."</td>";
echo "<tr/>";
echo "<tr>";
echo "<td>".form::label('genre', 'Genre: ')."</td>";
echo "<td>".form::dropdown('genre_id',$genres_list)."</td>";
echo "<tr/>";
echo "<tr>";
echo "<td colspan='2' align='left'>".form::submit('submit', 'Create album')."</td>";
echo "</tr>";
?>
</table>
<?php echo form::close(); ?>
</body>
</html>
La última es la vista de actualización. Crea un archivo
update.php
en application/views/.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<?php
echo html::stylesheet(array
(
'assets/css/style'
),
array
(
'screen'
), FALSE);
?>
<title>CD COLLECTION</title>
</head>
<body>
<?php echo form::open('album/update'); ?>
<table class='editor'>
<tr>
<td colspan='2' class='editor_title'>Update album</td>
</tr>
<?php
echo "<tr>";
echo "<td>".form::label('name', 'Name: ')."</td>";
echo "<td>".form::input('name', $name)."</td>";
echo "</tr>";
echo "<tr>";
echo "<td>".form::label('author', 'Author: ')."</td>";
echo "<td>".form::input('author', $author)."</td>";
echo "<tr/>";
echo "<tr>";
echo "<td>".form::label('genre', 'Genre: ')."</td>";
echo "<td>".form::dropdown('genre_id',$genres_list, $genre_id)."</td>";
echo "<tr/>";
echo "<tr>";
echo "<td colspan='2' align='left'>".form::submit('submit', 'Update album')."</td>";
echo "</tr>";
?>
</table>
<?php
echo form::hidden('album_id',$album_id);
echo form::close();
?>
</body>
</html>
El primero es un editor simple que permite al usuario insertar información sobre un nuevo álbum. Los campos como autor y nombre serán insertados usando una entrada html y el género usando un combo. Una vez que el usuario hace click en el botón create, toda la información se pasa como una petición
POST
al método create
/update
del controlador de álbum. Cuando el controlador recibe estas variables posteadas llama al modelo que inserta un nuevo álbum en la base de datos. Los formularios de ambas vistas hacen uso del asistente de formularios.Para dar un poco de estilo a nuestra aplicación, crea la carpeta assets en la carpeta raíz de Kohana al mismo nivel de la carpeta de aplicaciones. Ábrelo y crea dos nuevas carpetas: css e images.
En la carpeta css crea un nuevo archivo llamado
style.css
y pega lo siguiente en él:a {
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif ;
font-weight: normal;
font-size: 12px;
color: #00F;
vertical-align:text-top;
}
img {
border: 0;
}
label {
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif ;
font-weight: normal;
font-size: 12px;
}
input {
border: 1px solid #000;
}
select {
width:185px;
}
table.editor
{
text-align: center;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif ;
font-weight: normal;
font-size: 11px;
color: #fff;
width: 280px;
background-color: #666;
border: 0px;
border-collapse: collapse;
border-spacing: 0px;
}
table.editor td.editor_title
{
background-color: #666;
color: #fff;
padding: 4px;
text-align: left;
font-weight: bold;
font-size: 16px;
}
table.editor td
{
padding: 4px;
}
table.list
{
text-align: center;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif ;
font-weight: normal;
font-size: 11px;
color: #fff;
width: 280px;
background-color: #666;
border: 0px;
border-collapse: collapse;
border-spacing: 0px;
}
table.list td.item
{
background-color: #CCC;
color: #000;
padding: 4px;
text-align: left;
border: 1px #fff solid;
}
table.list td.list_title,table.list td.headers
{
background-color: #666;
color: #fff;
padding: 4px;
text-align: left;
border-bottom: 2px #fff solid;
font-weight: bold;
}
table.list td.list_title
{
font-size: 16px;
}
table.list td.headers
{
font-size: 12px;
}
Ahora copia las siguientes imágenes en la carpeta images:
Eso es todo. Apunta el navegador a http://localhost/kohana/index.php/album y deberías ver algo parecido a esto:
Si intentas crear un nuevo álbum o editar uno existente, deberías ver algo similar a esto:
Paso 10: Pensamientos finales
Desde luego, algunas mejoras son necesarias para esta aplicación, pero con muy poco código has creado una pequeña aplicación web. Ahora, sabes cómo usar el patrón MVC con Kohana, y cómo usar las bibliotecas y asistentes de la base de datos. Para aprender más, lee la documentación oficial.Gracias a Kohana, el mantenimiento de código se convierte en una tarea fácil, y añadir nuevas características es pan comido. Espero que hayas disfrutado del tutorial.