Guía de Uso Avanzado
Esta guía cubre patrones avanzados y técnicas de personalización para el microframework Alxarafe.
Creación de Módulos
Los módulos son la unidad organizativa principal en Alxarafe. Un módulo es un directorio dentro de Modules/ (aplicación) o src/Modules/ (núcleo del framework) siguiendo la convención de namespace PSR-4:
- Namespace:
Modules\{ModuleName}\Controller. - Directorio:
Modules/{ModuleName}/Controller/. - Nomenclatura: Los archivos deben llamarse
{Accion}Controller.php.
Módulo Mínimo
Para registrar un nuevo módulo, solo necesitas un controlador con el atributo #[ModuleInfo] en cualquiera de sus clases (generalmente el controlador principal).
namespace Modules\Blog\Controller;
use Alxarafe\Base\Controller\Controller;
use Alxarafe\Attribute\ModuleInfo;
#[ModuleInfo(name: 'Blog', description: 'Módulo de blog simple', icon: 'fas fa-blog')]
class PostController extends Controller {
// ...
}Sistema de Hooks (Ganchos)
Alxarafe implementa un potente sistema de hooks síncronos (HookService) que te permite interceptar la lógica del framework o crear tus propios puntos de extensión.
Registro de un Hook
Los hooks deben registrarse durante el bootstrap de la aplicación.
use Alxarafe\Service\HookService;
use Alxarafe\Service\HookPoints;
HookService::register(
HookService::resolve(HookPoints::AFTER_SAVE, ['entity' => 'Post']),
function($post) {
// Limpiar caché del blog después de guardar una entrada
Cache::forget('blog_posts');
}
);Creación de Hooks Personalizados
Puedes definir tus propios hooks en tu lógica de negocio:
// Ejecutar un hook de acción
HookService::execute('blog.before_publish', $post);
// Utilizar un hook de filtro para modificar un valor
$content = HookService::filter('blog.content_filter', $content);Campos y Componentes Personalizados
La interfaz de usuario programática se puede extender creando subclases personalizadas de AbstractField o AbstractContainer.
Creación de un Campo Personalizado
- Extender
Alxarafe\Component\AbstractField. - Implementar
getType(). - Crear una plantilla Blade correspondiente en
templates/form/{nombre_componente}.blade.php.
namespace Modules\MiModulo\Component;
use Alxarafe\Component\AbstractField;
class ColorPicker extends AbstractField {
protected string $component = 'colorpicker';
public function getType(): string { return 'color'; }
}Prioridad de Vistas
Cuando se llama a ViewController::render($view), el framework busca la plantilla en el siguiente orden:
- Tema:
APP_PATH/themes/{TemaActivo}/templates/{view}.blade.php - Módulo (App):
APP_PATH/Modules/{ModuloActual}/Templates/{view}.blade.php - App Compartido:
APP_PATH/templates/{view}.blade.php - Módulo (Core):
ALX_PATH/src/Modules/{ModuloActual}/Templates/{view}.blade.php - Núcleo Framework:
ALX_PATH/templates/{view}.blade.php
Esta jerarquía te permite sobrescribir la interfaz del núcleo del framework sin modificar la carpeta vendor/ ni los archivos base del framework.
Seguridad API y JWT
Alxarafe utiliza JSON Web Tokens (JWT) para la autenticación de APIs sin estado (stateless).
Ciclo de Vida del Token
- Login: Una petición POST a
/api/admin/logindevuelve un JWT firmado con la clavesecurity.jwt_secret_keydeconfig.json. - Autorización: Incluye el token en la cabecera de la petición:
Authorization: Bearer <token>. - Verificación:
ApiDispatchervalida automáticamente la firma y la fecha de expiración.
Protección de Endpoints
Utiliza los atributos #[RequireRole] o #[RequirePermission] en tus métodos de controlador de API.
#[ApiRoute(path: 'posts', method: 'POST')]
#[RequirePermission(permission: 'Blog.Post.doCreate')]
public function createAction($data) {
// ...
}Internacionalización (i18n)
Las traducciones son manejadas por Alxarafe\Lib\Trans y almacenadas en archivos YAML.
Estructura de Directorios
Modules/Blog/Lang/en.yamlModules/Blog/Lang/es.yaml
Uso en Código
Trans::_('key', ['param' => 'value']);Uso en Blade
{{ $me->trans('key') }}Fallback de Jerarquía
El traductor resuelve las claves en este orden:
- Localización destino (ej.
es_ES). - Localización padre (ej.
es). - Localización por defecto (ej.
en).