feat(rail-ads): rails responsive que llenan el espacio disponible

- 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
This commit is contained in:
FrankZamora
2025-11-27 21:55:04 -06:00
parent 070ee7398c
commit 6b6ebd3c6d
3 changed files with 72 additions and 135 deletions

View File

@@ -462,51 +462,22 @@ final class AdsensePlacementFormBuilder
$html .= ' </div>'; $html .= ' </div>';
$html .= '</div>'; $html .= '</div>';
// Format select - Multiples anchos y alturas disponibles // Format select - Solo altura (el ancho es responsive)
$railFormat = $this->renderer->getFieldValue($cid, 'behavior', 'rail_format', 'skyscraper'); $railFormat = $this->renderer->getFieldValue($cid, 'behavior', 'rail_format', 'h600');
$html .= $this->buildSelect($cid . 'RailFormat', 'Formato', $html .= $this->buildSelect($cid . 'RailFormat', 'Altura del Rail',
$railFormat, $railFormat,
[ [
// 130px width 'h250' => '250px (Compacto)',
'w130-h300' => '130x300', 'h300' => '300px (Pequeno)',
'w130-h400' => '130x400', 'h400' => '400px (Mediano)',
'w130-h500' => '130x500', 'h500' => '500px',
'w130-h600' => '130x600', 'h600' => '600px (Recomendado)',
// 140px width 'h700' => '700px',
'w140-h300' => '140x300', 'h800' => '800px (Grande)',
'w140-h400' => '140x400', 'h1050' => '1050px (Extra grande)'
'w140-h500' => '140x500',
'w140-h600' => '140x600',
// 150px width
'w150-h300' => '150x300',
'w150-h400' => '150x400',
'w150-h500' => '150x500',
'w150-h600' => '150x600',
// 160px width
'slim-small' => '160x300',
'slim-medium' => '160x400',
'slim-large' => '160x500',
'skyscraper' => '160x600 (Skyscraper)',
'slim-xlarge' => '160x700',
'wide-skyscraper' => '160x800',
// 300px width
'w300-h250' => '300x250 (Medium Rectangle)',
'half-page' => '300x600 (Half Page)',
'large-skyscraper' => '300x1050 (Large Skyscraper)',
// 400px width
'w400-h300' => '400x300',
'w400-h400' => '400x400',
'w400-h600' => '400x600',
// 500px width
'w500-h300' => '500x300',
'w500-h400' => '500x400',
'w500-h600' => '500x600',
// 600px width
'w600-h300' => '600x300',
'w600-h400' => '600x400',
'w600-h600' => '600x600'
] ]
); );
$html .= '<small class="text-muted d-block mt-1 mb-2">El ancho se ajusta automaticamente al espacio disponible.</small>';
// Top offset - Select con opciones predefinidas // Top offset - Select con opciones predefinidas
$topOffset = $this->renderer->getFieldValue($cid, 'behavior', 'rail_top_offset', '300'); $topOffset = $this->renderer->getFieldValue($cid, 'behavior', 'rail_top_offset', '300');

View File

