Plan 99.11 - Correcciones críticas: - FooterRenderer: Añadir PageVisibilityHelper::shouldShow() - HeroSectionRenderer: Añadir PageVisibilityHelper::shouldShow() - AdsensePlacementRenderer: Añadir PageVisibilityHelper::shouldShow() Mejoras adicionales: - UrlPatternExclusion: Soporte wildcards (*sct* → regex) - ExclusionFormPartial: UI mejorada con placeholders - ComponentConfiguration: Grupo _exclusions validado - 12 FormBuilders: Integración UI de exclusiones - 12 FieldMappers: Mapeo campos de exclusión Verificado: Footer oculto en post con categoría excluida SCT 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
553 lines
29 KiB
PHP
553 lines
29 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace ROITheme\Admin\RelatedPost\Infrastructure\Ui;
|
|
|
|
use ROITheme\Admin\Infrastructure\Ui\AdminDashboardRenderer;
|
|
use ROITheme\Admin\Shared\Infrastructure\Ui\ExclusionFormPartial;
|
|
|
|
/**
|
|
* FormBuilder para Related Posts
|
|
*
|
|
* @package ROITheme\Admin\RelatedPost\Infrastructure\Ui
|
|
*/
|
|
final class RelatedPostFormBuilder
|
|
{
|
|
public function __construct(
|
|
private AdminDashboardRenderer $renderer
|
|
) {}
|
|
|
|
public function buildForm(string $componentId): string
|
|
{
|
|
$html = '';
|
|
|
|
$html .= $this->buildHeader($componentId);
|
|
|
|
$html .= '<div class="row g-3">';
|
|
|
|
// Columna izquierda
|
|
$html .= '<div class="col-lg-6">';
|
|
$html .= $this->buildVisibilityGroup($componentId);
|
|
$html .= $this->buildContentGroup($componentId);
|
|
$html .= $this->buildLayoutGroup($componentId);
|
|
$html .= '</div>';
|
|
|
|
// Columna derecha
|
|
$html .= '<div class="col-lg-6">';
|
|
$html .= $this->buildTypographyGroup($componentId);
|
|
$html .= $this->buildColorsGroup($componentId);
|
|
$html .= $this->buildSpacingGroup($componentId);
|
|
$html .= $this->buildEffectsGroup($componentId);
|
|
$html .= '</div>';
|
|
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildHeader(string $componentId): string
|
|
{
|
|
$html = '<div class="rounded p-4 mb-4 shadow text-white" ';
|
|
$html .= 'style="background: linear-gradient(135deg, #0E2337 0%, #1e3a5f 100%); border-left: 4px solid #FF8600;">';
|
|
$html .= ' <div class="d-flex align-items-center justify-content-between flex-wrap gap-3">';
|
|
$html .= ' <div>';
|
|
$html .= ' <h3 class="h4 mb-1 fw-bold">';
|
|
$html .= ' <i class="bi bi-grid-3x3-gap me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Configuracion de Posts Relacionados';
|
|
$html .= ' </h3>';
|
|
$html .= ' <p class="mb-0 small" style="opacity: 0.85;">';
|
|
$html .= ' Seccion de posts relacionados con grid de cards';
|
|
$html .= ' </p>';
|
|
$html .= ' </div>';
|
|
$html .= ' <button type="button" class="btn btn-sm btn-outline-light btn-reset-defaults" data-component="related-post">';
|
|
$html .= ' <i class="bi bi-arrow-counterclockwise me-1"></i>';
|
|
$html .= ' Restaurar valores por defecto';
|
|
$html .= ' </button>';
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildVisibilityGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-toggle-on me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Visibilidad';
|
|
$html .= ' </h5>';
|
|
|
|
$enabled = $this->renderer->getFieldValue($componentId, 'visibility', 'is_enabled', true);
|
|
$html .= $this->buildSwitch('relatedPostEnabled', 'Activar componente', 'bi-power', $enabled);
|
|
|
|
$showOnDesktop = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_desktop', true);
|
|
$html .= $this->buildSwitch('relatedPostShowOnDesktop', 'Mostrar en escritorio', 'bi-display', $showOnDesktop);
|
|
|
|
$showOnMobile = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_mobile', true);
|
|
$html .= $this->buildSwitch('relatedPostShowOnMobile', 'Mostrar en movil', 'bi-phone', $showOnMobile);
|
|
|
|
// =============================================
|
|
// Checkboxes de visibilidad por tipo de página
|
|
// Grupo especial: _page_visibility
|
|
// =============================================
|
|
$html .= ' <hr class="my-3">';
|
|
$html .= ' <p class="small fw-semibold mb-2">';
|
|
$html .= ' <i class="bi bi-eye me-1" style="color: #FF8600;"></i>';
|
|
$html .= ' Mostrar en tipos de pagina';
|
|
$html .= ' </p>';
|
|
|
|
$showOnHome = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_home', true);
|
|
$showOnPosts = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_posts', true);
|
|
$showOnPages = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_pages', true);
|
|
$showOnArchives = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_archives', false);
|
|
$showOnSearch = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_search', false);
|
|
|
|
$html .= ' <div class="row g-2">';
|
|
$html .= ' <div class="col-md-4">';
|
|
$html .= $this->buildPageVisibilityCheckbox('relatedPostVisibilityHome', 'Home', 'bi-house', $showOnHome);
|
|
$html .= ' </div>';
|
|
$html .= ' <div class="col-md-4">';
|
|
$html .= $this->buildPageVisibilityCheckbox('relatedPostVisibilityPosts', 'Posts', 'bi-file-earmark-text', $showOnPosts);
|
|
$html .= ' </div>';
|
|
$html .= ' <div class="col-md-4">';
|
|
$html .= $this->buildPageVisibilityCheckbox('relatedPostVisibilityPages', 'Paginas', 'bi-file-earmark', $showOnPages);
|
|
$html .= ' </div>';
|
|
$html .= ' <div class="col-md-4">';
|
|
$html .= $this->buildPageVisibilityCheckbox('relatedPostVisibilityArchives', 'Archivos', 'bi-archive', $showOnArchives);
|
|
$html .= ' </div>';
|
|
$html .= ' <div class="col-md-4">';
|
|
$html .= $this->buildPageVisibilityCheckbox('relatedPostVisibilitySearch', 'Busqueda', 'bi-search', $showOnSearch);
|
|
$html .= ' </div>';
|
|
$html .= ' </div>';
|
|
|
|
// =============================================
|
|
// Reglas de exclusion avanzadas
|
|
// Grupo especial: _exclusions (Plan 99.11)
|
|
// =============================================
|
|
$exclusionPartial = new ExclusionFormPartial($this->renderer);
|
|
$html .= $exclusionPartial->render($componentId, 'relatedPost');
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildContentGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-card-text me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Contenido';
|
|
$html .= ' </h5>';
|
|
|
|
// Section Title
|
|
$sectionTitle = $this->renderer->getFieldValue($componentId, 'content', 'section_title', 'Descubre Mas Contenido');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="relatedPostSectionTitle" class="form-label small mb-1 fw-semibold">Titulo de seccion</label>';
|
|
$html .= ' <input type="text" id="relatedPostSectionTitle" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($sectionTitle) . '">';
|
|
$html .= ' </div>';
|
|
|
|
// Posts per page
|
|
$postsPerPage = $this->renderer->getFieldValue($componentId, 'content', 'posts_per_page', '12');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="relatedPostPerPage" class="form-label small mb-1 fw-semibold">Posts por pagina</label>';
|
|
$html .= ' <input type="number" id="relatedPostPerPage" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($postsPerPage) . '" min="1" max="50">';
|
|
$html .= ' </div>';
|
|
|
|
// Order by
|
|
$orderby = $this->renderer->getFieldValue($componentId, 'content', 'orderby', 'rand');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="relatedPostOrderby" class="form-label small mb-1 fw-semibold">Ordenar por</label>';
|
|
$html .= ' <select id="relatedPostOrderby" class="form-select form-select-sm">';
|
|
$html .= ' <option value="rand"' . ($orderby === 'rand' ? ' selected' : '') . '>Aleatorio</option>';
|
|
$html .= ' <option value="date"' . ($orderby === 'date' ? ' selected' : '') . '>Fecha</option>';
|
|
$html .= ' <option value="title"' . ($orderby === 'title' ? ' selected' : '') . '>Titulo</option>';
|
|
$html .= ' <option value="comment_count"' . ($orderby === 'comment_count' ? ' selected' : '') . '>Comentarios</option>';
|
|
$html .= ' <option value="menu_order"' . ($orderby === 'menu_order' ? ' selected' : '') . '>Orden de menu</option>';
|
|
$html .= ' </select>';
|
|
$html .= ' </div>';
|
|
|
|
// Order direction
|
|
$order = $this->renderer->getFieldValue($componentId, 'content', 'order', 'DESC');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="relatedPostOrder" class="form-label small mb-1 fw-semibold">Direccion</label>';
|
|
$html .= ' <select id="relatedPostOrder" class="form-select form-select-sm">';
|
|
$html .= ' <option value="DESC"' . ($order === 'DESC' ? ' selected' : '') . '>Descendente</option>';
|
|
$html .= ' <option value="ASC"' . ($order === 'ASC' ? ' selected' : '') . '>Ascendente</option>';
|
|
$html .= ' </select>';
|
|
$html .= ' </div>';
|
|
|
|
// Show pagination
|
|
$showPagination = $this->renderer->getFieldValue($componentId, 'content', 'show_pagination', true);
|
|
$html .= $this->buildSwitch('relatedPostShowPagination', 'Mostrar paginacion', 'bi-three-dots', $showPagination);
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildLayoutGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-grid me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Disposicion';
|
|
$html .= ' </h5>';
|
|
|
|
// Columns desktop
|
|
$colsDesktop = $this->renderer->getFieldValue($componentId, 'layout', 'columns_desktop', '3');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="relatedPostColsDesktop" class="form-label small mb-1 fw-semibold">';
|
|
$html .= ' <i class="bi bi-display me-1" style="color: #FF8600;"></i>';
|
|
$html .= ' Columnas escritorio';
|
|
$html .= ' </label>';
|
|
$html .= ' <select id="relatedPostColsDesktop" class="form-select form-select-sm">';
|
|
$html .= ' <option value="2"' . ($colsDesktop === '2' ? ' selected' : '') . '>2 columnas</option>';
|
|
$html .= ' <option value="3"' . ($colsDesktop === '3' ? ' selected' : '') . '>3 columnas</option>';
|
|
$html .= ' <option value="4"' . ($colsDesktop === '4' ? ' selected' : '') . '>4 columnas</option>';
|
|
$html .= ' </select>';
|
|
$html .= ' </div>';
|
|
|
|
// Columns tablet
|
|
$colsTablet = $this->renderer->getFieldValue($componentId, 'layout', 'columns_tablet', '2');
|
|
$html .= ' <div class="mb-3">';
|
|
$html .= ' <label for="relatedPostColsTablet" class="form-label small mb-1 fw-semibold">';
|
|
$html .= ' <i class="bi bi-tablet me-1" style="color: #FF8600;"></i>';
|
|
$html .= ' Columnas tablet';
|
|
$html .= ' </label>';
|
|
$html .= ' <select id="relatedPostColsTablet" class="form-select form-select-sm">';
|
|
$html .= ' <option value="1"' . ($colsTablet === '1' ? ' selected' : '') . '>1 columna</option>';
|
|
$html .= ' <option value="2"' . ($colsTablet === '2' ? ' selected' : '') . '>2 columnas</option>';
|
|
$html .= ' <option value="3"' . ($colsTablet === '3' ? ' selected' : '') . '>3 columnas</option>';
|
|
$html .= ' </select>';
|
|
$html .= ' </div>';
|
|
|
|
// Columns mobile
|
|
$colsMobile = $this->renderer->getFieldValue($componentId, 'layout', 'columns_mobile', '1');
|
|
$html .= ' <div class="mb-0">';
|
|
$html .= ' <label for="relatedPostColsMobile" class="form-label small mb-1 fw-semibold">';
|
|
$html .= ' <i class="bi bi-phone me-1" style="color: #FF8600;"></i>';
|
|
$html .= ' Columnas movil';
|
|
$html .= ' </label>';
|
|
$html .= ' <select id="relatedPostColsMobile" class="form-select form-select-sm">';
|
|
$html .= ' <option value="1"' . ($colsMobile === '1' ? ' selected' : '') . '>1 columna</option>';
|
|
$html .= ' <option value="2"' . ($colsMobile === '2' ? ' selected' : '') . '>2 columnas</option>';
|
|
$html .= ' </select>';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildTypographyGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-fonts me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Tipografia';
|
|
$html .= ' </h5>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$sectionTitleSize = $this->renderer->getFieldValue($componentId, 'typography', 'section_title_size', '1.75rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostSectionTitleSize" class="form-label small mb-1 fw-semibold">Tamano titulo seccion</label>';
|
|
$html .= ' <input type="text" id="relatedPostSectionTitleSize" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($sectionTitleSize) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$sectionTitleWeight = $this->renderer->getFieldValue($componentId, 'typography', 'section_title_weight', '500');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostSectionTitleWeight" class="form-label small mb-1 fw-semibold">Peso titulo seccion</label>';
|
|
$html .= ' <input type="text" id="relatedPostSectionTitleWeight" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($sectionTitleWeight) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$cardTitleSize = $this->renderer->getFieldValue($componentId, 'typography', 'card_title_size', '1rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostCardTitleSize" class="form-label small mb-1 fw-semibold">Tamano titulo card</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardTitleSize" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardTitleSize) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$cardTitleWeight = $this->renderer->getFieldValue($componentId, 'typography', 'card_title_weight', '500');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostCardTitleWeight" class="form-label small mb-1 fw-semibold">Peso titulo card</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardTitleWeight" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardTitleWeight) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildColorsGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-palette me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Colores';
|
|
$html .= ' </h5>';
|
|
|
|
// Seccion
|
|
$html .= ' <p class="small fw-semibold mb-2">Seccion</p>';
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$sectionTitleColor = $this->renderer->getFieldValue($componentId, 'colors', 'section_title_color', '#212529');
|
|
$html .= $this->buildColorPicker('relatedPostSectionTitleColor', 'Titulo seccion', $sectionTitleColor);
|
|
|
|
$html .= ' </div>';
|
|
|
|
// Cards
|
|
$html .= ' <p class="small fw-semibold mb-2">Cards</p>';
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$cardBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_bg_color', '#ffffff');
|
|
$html .= $this->buildColorPicker('relatedPostCardBgColor', 'Fondo card', $cardBgColor);
|
|
|
|
$cardTitleColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_title_color', '#212529');
|
|
$html .= $this->buildColorPicker('relatedPostCardTitleColor', 'Titulo card', $cardTitleColor);
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$cardHoverBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_hover_bg_color', '#f8f9fa');
|
|
$html .= $this->buildColorPicker('relatedPostCardHoverBgColor', 'Fondo hover', $cardHoverBgColor);
|
|
|
|
$html .= ' </div>';
|
|
|
|
// Paginacion
|
|
$html .= ' <p class="small fw-semibold mb-2">Paginacion</p>';
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$paginationBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_bg_color', '#ffffff');
|
|
$html .= $this->buildColorPicker('relatedPostPaginationBgColor', 'Fondo', $paginationBgColor);
|
|
|
|
$paginationTextColor = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_text_color', '#0d6efd');
|
|
$html .= $this->buildColorPicker('relatedPostPaginationTextColor', 'Texto', $paginationTextColor);
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$paginationActiveBg = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_active_bg', '#0d6efd');
|
|
$html .= $this->buildColorPicker('relatedPostPaginationActiveBg', 'Activo fondo', $paginationActiveBg);
|
|
|
|
$paginationActiveText = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_active_text', '#ffffff');
|
|
$html .= $this->buildColorPicker('relatedPostPaginationActiveText', 'Activo texto', $paginationActiveText);
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildSpacingGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-arrows-move me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Espaciado';
|
|
$html .= ' </h5>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$sectionMarginTop = $this->renderer->getFieldValue($componentId, 'spacing', 'section_margin_top', '3rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostSectionMarginTop" class="form-label small mb-1 fw-semibold">Margen superior</label>';
|
|
$html .= ' <input type="text" id="relatedPostSectionMarginTop" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($sectionMarginTop) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$sectionMarginBottom = $this->renderer->getFieldValue($componentId, 'spacing', 'section_margin_bottom', '3rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostSectionMarginBottom" class="form-label small mb-1 fw-semibold">Margen inferior</label>';
|
|
$html .= ' <input type="text" id="relatedPostSectionMarginBottom" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($sectionMarginBottom) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$titleMarginBottom = $this->renderer->getFieldValue($componentId, 'spacing', 'title_margin_bottom', '1.5rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostTitleMarginBottom" class="form-label small mb-1 fw-semibold">Margen titulo</label>';
|
|
$html .= ' <input type="text" id="relatedPostTitleMarginBottom" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($titleMarginBottom) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$gridGap = $this->renderer->getFieldValue($componentId, 'spacing', 'grid_gap', '1.5rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostGridGap" class="form-label small mb-1 fw-semibold">Espacio cards</label>';
|
|
$html .= ' <input type="text" id="relatedPostGridGap" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($gridGap) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="row g-2 mb-0">';
|
|
|
|
$cardPadding = $this->renderer->getFieldValue($componentId, 'spacing', 'card_padding', '1.5rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostCardPadding" class="form-label small mb-1 fw-semibold">Padding card</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardPadding" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardPadding) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$paginationMarginTop = $this->renderer->getFieldValue($componentId, 'spacing', 'pagination_margin_top', '1rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostPaginationMarginTop" class="form-label small mb-1 fw-semibold">Margen paginacion</label>';
|
|
$html .= ' <input type="text" id="relatedPostPaginationMarginTop" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($paginationMarginTop) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildEffectsGroup(string $componentId): string
|
|
{
|
|
$html = '<div class="card shadow-sm mb-3" style="border-left: 4px solid #1e3a5f;">';
|
|
$html .= ' <div class="card-body">';
|
|
$html .= ' <h5 class="fw-bold mb-3" style="color: #1e3a5f;">';
|
|
$html .= ' <i class="bi bi-magic me-2" style="color: #FF8600;"></i>';
|
|
$html .= ' Efectos Visuales';
|
|
$html .= ' </h5>';
|
|
|
|
$html .= ' <div class="row g-2 mb-3">';
|
|
|
|
$cardBorderRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_border_radius', '0.375rem');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostCardBorderRadius" class="form-label small mb-1 fw-semibold">Radio borde card</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardBorderRadius" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardBorderRadius) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$cardTransition = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_transition', '0.3s ease');
|
|
$html .= ' <div class="col-6">';
|
|
$html .= ' <label for="relatedPostCardTransition" class="form-label small mb-1 fw-semibold">Transicion</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardTransition" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardTransition) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="mb-3">';
|
|
$cardShadow = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_shadow', '0 .125rem .25rem rgba(0,0,0,.075)');
|
|
$html .= ' <label for="relatedPostCardShadow" class="form-label small mb-1 fw-semibold">Sombra card</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardShadow" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardShadow) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' <div class="mb-0">';
|
|
$cardHoverShadow = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_hover_shadow', '0 .5rem 1rem rgba(0,0,0,.15)');
|
|
$html .= ' <label for="relatedPostCardHoverShadow" class="form-label small mb-1 fw-semibold">Sombra hover</label>';
|
|
$html .= ' <input type="text" id="relatedPostCardHoverShadow" class="form-control form-control-sm" ';
|
|
$html .= ' value="' . esc_attr($cardHoverShadow) . '">';
|
|
$html .= ' </div>';
|
|
|
|
$html .= ' </div>';
|
|
$html .= '</div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildSwitch(string $id, string $label, string $icon, mixed $checked): string
|
|
{
|
|
$checked = $checked === true || $checked === '1' || $checked === 1;
|
|
|
|
$html = ' <div class="mb-2">';
|
|
$html .= ' <div class="form-check form-switch">';
|
|
$html .= sprintf(
|
|
' <input class="form-check-input" type="checkbox" id="%s" %s>',
|
|
esc_attr($id),
|
|
$checked ? 'checked' : ''
|
|
);
|
|
$html .= sprintf(
|
|
' <label class="form-check-label small" for="%s">',
|
|
esc_attr($id)
|
|
);
|
|
$html .= sprintf(' <i class="bi %s me-1" style="color: #FF8600;"></i>', esc_attr($icon));
|
|
$html .= sprintf(' <strong>%s</strong>', esc_html($label));
|
|
$html .= ' </label>';
|
|
$html .= ' </div>';
|
|
$html .= ' </div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildColorPicker(string $id, string $label, string $value): string
|
|
{
|
|
$html = ' <div class="col-6">';
|
|
$html .= sprintf(
|
|
' <label class="form-label small fw-semibold">%s</label>',
|
|
esc_html($label)
|
|
);
|
|
$html .= ' <div class="input-group input-group-sm">';
|
|
$html .= sprintf(
|
|
' <input type="color" class="form-control form-control-color" id="%s" value="%s">',
|
|
esc_attr($id),
|
|
esc_attr($value)
|
|
);
|
|
$html .= sprintf(
|
|
' <span class="input-group-text" id="%sValue">%s</span>',
|
|
esc_attr($id),
|
|
esc_html(strtoupper($value))
|
|
);
|
|
$html .= ' </div>';
|
|
$html .= ' </div>';
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function buildPageVisibilityCheckbox(string $id, string $label, string $icon, mixed $checked): string
|
|
{
|
|
$checked = $checked === true || $checked === '1' || $checked === 1;
|
|
|
|
$html = ' <div class="form-check form-check-checkbox mb-2">';
|
|
$html .= sprintf(
|
|
' <input class="form-check-input" type="checkbox" id="%s" %s>',
|
|
esc_attr($id),
|
|
$checked ? 'checked' : ''
|
|
);
|
|
$html .= sprintf(
|
|
' <label class="form-check-label small" for="%s">',
|
|
esc_attr($id)
|
|
);
|
|
$html .= sprintf(' <i class="bi %s me-1" style="color: #FF8600;"></i>', esc_attr($icon));
|
|
$html .= sprintf(' %s', esc_html($label));
|
|
$html .= ' </label>';
|
|
$html .= ' </div>';
|
|
|
|
return $html;
|
|
}
|
|
}
|