PROBLEMA:
- wp_head() se ejecuta ANTES de que los componentes rendericen
- CriticalCSSCollector estaba vacío al momento de inyectar en <head>
- Componentes retornaban solo HTML sin CSS → sitio sin estilos
SOLUCIÓN:
- Eliminar lógica condicional de is_critical en render()
- Siempre incluir CSS inline con el componente (comportamiento anterior)
- Campo is_critical reservado para futura implementación con output buffering
Archivos modificados:
- NavbarRenderer.php
- TopNotificationBarRenderer.php
- HeroRenderer.php
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Implementar sistema de grupos de componentes tipo "carpetas de apps"
- Crear ComponentGroupRegistry para gestionar grupos y componentes
- Añadir vista home con grupos: Header, Contenido, CTAs, Engagement, Forms, Config
- Rediseñar UI con Design System: header navy, cards blancos, mini-cards verticales
- Incluir animaciones fadeInUp escalonadas y efectos hover con glow
- Mantener navegación a vistas de componentes individuales
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Optimización PageSpeed Fase 4.1:
- Cambio font-display:block → font-display:swap en bootstrap-icons.min.css
- Reduce bloqueo de renderizado en ~420ms
- Permite mostrar fallback mientras carga la fuente de iconos
Archivos subset ya tenían swap configurado (sin cambios necesarios)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
El ins.adsbygoogle tenia width 0 porque el contenedor padre
no tenia ancho definido. Esto causaba el error
"No slot size for availableWidth=0" de AdSense.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Anchor Ads: Cambiar de visibility:hidden a transform:translateY()
para que AdSense pueda medir dimensiones del slot
- Vignette Ads: Solo mostrar overlay cuando data-ad-status="filled"
- Mover card Exclusiones a columna izquierda en admin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Anchor Ads:
- Ocultos por defecto via CSS (opacity: 0, visibility: hidden)
- Solo se muestran cuando AdSense llena el slot (clase .ad-loaded)
- Ya no aparece espacio en blanco si no hay anuncio
Vignette Ads:
- Agregados tamaños: 728x90, 970x250, 970x90, 468x60, 320x100
- Nueva opción "auto" (recomendado) para formato automático
- Renderer actualizado para manejar todos los tamaños
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix TypeError: buildSelect() Argument #3 ($value) must be of type string.
The getFieldValue() method can return boolean for certain DB values,
causing type mismatch with strict typed buildSelect() method.
Added (string) casts to all buildSelect() calls in Vignette Ads section:
- vignetteTrigger
- size
- opacity
- reshowTime
- maxSession
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Agregar watchUnfilledAds() con MutationObserver
- Detectar data-ad-status="unfilled" de AdSense
- Timeout de 5s como respaldo si no hay contenido
- Evitar mostrar espacio en blanco cuando no hay anuncio
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Anchor Ads: anuncios fijos top/bottom con botones minimizar/cerrar
- Vignette Ads: modal fullscreen con triggers configurables
- Schema v1.3.0 con grupos anchor_ads y vignette_ads (18 campos)
- FieldMapper actualizado para persistir settings en BD
- JavaScript para interacción (colapso, cierre, localStorage)
- Soporte para responsive y tamaños fijos en vignette
IMPORTANTE: Ejecutar en servidor remoto:
wp roi-theme sync-component adsense-placement
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Nuevo campo hide_for_logged_in en schema visibility group
- Switch en panel de administracion con icono bi-person-lock
- Mapeo en FieldMapper para persistencia
- Validacion en roi_render_ad_slot, roi_render_rail_ads,
roi_enqueue_adsense_script y roi_inject_content_ads
- No carga script ni muestra ads si usuario tiene sesion activa
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- El slot after-related estaba definido en schema pero no se llamaba
- Ahora se renderiza después del componente related-post
- Requiere habilitar 'Después de Related Posts' en panel AdSense
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Agregar min-width: 170px para evitar corte
- Quitar overflow:hidden que cortaba contenido
- Detectar footer y ocultar rails cuando se acercan
- Transicion suave de opacity para ocultar/mostrar
- Ancho calculado automaticamente: (viewport - container) / 2 - 20px
- 10px margen del viewport + 10px gap al container
- Selector simplificado: solo altura (250-1050px)
- AdSense usa data-full-width-responsive para adaptarse
- Media query actualizada: oculta en pantallas < 1620px
- Added width options: 130px, 140px, 150px, 160px, 300px, 400px, 500px, 600px
- Each width has multiple height options (300, 400, 500, 600, etc.)
- Total of 31 format combinations available
- Updated Schema, Renderer and FormBuilder
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed Rail Ads positioning from container-width-based formula to fixed 15px from viewport edges
- Rails no longer move inward when container width is reduced
- Fixes overlap issue when layout width setting changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Formatos: skyscraper (160x600), wide-skyscraper (160x800), half-page (300x600), large-skyscraper (300x1050)
- Distancia desde arriba: 150, 200, 300 (default), 400, 500, 700px
- Cambiar rail_top_offset de text a select con opciones predefinidas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Nuevo grupo 'Layout y Contenedor' en theme-settings
- Opciones: 1140px, 1200px, 1320px (default), 1400px, 100%
- CSS dinamico aplicado via ThemeSettingsRenderer
- Corregir selectores de hero en Rail Ads (.hero-section, .featured-image-container)
- Agregar setTimeout para esperar carga de DOM
- Aumentar gap de separacion a 30px
- Subir maxTop al 40% del viewport
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Usar CSS max() para evitar rail izquierdo cortado fuera del viewport
- Agregar JavaScript inteligente para detectar navbar/hero dinámicamente
- Rail ads se posicionan debajo del hero cuando es visible
- Usar requestAnimationFrame para throttle de scroll
- Eliminar dependencia de valores fijos en pixels
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Panel AdSense reorganizado:
- Diagrama visual mostrando ubicaciones de anuncios (POST-TOP, IN-CONTENT, POST-BOTTOM, RAIL)
- Secciones colapsables por ubicación con badges de color
- Slots con descripciones claras indicando uso (Auto, In-Article, Display, etc.)
In-Content Ads mejorado:
- Soporte para 1-8 anuncios dentro del contenido
- Modo aleatorio (random) que varía posiciones en cada visita
- Configuración de mínimo/máximo de ads
- Párrafos mínimos entre anuncios configurable (2-6)
- Primer ad siempre en posición fija configurada
Archivos modificados:
- Schema v1.2.0 con 4 nuevos campos (random_mode, min_ads, max_ads, min_paragraphs_between)
- FormBuilder con diagrama visual y mejor organización
- ContentAdInjector con lógica de posicionamiento random
- Renderer con soporte para post-content-1 hasta post-content-8
- FieldMapper actualizado con nuevos campos
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: mu-plugin allow-unfiltered-html.php was replacing all
filtered content with raw DB content at PHP_INT_MAX priority.
Solution: Modified mu-plugin on server to call roi_inject_content_ads()
after getting raw content.
NOTE: The mu-plugin change is only on the production server at:
/wp-content/mu-plugins/allow-unfiltered-html.php
The change adds roi_inject_content_ads() call after YouTube Facade filter.
This allows ads to be injected into posts even with the raw content bypass.
Cleaned up:
- Removed debug logging from adsense-placement.php
- Removed template-level debug from single.php
- Removed debug markers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The output buffer in adsense-delay.php was causing conflicts with
zlib compression buffer, resulting in ads being generated but not
appearing in final HTML.
Root cause: Multiple output buffers (zlib + adsense-delay) were
nested improperly, causing ob_end_flush() failures and content loss.
Solution: Disable the output buffer since AdsensePlacementRenderer
already generates scripts with type="text/plain" data-adsense-push.
The buffer was redundant and only needed for external AdSense sources.
Debug logs confirmed:
- Filter generates ads correctly (598+601 chars)
- Content exists after filter (54765 chars)
- But ads missing in final HTML (0 roi-ad-slot found)
- ob_end_flush() errors in debug.log
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Change roi_delay_adsense_scripts() to read from 'adsense-placement' component
- Change roi_add_adsense_init_script() to use same settings source
- Use 'forms.delay_enabled' field path instead of 'visibility.is_enabled'
- Add clarifying comments about output buffer purpose
The 'adsense-delay' component was never created in the database, causing
the delay functions to always use default values. Now properly reads
from the existing 'adsense-placement' component settings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed AdSense injection filter from priority 100 to 150 to ensure
it runs AFTER restrict-content-pro's rcp_filter_restricted_content
filter which also uses priority 100.
This should fix ads not appearing in post content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Additional debug info:
- Log post_id and URL to identify which post is being processed
- Log first 200 chars of postTopHtml to verify content
- Log final content length
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added error_log statements to roi_inject_content_ads() to trace:
- Function entry point
- Conditions failing (is_single, in_the_loop, is_main_query)
- Container null check
- Settings loaded status
- Post exclusion check
- Rendered slot lengths
- Any exceptions with full trace
This will help identify why ads are not appearing on production
despite all database settings being correctly configured.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The $container variable was being assigned inside a try-catch block
without being declared as global first, making it unavailable to
Inc/adsense-placement.php functions. This caused AdSense slots to
not be injected into the content.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- CSS Personalizado card on left column (10 rows textarea)
- JavaScript Personalizado card on right column (Header + Footer)
- Improved visual organization with separate alerts per card
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove Analytics and AdSense tabs from theme-settings component
- Add Analytics group to adsense-placement component
- Add roi_enqueue_analytics_script() for GA4/UA support
- Clean up ThemeSettings to only handle custom code (CSS/JS)
- Update FormBuilders and FieldMappers accordingly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>