@@ -294,48 +294,27 @@ final class AdsensePlacementRenderer
$topOffset = (int)($settings['behavior']['rail_top_offset'] ?? 300); $topOffset = (int)($settings['behavior']['rail_top_offset'] ?? 300);
$delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true; $delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true;
// Dimensiones segun formato // Altura del rail segun formato seleccionado
// Soporta anchos: 130, 140, 150, 160, 300, 400, 500, 600px // El ancho es responsive (se ajusta automaticamente al espacio disponible)
[$width, $height] = match($format) { $height = match($format) {
// 130px width 'h250' => 250,
'w130-h300' => [130, 300], 'h300' => 300,
'w130-h400' => [130, 400], 'h400' => 400,
'w130-h500' => [130, 500], 'h500' => 500,
'w130-h600' => [130, 600], 'h600' => 600,
// 140px width 'h700' => 700,
'w140-h300' => [140, 300], 'h800' => 800,
'w140-h400' => [140, 400], 'h1050' => 1050,
'w140-h500' => [140, 500], // Legacy keys para compatibilidad con valores anteriores
'w140-h600' => [140, 600], 'skyscraper', 'slim-large', 'w130-h600', 'w140-h600', 'w150-h600' => 600,
// 150px width 'slim-small', 'w130-h300', 'w140-h300', 'w150-h300' => 300,
'w150-h300' => [150, 300], 'slim-medium', 'w130-h400', 'w140-h400', 'w150-h400' => 400,
'w150-h400' => [150, 400], 'slim-xlarge' => 700,
'w150-h500' => [150, 500], 'wide-skyscraper' => 800,
'w150-h600' => [150, 600], 'w300-h250' => 250,
// 160px width (legacy keys) 'half-page' => 600,
'slim-small' => [160, 300], 'large-skyscraper' => 1050,
'slim-medium' => [160, 400], default => 600,
'slim-large' => [160, 500],
'slim-xlarge' => [160, 700],
'wide-skyscraper' => [160, 800],
// 300px width
'w300-h250' => [300, 250],
'half-page' => [300, 600],
'large-skyscraper' => [300, 1050],
// 400px width
'w400-h300' => [400, 300],
'w400-h400' => [400, 400],
'w400-h600' => [400, 600],
// 500px width
'w500-h300' => [500, 300],
'w500-h400' => [500, 400],
'w500-h600' => [500, 600],
// 600px width
'w600-h300' => [600, 300],
'w600-h400' => [600, 400],
'w600-h600' => [600, 600],
// Default: skyscraper 160x600
default => [160, 600],
}; };
$scriptType = $delayEnabled ? 'text/plain' : 'text/javascript'; $scriptType = $delayEnabled ? 'text/plain' : 'text/javascript';
@@ -344,29 +323,35 @@ final class AdsensePlacementRenderer
// === CSS via CSSGenerator (NO hardcodeado) === // === CSS via CSSGenerator (NO hardcodeado) ===
$cssRules = []; $cssRules = [];
// Estilos base para Rail Ads // Estilos base para Rail Ads - RESPONSIVE
// El ancho se calcula automaticamente para llenar el espacio disponible
// Formula: (viewport - container) / 2 - margen_exterior(10px) - gap_interior(10px)
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad', [ $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad', [
'position' => 'fixed', 'position' => 'fixed',
'top' => $topOffset . 'px', 'top' => $topOffset . 'px',
'width' => $width . 'px', 'width' => 'calc((100vw - var(--roi-container-width-numeric, 1320px)) / 2 - 20px)',
'height' => $height . 'px',
'display' => 'flex',
'justify-content' => 'center',
'align-items' => 'flex-start',
'z-index' => '100', 'z-index' => '100',
'transition' => 'top 0.2s ease-out', 'transition' => 'top 0.2s ease-out, width 0.2s ease-out',
'overflow' => 'hidden',
]); ]);
// Posicion rail izquierdo - FIJO en el borde del viewport // Posicion rail izquierdo - 10px del borde del viewport
// Los Rails NO dependen del container width, siempre estan a 5px del borde
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-left', [ $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-left', [
'left' => '5px', 'left' => '10px',
]); ]);
// Posicion rail derecho - FIJO en el borde del viewport // Posicion rail derecho - 10px del borde del viewport
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-right', [ $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-right', [
'right' => '5px', 'right' => '10px',
]); ]);
// Media query para ocultar en pantallas < 1600px // Media query para ocultar en pantallas donde no hay espacio suficiente
// NOTA: Media queries se escriben directamente (patron consistente con FeaturedImageRenderer) // Minimo: container(1320) + 2*rail_min(130) + 4*margin(10) = 1320+260+40 = 1620px
$cssRules[] = "@media (max-width: 1599px) { $cssRules[] = "@media (max-width: 1619px) {
.roi-rail-ad { display: none !important; } .roi-rail-ad { display: none !important; }
}"; }";
@@ -377,8 +362,9 @@ final class AdsensePlacementRenderer
/** /**
* EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense * EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense
* Los atributos style="display:inline-block;width:Xpx;height:Xpx" son * Usamos display:block con data-full-width-responsive="true" para que
* especificacion de Google y NO pueden generarse via CSSGenerator. * el anuncio se adapte automaticamente al ancho del contenedor responsive.
* La altura se controla via el selector de formato.
* Ref: https://support.google.com/adsense/answer/9274516 * Ref: https://support.google.com/adsense/answer/9274516
*/ */
@@ -386,11 +372,12 @@ final class AdsensePlacementRenderer
if ($leftEnabled) { if ($leftEnabled) {
$html .= sprintf( $html .= sprintf(
'<div class="roi-rail-ad roi-rail-ad-left"> '<div class="roi-rail-ad roi-rail-ad-left">
<ins class="adsbygoogle" style="display:inline-block;width:%dpx;height:%dpx" <ins class="adsbygoogle" style="display:block;height:%dpx"
data-ad-client="%s" data-ad-slot="%s"></ins> data-ad-client="%s" data-ad-slot="%s"
data-full-width-responsive="true"></ins>
<script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script> <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
</div>', </div>',
$width, $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
); );
} }
@@ -398,11 +385,12 @@ final class AdsensePlacementRenderer
if ($rightEnabled) { if ($rightEnabled) {
$html .= sprintf( $html .= sprintf(
'<div class="roi-rail-ad roi-rail-ad-right"> '<div class="roi-rail-ad roi-rail-ad-right">
<ins class="adsbygoogle" style="display:inline-block;width:%dpx;height:%dpx" <ins class="adsbygoogle" style="display:block;height:%dpx"
data-ad-client="%s" data-ad-slot="%s"></ins> data-ad-client="%s" data-ad-slot="%s"
data-full-width-responsive="true"></ins>
<script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script> <script type="%s"%s>(adsbygoogle = window.adsbygoogle || []).push({});</script>
</div>', </div>',
$width, $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr $height, esc_attr($publisherId), esc_attr($slotId), $scriptType, $dataAttr
); );
} }

