# Contexto Public - Renderizado Frontend de Componentes ## Propósito El contexto `public/` contiene **todo el código relacionado con el renderizado de componentes en el frontend**. Cada componente tiene su propia carpeta con su Clean Architecture completa. ## Filosofía: Context-First Architecture Similar a `admin/`, el contexto `public/` agrupa todo lo relacionado con la visualización pública de componentes. Cada componente es independiente y tiene sus propias capas de Clean Architecture. ## Estructura (Fase-00) En Fase-00 solo creamos la estructura base. Los componentes se crearán en fases posteriores: ``` public/ ├── README.md (este archivo) └── .gitkeep (preserva directorio en Git) ``` ## Estructura Futura (Post Fase-00) ``` public/ ├── Navbar/ # Componente Navbar │ ├── Domain/ │ │ ├── NavbarData.php # Entidad de lectura │ │ └── NavbarDataProviderInterface.php │ ├── Application/ │ │ ├── GetNavbarDataUseCase.php # Caso de uso │ │ └── DTO/ │ │ └── NavbarDataDTO.php │ ├── Infrastructure/ │ │ ├── Persistence/ │ │ │ └── WordPressNavbarDataProvider.php │ │ ├── UI/ │ │ │ ├── NavbarRenderer.php # Renderizador │ │ │ ├── views/ │ │ │ │ └── navbar.php # Template │ │ │ └── assets/ │ │ │ ├── css/ │ │ │ │ └── navbar.css │ │ │ └── js/ │ │ │ └── navbar.js │ │ └── Hooks/ │ │ └── NavbarHooks.php # WordPress hooks │ └── README.md ├── Footer/ # Otro componente │ └── (misma estructura) └── (más componentes...) ``` ## Principios del Contexto Public 1. **Solo lectura**: El frontend solo lee configuraciones, no las modifica 2. **Performance**: Optimizado para carga rápida y caché 3. **Presentación**: Se enfoca en renderizar HTML, CSS, JS 4. **Independencia**: Cada componente es autónomo ## Responsabilidades El contexto `public/` se encarga de: ✅ **Renderizado de componentes** en el frontend ✅ **Lectura de configuraciones** de la base de datos ✅ **Generación de HTML** según templates ✅ **Carga de assets** (CSS, JS) del componente ✅ **Enqueue de scripts y estilos** ✅ **Hooks de WordPress** para frontend (`wp_head`, `wp_footer`, etc.) ❌ **NO** se encarga de: - Administración de componentes (va en `admin/`) - Guardado de configuraciones - Lógica compartida (va en `shared/`) ## Ejemplo de Flujo de Public ### 1. Usuario visita página web ``` Usuario (navegador) ↓ WordPress carga tema ↓ NavbarHooks.php (registra hook 'wp_body_open') ↓ Hook ejecutado ↓ NavbarRenderer.php (obtiene datos y renderiza) ↓ GetNavbarDataUseCase.php (obtiene configuración) ↓ WordPressNavbarDataProvider.php (lee de DB) ↓ navbar.php (template con HTML) ↓ HTML enviado al navegador ``` ### 2. Código de ejemplo ```php // public/Navbar/Application/GetNavbarDataUseCase.php namespace ROITheme\Public\Navbar\Application; use ROITheme\Public\Navbar\Domain\NavbarDataProviderInterface; final class GetNavbarDataUseCase { public function __construct( private readonly NavbarDataProviderInterface $dataProvider ) {} public function execute(): array { $data = $this->dataProvider->get(); // Transformar datos si es necesario return [ 'logo_url' => $data['logo_url'] ?? '', 'menu_items' => $data['menu_items'] ?? [], 'sticky' => $data['sticky'] ?? false, ]; } } ``` ```php // public/Navbar/Infrastructure/UI/NavbarRenderer.php namespace ROITheme\Public\Navbar\Infrastructure\UI; use ROITheme\Public\Navbar\Application\GetNavbarDataUseCase; final class NavbarRenderer { public function __construct( private readonly GetNavbarDataUseCase $getNavbarData ) {} public function render(): void { $data = $this->getNavbarData->execute(); // Encolar assets wp_enqueue_style( 'roi-navbar', get_template_directory_uri() . '/public/Navbar/Infrastructure/UI/assets/css/navbar.css', [], '1.0.0' ); wp_enqueue_script( 'roi-navbar', get_template_directory_uri() . '/public/Navbar/Infrastructure/UI/assets/js/navbar.js', ['jquery'], '1.0.0', true ); // Renderizar template require __DIR__ . '/views/navbar.php'; } } ``` ```php // public/Navbar/Infrastructure/Hooks/NavbarHooks.php namespace ROITheme\Public\Navbar\Infrastructure\Hooks; use ROITheme\Public\Navbar\Infrastructure\UI\NavbarRenderer; final class NavbarHooks { public function __construct( private readonly NavbarRenderer $renderer ) {} public function register(): void { add_action('wp_body_open', [$this->renderer, 'render']); } } ``` ```php // public/Navbar/Infrastructure/UI/views/navbar.php ``` ## Relación con Otros Contextos ``` admin/ → Guarda configuraciones ↓ Base de Datos → Almacena settings ↓ lee public/ → Renderiza componentes ↓ Navegador del Usuario ``` **Clave**: `public/` solo LECTURA, nunca escritura. ## Optimización y Caché ### 1. Usar Transients de WordPress ```php public function get(): array { $cached = get_transient('roi_navbar_data'); if ($cached !== false) { return $cached; } $data = $this->fetchFromDatabase(); set_transient('roi_navbar_data', $data, HOUR_IN_SECONDS); return $data; } ``` ### 2. Conditional Asset Loading ```php if ($data['sticky']) { wp_enqueue_script('roi-navbar-sticky'); } ``` ### 3. Lazy Loading de Componentes ```php add_action('wp_body_open', function() { if (is_front_page()) { // Solo cargar en homepage $renderer->render(); } }); ``` ## Reglas de Dependencia ✅ **PUEDE** depender de: - `shared/Domain/` (Value Objects, Exceptions) - `shared/Application/` (Contracts, Services) - `shared/Infrastructure/` (Implementaciones de servicios) - WordPress frontend functions (`wp_enqueue_style`, `wp_head`, etc.) ❌ **NO PUEDE** depender de: - `admin/` (contexto independiente) - Funciones de administración de WordPress ## Testing ### Tests Unitarios ```php // tests/Unit/Public/Navbar/Application/GetNavbarDataUseCaseTest.php public function test_returns_navbar_data() { $dataProvider = $this->createMock(NavbarDataProviderInterface::class); $dataProvider->method('get')->willReturn(['logo_url' => 'test.png']); $useCase = new GetNavbarDataUseCase($dataProvider); $data = $useCase->execute(); $this->assertEquals('test.png', $data['logo_url']); } ``` ### Tests de Integración ```php // tests/Integration/Public/Navbar/Infrastructure/WordPressNavbarDataProviderTest.php public function test_retrieves_navbar_settings_from_db() { update_option('roi_navbar_settings', ['logo_url' => 'test.png']); $provider = new WordPressNavbarDataProvider(); $data = $provider->get(); $this->assertEquals('test.png', $data['logo_url']); } ``` ### Tests E2E (Playwright) ```php // tests/E2E/Public/NavbarRenderingTest.php public function test_navbar_renders_on_homepage() { $this->visit('/'); $this->see('.roi-navbar'); $this->see('Logo'); } ``` ### Tests de Performance ```php // tests/Performance/Public/NavbarPerformanceTest.php public function test_navbar_renders_in_less_than_100ms() { $start = microtime(true); $renderer = new NavbarRenderer($this->getNavbarDataUseCase); ob_start(); $renderer->render(); ob_end_clean(); $duration = (microtime(true) - $start) * 1000; $this->assertLessThan(100, $duration); } ``` ## Cuándo Agregar Código Aquí Agrega código a `public/` cuando: - Renderizas un componente en el frontend - Necesitas mostrar datos al usuario final - Cargas assets (CSS, JS) para el frontend - Registras hooks de frontend (`wp_head`, `wp_footer`, etc.) - Optimizas performance de renderizado No agregues aquí: - Formularios de admin (van en `admin/`) - Guardado de configuraciones - Lógica compartida (va en `shared/`) ## Assets y Performance ### Organización de Assets ``` public/Navbar/Infrastructure/UI/assets/ ├── css/ │ ├── navbar.css # Estilos del componente │ └── navbar.min.css # Versión minificada ├── js/ │ ├── navbar.js # JavaScript del componente │ └── navbar.min.js # Versión minificada └── images/ └── default-logo.png # Imágenes del componente ``` ### Minificación y Concatenación En producción, usar versiones minificadas: ```php $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; wp_enqueue_style('roi-navbar', "...navbar{$suffix}.css"); ``` ## Estado Actual (Fase-00) En Fase-00, `public/` solo tiene la estructura base. Los componentes se crearán en las siguientes fases: - **Fase-1**: Estructura base e infraestructura - **Fase-2**: Migración de base de datos - **Fase-3**: Implementación de componentes públicos - **Fase-4+**: Componentes adicionales y optimización ## Próximos Pasos 1. Crear primer componente en Fase-3 (ej: Navbar) 2. Implementar Domain layer (entidades de lectura) 3. Implementar Application layer (casos de uso de lectura) 4. Implementar Infrastructure layer (renderizado, hooks) 5. Crear templates y assets 6. Optimizar con caché 7. Crear tests de performance 8. Repetir para cada componente