feat(theme-settings): agregar configuracion de ancho del contenedor

- 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>
This commit is contained in:
FrankZamora
2025-11-27 21:03:43 -06:00
parent 2fa112ab7f
commit 0dfe3fcd2c
5 changed files with 198 additions and 15 deletions

View File

@@ -333,17 +333,17 @@ final class AdsensePlacementRenderer
$css = implode("\n", $cssRules);
// JavaScript para posicionamiento inteligente de Rail Ads
// Detecta dinamicamente el header/hero y ajusta posicion sin valores fijos
// Detecta dinamicamente el header/hero/featured-image y ajusta posicion
$js = "
<script>
(function() {
var railAds = document.querySelectorAll('.roi-rail-ad');
if (!railAds.length) return;
// Buscar elementos de referencia (en orden de prioridad)
var navbar = document.querySelector('.navbar-fixed-top, .roi-navbar, .site-header, nav.navbar');
var hero = document.querySelector('.roi-hero, .hero-section, .hero, [class*=\"hero\"]');
var mainContent = document.querySelector('main, .site-main, .main-content, article');
// Selectores especificos del tema ROI
var navbar = document.querySelector('nav.navbar');
var hero = document.querySelector('.hero-section');
var featuredImage = document.querySelector('.featured-image-container');
function getNavbarHeight() {
if (navbar) {
@@ -357,20 +357,33 @@ final class AdsensePlacementRenderer
function adjustRailPosition() {
var navHeight = getNavbarHeight();
var gap = 20; // Espacio minimo de separacion
var gap = 30; // Espacio de separacion
var newTop = navHeight + gap;
// Si hay hero visible, posicionar debajo de el
// Buscar el elemento mas bajo entre hero y featured-image
var lowestBottom = navHeight;
if (hero) {
var heroRect = hero.getBoundingClientRect();
// Si el bottom del hero esta visible (> navbar height), rails debajo del hero
if (heroRect.bottom > navHeight) {
newTop = heroRect.bottom + gap;
if (heroRect.bottom > 0) {
lowestBottom = Math.max(lowestBottom, heroRect.bottom);
}
}
// Limitar el top maximo para que no quede muy abajo
var maxTop = window.innerHeight * 0.25; // Max 25% del viewport
if (featuredImage) {
var featuredRect = featuredImage.getBoundingClientRect();
if (featuredRect.bottom > 0) {
lowestBottom = Math.max(lowestBottom, featuredRect.bottom);
}
}
// Si algo esta visible en pantalla, posicionar debajo
if (lowestBottom > navHeight) {
newTop = lowestBottom + gap;
}
// Limitar el top maximo al 40% del viewport (mas generoso)
var maxTop = window.innerHeight * 0.4;
newTop = Math.min(newTop, maxTop);
// Asegurar minimo respetando navbar
@@ -400,7 +413,8 @@ final class AdsensePlacementRenderer
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', adjustRailPosition);
} else {
adjustRailPosition();
// Esperar un poco para que carguen los elementos
setTimeout(adjustRailPosition, 100);
}
})();
</script>";

View File

@@ -50,6 +50,7 @@ final class ThemeSettingsRenderer implements RendererInterface
* Genera contenido para wp_head
*
* Incluye:
* - Layout CSS (container width)
* - Custom CSS (si configurado)
* - Custom JS Header (si configurado)
*
@@ -60,6 +61,12 @@ final class ThemeSettingsRenderer implements RendererInterface
{
$output = '';
// Layout CSS (container width configurable)
$layoutOutput = $this->renderLayoutCSS($data);
if (!empty($layoutOutput)) {
$output .= $layoutOutput . "\n";
}
// Custom CSS
$cssOutput = $this->renderCustomCSS($data);
if (!empty($cssOutput)) {
@@ -75,6 +82,47 @@ final class ThemeSettingsRenderer implements RendererInterface
return $output;
}
/**
* Genera CSS para el layout configurable
*
* @param array $data Datos del componente
* @return string Bloque style o vacio si usa defaults
*/
private function renderLayoutCSS(array $data): string
{
$containerWidth = $data['layout']['container_max_width'] ?? '1320';
// Si es el valor default, no generar CSS extra
if ($containerWidth === '1320') {
return '';
}
// Validar que el valor sea seguro
$allowedWidths = ['1140', '1200', '1320', '1400', '100%'];
if (!in_array($containerWidth, $allowedWidths, true)) {
return '';
}
// Generar el CSS
$widthValue = ($containerWidth === '100%') ? '100%' : $containerWidth . 'px';
return sprintf(
'<!-- Layout CSS (ROI Theme) -->
<style id="roi-theme-layout-css">
/* Container width override */
@media (min-width: 1200px) {
.container,
.container-lg,
.container-xl,
.container-xxl {
max-width: %s;
}
}
</style>',
esc_attr($widthValue)
);
}
/**
* Genera contenido para wp_footer
*