Agrega propiedades flexbox al contenedor .hero-section para que el contenido (título y badges) se muestre centrado verticalmente cuando no hay badges de categorías. Cambios: - display: flex - align-items: center - justify-content: center También incluye specs OpenSpec para arquitectura del tema. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.5 KiB
Especificacion de Patrones WordPress
Purpose
Define como integrar WordPress con Clean Architecture en ROITheme. WordPress tiene caracteristicas propias que requieren patrones especificos para mantener la arquitectura limpia.
Requirements
Requirement: Ubicacion de Hooks de WordPress
WordPress hooks (add_action, add_filter) MUST be located ONLY in Infrastructure.
Scenario: Hooks prohibidos en Domain
- WHEN el codigo esta en la capa Domain
- THEN NO DEBE contener add_action
- AND NO DEBE contener add_filter
- AND NO DEBE registrar callbacks de WordPress
Scenario: Hooks prohibidos en Application
- WHEN el codigo esta en la capa Application
- THEN NO DEBE contener add_action
- AND NO DEBE contener add_filter
Scenario: Ubicacion correcta de hooks
- WHEN se necesitan hooks de WordPress
- THEN DEBEN colocarse en Infrastructure/Wordpress/[Componente]HooksRegistrar.php
- AND los hooks DEBEN delegar a Use Cases
- AND los hooks NO DEBEN contener logica de negocio
Requirement: Encapsulacion de wpdb
Access to global $wpdb MUST be encapsulated in Infrastructure repositories.
Scenario: wpdb prohibido en Domain
- WHEN el codigo esta en la capa Domain
- THEN NO DEBE contener global $wpdb
- AND NO DEBE hacer consultas directas a base de datos
Scenario: wpdb prohibido en Application
- WHEN el codigo esta en la capa Application
- THEN NO DEBE contener global $wpdb
- AND DEBE usar interfaces de repository
Scenario: Ubicacion correcta de wpdb
- WHEN se necesita acceso a base de datos
- THEN DEBE usarse en Infrastructure/Persistence/WordPress[Componente]Repository.php
- AND el repository DEBE implementar una interface definida en Domain
Requirement: Ubicacion de wp_enqueue_scripts
Functions wp_enqueue_style and wp_enqueue_script MUST be located ONLY in Infrastructure.
Scenario: Enqueue prohibido en Domain
- WHEN el codigo esta en la capa Domain
- THEN NO DEBE contener wp_enqueue_style
- AND NO DEBE contener wp_enqueue_script
Scenario: Enqueue prohibido en Application
- WHEN el codigo esta en la capa Application
- THEN NO DEBE contener funciones de enqueue
- AND NO DEBE conocer detalles de assets
Scenario: Ubicacion correcta de enqueue
- WHEN se necesita cargar assets
- THEN DEBE colocarse en Infrastructure/Services/[Componente]AssetEnqueuer.php
- AND DEBE registrarse via hooks en Infrastructure
Requirement: Ubicacion de register_post_type
CPT and taxonomy registration MUST be located ONLY in Infrastructure.
Scenario: CPT no es concepto de Domain
- WHEN se considera donde registrar un Custom Post Type
- THEN NO DEBE ir en Domain porque no es concepto de negocio
- AND NO DEBE ir en Application
- AND ES un detalle de implementacion de WordPress
Scenario: Ubicacion correcta de CPT
- WHEN se necesita registrar un Custom Post Type
- THEN DEBE colocarse en Infrastructure/Wordpress/[Componente]CPTRegistrar.php
Requirement: Ubicacion de add_shortcode
Shortcodes MUST be located ONLY in Infrastructure and delegate to Use Cases.
Scenario: Shortcode prohibido en Domain y Application
- WHEN el codigo esta en Domain o Application
- THEN NO DEBE contener add_shortcode
Scenario: Ubicacion correcta de shortcode
- WHEN se necesita un shortcode
- THEN DEBE colocarse en Infrastructure/Wordpress/[Componente]ShortcodeRegistrar.php
- AND DEBE delegar la logica a un Use Case
Requirement: Ubicacion de Options API
WordPress Options API MUST be encapsulated in Infrastructure repositories.
Scenario: Options prohibidas en Domain y Application
- WHEN el codigo esta en Domain o Application
- THEN NO DEBE contener get_option
- AND NO DEBE contener update_option
- AND NO DEBE contener delete_option
Scenario: Ubicacion correcta de Options
- WHEN se necesita acceso a opciones de WordPress
- THEN DEBE colocarse en Infrastructure/Persistence/WordPressSettingsRepository.php
- AND DEBE implementar una interface de Application
Requirement: Evitar functions.php Gigante
The functions.php file MUST contain only bootstrap, not logic.
Scenario: functions.php correcto
- WHEN se implementa functions.php
- THEN DEBE contener solo Autoloader, Container DI y Bootstrap
- AND NO DEBE contener logica de negocio
- AND NO DEBE contener definiciones de funciones de negocio
Requirement: Evitar Logica en Templates
Templates MUST contain only rendering, not business logic.
Scenario: Template prohibido con logica
- WHEN un template de WordPress existe
- THEN NO DEBE contener global $wpdb
- AND NO DEBE contener validaciones de negocio
- AND NO DEBE contener consultas a base de datos
- AND NO DEBE contener cadenas if/elseif complejas
Scenario: Template correcto
- WHEN se crea un template
- THEN DEBE recibir un ViewModel preparado
- AND DEBE contener solo HTML con escaping
- AND DEBE usar esc_html(), esc_attr(), esc_url()
Requirement: Evitar wpdb Disperso
Usage of wpdb MUST NOT be scattered throughout the code.
Scenario: wpdb centralizado
- WHEN se necesita acceso a base de datos
- THEN DEBE usarse SOLO en repositories
- AND los repositories DEBEN estar en Infrastructure/Persistence/
- AND multiples archivos NO DEBEN tener global $wpdb
Scenario: Beneficios de centralizacion
- WHEN wpdb esta centralizado en repositories
- THEN cambiar la base de datos requiere modificar solo repositories
- AND el testing es posible via mocks de interface
- AND la logica de negocio permanece pura
Requirement: Evitar Variables Globales Masivas
Code MUST NOT use massive global variables.
Scenario: Globales prohibidas
- WHEN se escribe codigo
- THEN NO DEBE usar global $roi_config
- AND NO DEBE usar singletons dispersos
- AND NO DEBE crear estado global
Scenario: Solucion con Dependency Injection
- WHEN se necesitan dependencias compartidas
- THEN DEBE usarse un Container de Inyeccion de Dependencias
- AND las dependencias se inyectan via constructor
- AND no hay estado global
Requirement: Codigo Testeable
Code MUST be testable without WordPress installed.
Scenario: Domain testeable
- WHEN se escribe codigo de Domain
- THEN DEBE ser testeable sin base de datos
- AND DEBE ser testeable sin WordPress
- AND DEBE ser testeable sin UI
Scenario: Mocks via interfaces
- WHEN se escriben tests
- THEN las dependencias se mockean via interfaces
- AND los tests unitarios NO requieren setup complejo
- AND Domain puede probarse de forma aislada
Requirement: Arbol de Decisiones WordPress
WordPress code MUST be located according to code type.
Scenario: Determinar ubicacion de hooks
- WHEN el codigo es add_action o add_filter
- THEN va en Infrastructure/Wordpress/[Componente]HooksRegistrar.php
Scenario: Determinar ubicacion de wpdb
- WHEN el codigo usa global $wpdb
- THEN va en Infrastructure/Persistence/WordPress[Componente]Repository.php
Scenario: Determinar ubicacion de enqueue
- WHEN el codigo usa wp_enqueue_style o wp_enqueue_script
- THEN va en Infrastructure/Services/[Componente]AssetEnqueuer.php
Scenario: Determinar ubicacion de CPT
- WHEN el codigo usa register_post_type o register_taxonomy
- THEN va en Infrastructure/Wordpress/[Componente]CPTRegistrar.php
Scenario: Determinar ubicacion de shortcode
- WHEN el codigo usa add_shortcode
- THEN va en Infrastructure/Wordpress/[Componente]ShortcodeRegistrar.php
Scenario: Determinar ubicacion de options
- WHEN el codigo usa get_option o update_option
- THEN va en Infrastructure/Persistence/WordPressSettingsRepository.php
Scenario: Determinar ubicacion de nonces
- WHEN el codigo usa wp_nonce_field o check_admin_referer
- THEN va en Infrastructure/Api/Wordpress/[Componente]Controller.php
Requirement: Comandos de Validacion WordPress
Code MUST be validated with specific commands.
Scenario: Validar Domain sin WordPress
- WHEN se valida la capa Domain
- THEN grep por global $wpdb DEBE retornar vacio
- AND grep por add_action DEBE retornar vacio
- AND grep por $_POST DEBE retornar vacio
Scenario: Validar Application sin WordPress
- WHEN se valida la capa Application
- THEN grep por global $wpdb DEBE retornar vacio
- AND grep por add_action DEBE retornar vacio
- AND grep por wp_enqueue DEBE retornar vacio