Núcleo
Vistas, themes y widgets
Themes
Un theme es una carpeta de webroot/themes/ con las plantillas Smarty y los recursos de una apariencia. El sitio público usa el de Templates.Theme; el panel usa inspinia (lo fija AdminSuperController).
webroot/themes/<theme>/
├── css/ js/ img/ recursos (Koshkil::getThemePath('css/theme.css'))
└── templates/
├── front/ plantillas del sitio ($templateFolder = "front")
│ ├── main.tpl layout
│ ├── index/index.tpl IndexController::index()
│ └── cuentas/…
├── admin/ plantillas del panel
├── widgets/
│ └── front/header.tpl widget THeader del grupo "front"
└── error/ error.tpl, error404.tpl, error4xx.tpl, error500.tpl
Para crear un theme nuevo, copiá uno existente (por ejemplo brillare) y cambiá Templates.Theme en la configuración del dominio.
Dónde se buscan las plantillas
La vista busca primero en templates/<templateFolder>/ y después en templates/. Así, index/index.tpl se resuelve en templates/front/index/index.tpl y error/error404.tpl en templates/error/. Dentro de un plugin, se usan las plantillas de plugins/<plugin>/webroot/templates/.
Las plantillas compiladas se guardan en tmp/cache/view/<theme>/.
El layout
Controller::$templateFile (normalmente main.tpl) es la página completa. Recibe en $template la plantilla de la acción y la incluye:
{* templates/front/main.tpl *}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>{if $webpageTitle}{$webpageTitle} · {/if}{Configure::read('Web.SiteName')}</title>
<link rel="stylesheet" href="{Koshkil::getThemePath('css/theme.css')}">
{foreach Configure::read('styles') as $style}<link rel="stylesheet" href="{$style}">{/foreach}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>var MAIN_URL='{Koshkil::GetLink('/')}';</script>
</head>
<body>
{html_widget type="front.header"}
<main{if $data_controller} data-controller="{$data_controller}"{/if}>
{html_include file="{$template}"}
</main>
{html_widget type="front.footer"}
{html_widget type="front.scripts"}
</body>
</html>
En las plantillas están disponibles todas las variables asignadas con $this->set(), además de $usuario (si hay sesión), $Response y $_SERVER. Las clases estáticas se pueden llamar directamente: {Koshkil::getLink('/')}, {Configure::read('Web.SiteName')}.
Scripts y estilos por página
Desde el controlador se agregan archivos que el layout y el widget de scripts imprimen:
WebElements::addScript(Koshkil::getThemePath('js/productos.js'));
WebElements::addScript('https://www.google.com/recaptcha/api.js');
WebElements::addScript('/js/primero.js', true); // al principio de la lista
WebElements::addStyle('/css/plugins/datatables.css');
Se acumulan en Configure::read('scripts') y Configure::read('styles') sin duplicados. Con Debug.Javascript en false, si existe archivo.min.js se usa esa versión.
Widgets
Un widget es un componente de interfaz con su propia lógica y plantilla: cabecera, pie, menú, buscador…
{html_widget type="front.header"}
{html_widget type="admin.uploads" name="galeria"}
{html_widget type="plugins.noticias.front.noticias"} {* widget de un plugin *}
type |
Clase | Archivo | Plantilla |
|---|---|---|---|
front.header |
THeader |
src/Widgets/front/THeader.php |
templates/widgets/front/header.tpl |
admin.uploads |
TUploads |
src/Widgets/admin/TUploads.php |
templates/widgets/admin/uploads.tpl |
plugins.noticias.front.noticias |
TNoticias |
plugins/noticias/src/Widgets/Front/TNoticias.php |
plugins/noticias/webroot/templates/widgets/front/noticias.tpl |
<?php
// src/Widgets/front/TDestacados.php
Koshkil::Uses('sys.web.TWidget');
Koshkil::UsesModel('productos');
class TDestacados extends TWidget {
public function run() {
$cantidad = intval($this->parameters['cantidad'] ?? 4);
$this->set([
'destacados' => TMProductos::where('prd_destacado', '1')->take($cantidad)->get(),
]);
}
}
{html_widget type="front.destacados" cantidad=6}
El widget ejecuta create(), init() y run(); init() configura las carpetas de plantillas, así que si lo sobrescribís llamá a parent::init(). Los parámetros de la etiqueta llegan en $this->parameters y la plantilla recibe también todas las variables del controlador.
Plugins de Smarty incluidos
Están en src/Smarty/plugins/ y se registran solos.
| Etiqueta | Tipo | Uso |
|---|---|---|
{html_include file="…"} |
función | Incluye una plantilla relativa a la carpeta del theme; si no existe, muestra error/error404.tpl. Acepta plugin="nombre". |
{html_widget type="…"} |
función | Ejecuta un widget. |
{t key="…" domain="…"} |
función | Traducción (ver Internacionalización). |
{trans}clave{/trans} |
bloque | Traducción de bloque. |
{rule_or_role roles="…" rules="…"}…{/rule_or_role} |
bloque | Muestra el contenido solo si el usuario tiene el rol o la regla. |
{field_maxlength model="…" field="…"} |
función | Imprime maxlength="N" según el largo de la columna. |
{call_method name="…"} |
función | Llama a un método público del controlador. |
{include_plugins folder="…"} |
función | Incluye las plantillas de esa carpeta de todos los plugins activos. |
{include_plugins_scripts file="…"} |
función | Imprime los <script> de ese archivo en todos los plugins activos. |
|t |
modificador | Traducción: {'save'|t} (dominio common). |
|formatdate:"DD/MM/YYYY" |
modificador | Formato de fecha con nombres en español (DDDD, MMMM, HH, mm…). |
|elapsed |
modificador | Tiempo transcurrido desde una fecha. |
|excerpt:120 |
modificador | Resumen de un texto. |
|slug |
modificador | Texto apto para URL. |
|decamelize, |php_strtolower, |php_ucwords, |replace_str |
modificadores | Utilidades de texto. |
|php_json_encode, |php_base64_encode |
modificadores | Codificación. |
|gravatar |
modificador | URL del avatar de Gravatar de un email. |
Para agregar los tuyos, creá src/Smarty/plugins/function.mifuncion.php (o modifier., block.) con la función smarty_function_mifuncion($params, $template).
Escapá lo que viene del usuario
Smarty no escapa por defecto. Usá {$variable|escape} para todo texto ingresado por usuarios.