View File

@@ -222,42 +222,20 @@
}, },
"rail_format": { "rail_format": {
"type": "select", "type": "select",
"label": "Formato Rail Ads", "label": "Altura Rail Ads",
"default": "skyscraper", "default": "h600",
"editable": true, "editable": true,
"options": { "options": {
"w130-h300": "130x300", "h250": "250px (Compacto)",
"w130-h400": "130x400", "h300": "300px (Pequeno)",
"w130-h500": "130x500", "h400": "400px (Mediano)",
"w130-h600": "130x600", "h500": "500px",
"w140-h300": "140x300", "h600": "600px (Recomendado)",
"w140-h400": "140x400", "h700": "700px",
"w140-h500": "140x500", "h800": "800px (Grande)",
"w140-h600": "140x600", "h1050": "1050px (Extra grande)"
"w150-h300": "150x300",
"w150-h400": "150x400",
"w150-h500": "150x500",
"w150-h600": "150x600",
"slim-small": "160x300",
"slim-medium": "160x400",
"slim-large": "160x500",
"skyscraper": "160x600 (Skyscraper)",
"slim-xlarge": "160x700",
"wide-skyscraper": "160x800",
"w300-h250": "300x250 (Medium Rectangle)",
"half-page": "300x600 (Half Page)",
"large-skyscraper": "300x1050 (Large Skyscraper)",
"w400-h300": "400x300",
"w400-h400": "400x400",
"w400-h600": "400x600",
"w500-h300": "500x300",
"w500-h400": "500x400",
"w500-h600": "500x600",
"w600-h300": "600x300",
"w600-h400": "600x400",
"w600-h600": "600x600"
}, },
"description": "Tamano del anuncio en los rails laterales" "description": "Altura del anuncio. El ancho se ajusta automaticamente al espacio disponible."
}, },
"rail_top_offset": { "rail_top_offset": {
"type": "select", "type": "select",