Introducción
Temma en 3 minutos
Temma es un Modelo-Vista-Controlador (MVC), diseñado para facilitar y acelerar el desarrollo de sitios web.
El framework se encarga de las peticiones entrantes, evitando que tengas que redesarrollar una y otra vez las capas más bajas de tus aplicaciones, dejándote libre para concentrarte en el “código de negocio”, la parte más importante.
Su filosofía: convenciones simples en lugar de configuración.
- Ninguna ruta que declarar: por defecto, la URL /articles/show/2 llama al método show(2) del controlador Articles.
- Ninguna consulta SQL que escribir en los casos simples: el framework crea por sí mismo el objeto de acceso a la tabla correspondiente.
- Ninguna vista que conectar: la plantilla asociada a la acción se interpreta automáticamente; para las APIs, la vista JSON se activa en una línea.
El resto de esta página lo demuestra con un ejemplo completo.
0Con un agente de IA
Si programas con un agente de programación (Claude Code, Codex, Copilot…), no tienes nada que instalar a mano. Basta con darle esta frase:
Crea un sitio web usando Temma (temma.net/go) |
El agente lee temma.net/go, una guía de instalación ejecutable: comprueba los requisitos, crea el proyecto, configura la base de datos y el servidor web, y arranca el sitio. A partir de ahí dispone de los skills de IA de Temma, instalados en el proyecto, para escribir código conforme a las convenciones del framework.
El resto de esta página sigue siendo útil: explica cómo funciona Temma y, por tanto, qué habrá producido el agente.
1Principios básicos
Temma facilita el desarrollo de sitios compuestos por URLs como:
http://www.site.com/controller/action/p1/p2/p3
Las URLs se dividen en 3 partes:
- El nombre del controlador, un objeto que será instanciado al recibir la petición.
- El nombre de la acción, un método de este objeto que será llamado.
- Un número variable de parámetros que este método podrá usar.
Entonces se ejecutará el siguiente código:
Controller::action(p1, p2, p3)
Por defecto, el framework generará una página interpretando el archivo de plantilla templates/controller/action.tpl
Del lado del modelo, Temma puede crear automáticamente un DAO (Data Access Object, objeto de acceso a datos): un objeto que lee y escribe en la tabla con el nombre del controlador, sin SQL que escribir. Para las consultas complejas, retomas el control escribiendo tu propio DAO.
Obviamente, es posible modificar los comportamientos por defecto. Un controlador puede optar por leer los datos recibidos por POST en lugar de − o además de − los recibidos en la URL o como parámetros GET. Una acción puede definir una plantilla específica a usar, o incluso definir un tipo de vista completamente diferente (que generará JSON o XML en lugar de HTML, por ejemplo).
La página del flujo de ejecución detalla todo lo que hace Temma entre el momento en que recibe la petición y el momento en que envía la respuesta.
2Ejemplo de desarrollo
Para este ejemplo, vamos a crear un sitio web muy simple con dos páginas:
- /articles/list: muestra la lista de artículos.
- /articles/show/2: muestra el artículo cuyo identificador es 2.
Puedes leer este ejemplo sin instalar nada.
Hay cuatro archivos implicados, indicados en negrita a continuación. El archivo de configuración ya existe después de la instalación, y vamos a rellenarlo; los otros tres son los que vamos a escribir:
mi_proyecto/
controllers/
Articles.php
etc/
temma.php
templates/
articles/
list.tpl
show.tpl
Fíjate en el directorio templates/articles/: su nombre es el del controlador, y el nombre de cada plantilla que contiene es el de una acción. Es la convención de nombres mencionada más arriba.
2.1Configuración
Lo primero que hay que hacer es crear el archivo de configuración del proyecto. Es el archivo etc/temma.php.
Consulta la documentación de configuración para conocer las diferentes opciones.
La instalación de Temma proporciona archivos de ejemplo, pero aquí está el contenido del que vamos a usar:
<?php
return [
'application' => [
'dataSources' => [
// configuración de la base de datos
'db' => 'mysql://user:passwd@localhost/mybase'
],
// configuración del controlador raíz
'rootController' => 'Articles'
],
// umbral de escritura de logs
'loglevels' => 'WARN',
// variables de plantilla importadas automáticamente
'autoimport' => [
'siteName' => 'Sitio de demostración'
]
];
- Línea 7: Configuración de la conexión a la base de datos. La fuente se llama db, que es el nombre que el DAO busca por defecto.
- Línea 10: La directiva rootController sirve para definir el controlador raíz del sitio, es decir, el que responderá cuando nos conectemos a la dirección http://www.my-site.com/.
- Línea 13: Definimos el nivel mínimo de errores que se registrarán en el archivo log/temma.log.
- Línea 16: Definimos una variable de plantilla que contiene el nombre del sitio. Las variables importadas automáticamente se agrupan bajo la variable conf, así que esta se leerá en las plantillas escribiendo {$conf.siteName}.
2.2Base de datos
Antes que nada, vamos a crear una tabla en la base de datos. Necesitas ejecutar la siguiente consulta en tu base de datos:
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT,
title TINYTEXT,
text MEDIUMTEXT,
author TINYTEXT,
PRIMARY KEY (id)
);
Aquí hay dos detalles de nombres que tienen su importancia, porque Temma se basará en ellos para crear automáticamente el DAO que hará el enlace con esta tabla (como veremos en la sección siguiente):
- La tabla se llama articles, como el controlador que vamos a escribir.
- Su clave primaria se llama id.
Son las dos convenciones por defecto de Temma. Se pueden cambiar (consulta la documentación del DAO genérico), pero respetarlas permite no tener nada que configurar.
Y podemos añadirle datos:
INSERT INTO articles (title, text, author)
VALUES ('Primer artículo', 'Texto del primer artículo', 'John'),
('Segundo artículo', 'Texto del segundo artículo', 'Bob'),
('Tercer artículo', 'Texto del tercer artículo', 'John');
2.3Controlador
Vamos a escribir nuestro primer controlador. Un controlador es un objeto que recibe conexiones y las gestiona para enviar datos de vuelta.
Los controladores tienen acciones, y a cada acción se le pueden asignar parámetros.
Nuestro controlador se llamará Articles. En lugar de escribirlo de una sola vez, empecemos por lo estrictamente necesario: lo justo para mostrar la lista de artículos.
En el directorio controllers/ de tu proyecto, crea un archivo llamado Articles.php.
Una línea merece atención antes de leer el código: $_temmaAutoDao. Al declarar este atributo, le pedimos a Temma que cree automáticamente el DAO que servirá para acceder a los datos. Se configurará para usar la tabla articles, basándose en el nombre del controlador. Estará disponible en el atributo $this->_dao del controlador, que podrá usarlo para consultar la base de datos sin escribir SQL.
<?php
/** Controlador de gestión de artículos. */
class Articles extends \Temma\Web\Controller {
/** Indica al framework que debe crear automáticamente el DAO. */
protected $_temmaAutoDao = true;
/** Acción que muestra la lista de artículos. */
public function list() {
// recuperación de la lista de elementos desde la base de datos
$articles = $this->_dao->search();
// la lista se pone a disposición de la plantilla
$this['articles'] = $articles;
}
}
- Línea 4: Los controladores deben heredar del objeto \Temma\Web\Controller.
- Línea 6: Se solicita el DAO. Temma lo crea antes de que se ejecute la acción.
- Línea 9: La acción list, que responde a la URL http://www.my-site.com/articles/list
-
Línea 11: El método search() del DAO devuelve todas las filas de la tabla, en forma de una
lista de arrays asociativos cuyas claves son los nombres de las columnas:
Es esta estructura la que volveremos a encontrar en la plantilla.[ ['id' => 1, 'title' => 'Primer artículo', 'text' => '...', 'author' => 'John'], ['id' => 2, 'title' => 'Segundo artículo', 'text' => '...', 'author' => 'Bob'], ['id' => 3, 'title' => 'Tercer artículo', 'text' => '...', 'author' => 'John'], ] - Línea 14: Copiamos el valor de la variable $articles en la variable de plantilla articles. La plantilla usada será (implícitamente) el archivo templates/articles/list.tpl.
Con esto ya funciona la página de lista. Aquí está ahora el controlador completo: le hemos añadido la acción show(), que muestra un solo artículo, y la acción raíz __invoke(), cuyo único papel es recibir las conexiones en la raíz del sitio y redirigirlas a la lista de artículos.
<?php
/** Controlador de gestión de artículos. */
class Articles extends \Temma\Web\Controller {
/** Indica al framework que debe crear automáticamente el DAO. */
protected $_temmaAutoDao = true;
/** Acción raíz (sin acción explícita). */
public function __invoke() {
// redirección a la lista de artículos
$this->_redirect('/articles/list');
}
/** Acción que muestra la lista de artículos. */
public function list() {
// recuperación de la lista de elementos desde la base de datos
$articles = $this->_dao->search();
// la lista se pone a disposición de la plantilla
$this['articles'] = $articles;
}
/**
* Acción que muestra el contenido completo de un artículo.
* @param int $id Identificador del artículo.
*/
public function show(int $id) {
// recuperación del contenido del artículo desde la base de datos
$article = $this->_dao->get($id);
// comprobamos si el elemento solicitado existe o no
if (!$article) {
// no existe, redirigimos a la lista
$this->_redirect('/articles/list');
} else {
// existe, los datos se envían a la plantilla
$this['article'] = $article;
}
}
}
-
Línea 9: La acción raíz se ejecuta cuando no se solicita ninguna acción en concreto.
Como este controlador se ha definido como el controlador raíz (rootController en el archivo etc/temma.php),
esta es, por tanto, la acción que se llamará al acceder a la raíz del sitio.
- Esta acción responde a las siguientes dos URLs:
http://www.my-site.com/
http://www.my-site.com/articles - Línea 11: El internauta es redirigido a la página que muestra la lista de artículos.
- Esta acción responde a las siguientes dos URLs:
-
Línea 27: La acción show, que muestra el contenido de un artículo cuyo identificador se
proporciona como parámetro en la URL. El parámetro $id del método recibe el valor leído en la URL,
convertido a entero.
- Esta acción responde a la URL: http://www.my-site.com/articles/show/2
- Línea 29: El método get() del DAO recupera una sola fila a partir de su identificador, y la devuelve en forma de array asociativo (o un valor vacío si no existe).
- Línea 34: Si el artículo no existe, redirigimos a la lista de artículos.
- Línea 37: Si el artículo existe, lo guardamos como una variable de plantilla. La plantilla usada será (implícitamente) el archivo templates/articles/show.tpl.
2.4Plantillas
Temma usa el motor de plantillas Smarty, que es muy popular y tiene una sintaxis muy fácil de entender.
Para la página que muestra la lista de artículos, vamos a crear el archivo templates/articles/list.tpl:
<html>
<head>
<title>{$conf.siteName}</title>
</head>
<body>
<ul>
{* bucle sobre la lista de artículos *}
{foreach $articles as $article}
{* añade un enlace al artículo *}
<li>
<a href="/articles/show/{$article.id}">
{$article.title}
</a>
</li>
{/foreach}
</ul>
</body>
</html>
- Línea 3: El nombre del sitio se coloca en la etiqueta <title>. Proviene de la directiva autoimport del archivo de configuración. Se escapa, para convertir los posibles caracteres especiales en entidades HTML.
- Línea 8: Bucle sobre los elementos de la lista de artículos, la que el controlador guardó en la variable de plantilla articles.
- Líneas 11 a 15: Creación del enlace a la página de un artículo. Cada $article es uno de los arrays asociativos devueltos por el DAO, así que sus columnas se leen escribiendo {$article.id} y {$article.title}. El título del artículo se escapa automáticamente, para convertir los caracteres especiales en entidades HTML.
Para la página que muestra un artículo, vamos a crear el archivo templates/articles/show.tpl:
<html>
<head>
<title>{$conf.siteName}</title>
</head>
<body>
{* muestra el título del artículo *}
<h1>{$article.title}</h1>
{* muestra el autor del artículo *}
<h2>por {$article.author}</h2>
<p>
{* muestra el contenido del artículo *}
{$article.text|raw}
</p>
</body>
</html>
- Línea 3: El nombre del sitio se coloca en la etiqueta <title>, y sus caracteres especiales se escapan automáticamente.
- Línea 7: El título del artículo se coloca en una etiqueta H1, y sus caracteres especiales se escapan automáticamente.
- Línea 10: El nombre del autor se coloca en una etiqueta H2, y sus caracteres especiales se escapan automáticamente.
- Línea 14: El texto del artículo se coloca en un párrafo (etiqueta P), y solicitamos explícitamente que su contenido no se escape (ya es HTML).
2.5Resumen
Esto es lo que muestra el navegador:
Y esta es la cadena que Temma ha recorrido para producir la página de un artículo:
- El internauta solicita /articles/show/2.
- Temma instancia el controlador Articles y crea su DAO, configurado para la tabla articles.
- Temma llama a la acción show(2), que consulta la tabla mediante $this->_dao y deposita el resultado en una variable de plantilla.
- Temma interpreta la plantilla templates/articles/show.tpl con esa variable, y devuelve el HTML obtenido.
No has escrito ninguna consulta SQL, ni código de enrutamiento, ni pegamento entre las capas: solamente los tres archivos del ejemplo.
Una última cosa: basta una línea para que este controlador se convierta en una API que devuelve JSON, gracias a las vistas. Temma sabe incluso hacer negociación de contenido: el mismo controlador puede entonces enviar HTML o JSON, según lo que pida el cliente.
3Para saber más
- Instalar Temma: crear un proyecto y ponerlo en marcha.
- Documentación completa de Temma
- DAO genérico: todo lo que sabe hacer el objeto $this->_dao (criterios de búsqueda, ordenaciones, creación, modificación, eliminación).
- Controladores: todos los métodos y atributos disponibles en tus controladores.
- Flujo de ejecución: lo que hace Temma entre la petición y la respuesta.
- Tutoriales: ejemplos completos, desde una API REST hasta un chat en tiempo real.