Construir un Tema desde Cero
Los themes de Chinaski son un directorio de archivos de Template Toolkit: un par de shells HTML más un partial de head, y cada tipo de bloque se renderiza vía su propio template. Esta guía recorre la creación del tuyo de punta a punta: scaffolding, escritura de templates, cableado de bloques y menús, y testing.
Para empezar: tres maneras
- Clona un starter theme registrado en la pantalla de Themes; el nuevo slug recibe una copia completa para editar.
- Genera con Claude; el panel de Themes toma un nombre, un Design Brief opcional (elige un diseño de referencia previamente subido, o sube uno al momento) y opcionalmente un Design Intent de un párrafo. Create Theme Scaffold clona los archivos starter, luego muestra un prompt listo para copiar nombrando tu theme, brief e intent; entrégaselo a tu asistente conectado vía MCP, que leerá la guía de themes integrada y escribirá los archivos por ti.
- Manualmente; copia
builder/site_templates/abuilder/themes/<your-slug>/y edita las copias al mismo contrato de abajo.
Cualquiera de las rutas crea el slug y lo registra en la tabla de themes; la pantalla de Themes muestra qué theme está activo actualmente, y solo los themes no activos pueden borrarse.
Los archivos que lleva un theme
El map de archivos del theme por defecto está en la página Letterbox; cada template ahí (_head.tt, _header.tt, _footer.tt, page.tt, post.tt, blog_index.tt, más 404.tt, documents.tt, search.tt, offline.tt) pertenece a un theme. Tu theme de reemplazo recrea cualquier subconjunto por nombre; los templates en page.tt/post.tt/blog_index.tt son los que el builder busca.
Declara los slots de menú escribiendo un comentario marcador al inicio de un template: [%# MENU_SLOT: header %]. La pantalla de Navigation toma cada slot declarado de tu theme y lo ofrece cuando creas un elemento de nav.
El contrato del renderer
builder/build.pl lee la base de datos SQLite y corre cada página y post publicados por Template Toolkit, escribiendo el HTML resultante bajo output/<lang>/:
- renderiza páginas, posts, los índices de blog + categoría, el feed RSS, el sitemap, robots.txt y el 404
- copia
public/media/por idioma - limpia el output no escrito en esta corrida (elementos borrados, sin publicar, fuera de ventana)
- honra el promotion guard, el write budget y el timeout general del build
Las fallas de render de templates no abortan un build; el template fallido se registra y el build continúa (visible vía Build history / dashboard).
Template Toolkit en breve
Usa | html para cualquier campo controlado por el usuario y | uri para los componentes de URL. IF/UNLESS/FOREACH cubre los loops (loop.index, loop.count, loop.last). Los includes comparten los partials integrados por stash ([% INCLUDE '_head.tt' %]).
Cada template de site recibe variables documentadas; page.tt recibe título, cuerpo, slug, idioma, meta fields, OG fields, imagen destacada y settings de nivel site como site_name, url_base; post.tt adicionalmente recibe excerpt, autor, categoría, tags, custom fields; blog_index.tt recibe el listado de posts y el objeto de paginación. Los docs del theme integrado listan las tablas completas de variables por template y los detalles.
Blocks
builder/block_templates/*.tt; un archivo por tipo de bloque; son markup independiente del theme, así que los themes estilizan los bloques por nombre de clase en lugar de por markup. La stylesheet del theme por defecto (_head.tt) implementa cada clase wrapper/inner documentada en la referencia de clases de bloques integrada; tu _head.tt debe cubrir el mismo contrato (o los bloques se renderizan sin estilo). Cualquier {{block:name}} inline en un cuerpo llega ya renderizado en la variable de cuerpo de tu template; coordina las clases CSS en lugar de reescanear marcadores.
Testing mientras tu theme está inactivo
- Preview; el enlace de preview de la pantalla de Themes renderiza vistas de muestra de página, post y blog desde el theme en progreso sin tocar el site en vivo (con datos reales de nav del idioma por defecto).
- Build real; haz clic en Build (o corre
perl builder/build.pl), revisa el dashboard y el Build history para el output completo del build y los nombres de templates fallidos. - Iteraciones seguras; corre el builder con
CHINASKI_OUTPUT=/tmp/previewpara escribir a otro directorio y no tocar tu site en vivo.
Reglas de seguridad para construir
- escapa los scalars controlados por el usuario con
| html; excepciones: los cuerpos de páginas/posts (intencionalmente raw) y el JSON-LD que te llega pre-escapado - usa
| urien los componentes de URL construidos de input de usuario; nunca concatenes valores raw enhref/src - los valores de campos de bloque vienen de formularios del admin; igualmente no confiables, escápalos
- el contenido de snippets es verbatim; audita quién puede editar snippets (ese permiso está a un paso de correr JavaScript arbitrario de terceros en tu site público)
- minimiza los bloques
<script>inline; el CSP del site estático los permite hoy, pero cada script inline adicional ensancha la superficie de XSS si alguna vez aterriza una inyección de cuerpo
Enviarlo
Cuando el nuevo theme se vea bien en preview, actívalo en Themes; el theme viejo sigue disponible; borrar un theme se permite solo para los no activos. Cambiar el theme activo invalida el estado del build incremental, así que el siguiente build después del switch es uno completo, y el output en vivo usará consistentemente los templates nuevos.