buildHeader(); $html .= '
'; // Columna izquierda $html .= '
'; $html .= $this->buildShortcodeGuide(); $html .= $this->buildVisibilityGroup($componentId); $html .= $this->buildContentGroup($componentId); $html .= $this->buildMediaGroup($componentId); $html .= '
'; // Columna derecha $html .= '
'; $html .= $this->buildLayoutGroup($componentId); $html .= $this->buildTypographyGroup($componentId); $html .= $this->buildColorsGroup($componentId); $html .= $this->buildSpacingGroup($componentId); $html .= $this->buildEffectsGroup($componentId); $html .= '
'; $html .= '
'; return $html; } private function buildHeader(): string { $html = '
renderer->getFieldValue($componentId, 'visibility', 'is_enabled', true); $html .= $this->buildSwitch('postGridEnabled', 'Activar componente', 'bi-power', $enabled); $showOnDesktop = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_desktop', true); $html .= $this->buildSwitch('postGridShowOnDesktop', 'Mostrar en escritorio', 'bi-display', $showOnDesktop); $showOnMobile = $this->renderer->getFieldValue($componentId, 'visibility', 'show_on_mobile', true); $html .= $this->buildSwitch('postGridShowOnMobile', 'Mostrar en movil', 'bi-phone', $showOnMobile); // Checkboxes de visibilidad por tipo de página $html .= '
'; $html .= '

'; $html .= ' '; $html .= ' Mostrar en tipos de pagina'; $html .= '

'; $showOnHome = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_home', true); $showOnPosts = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_posts', false); $showOnPages = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_pages', false); $showOnArchives = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_archives', true); $showOnSearch = $this->renderer->getFieldValue($componentId, '_page_visibility', 'show_on_search', true); $html .= '
'; $html .= '
'; $html .= $this->buildPageVisibilityCheckbox('postGridVisibilityHome', 'Home', 'bi-house', $showOnHome); $html .= '
'; $html .= '
'; $html .= $this->buildPageVisibilityCheckbox('postGridVisibilityPosts', 'Posts', 'bi-file-earmark-text', $showOnPosts); $html .= '
'; $html .= '
'; $html .= $this->buildPageVisibilityCheckbox('postGridVisibilityPages', 'Paginas', 'bi-file-earmark', $showOnPages); $html .= '
'; $html .= '
'; $html .= $this->buildPageVisibilityCheckbox('postGridVisibilityArchives', 'Archivos', 'bi-archive', $showOnArchives); $html .= '
'; $html .= '
'; $html .= $this->buildPageVisibilityCheckbox('postGridVisibilitySearch', 'Busqueda', 'bi-search', $showOnSearch); $html .= '
'; $html .= '
'; // Reglas de exclusion $exclusionPartial = new ExclusionFormPartial($this->renderer); $html .= $exclusionPartial->render($componentId, 'postGrid'); $html .= '
'; $html .= ''; return $html; } private function buildContentGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Contenido'; $html .= '
'; // Switches de contenido $showThumbnail = $this->renderer->getFieldValue($componentId, 'content', 'show_thumbnail', true); $html .= $this->buildSwitch('postGridShowThumbnail', 'Mostrar imagen destacada', 'bi-image', $showThumbnail); $showExcerpt = $this->renderer->getFieldValue($componentId, 'content', 'show_excerpt', true); $html .= $this->buildSwitch('postGridShowExcerpt', 'Mostrar extracto', 'bi-text-paragraph', $showExcerpt); $showMeta = $this->renderer->getFieldValue($componentId, 'content', 'show_meta', true); $html .= $this->buildSwitch('postGridShowMeta', 'Mostrar metadatos', 'bi-info-circle', $showMeta); $showCategories = $this->renderer->getFieldValue($componentId, 'content', 'show_categories', true); $html .= $this->buildSwitch('postGridShowCategories', 'Mostrar categorias', 'bi-folder', $showCategories); $html .= '
'; // Excerpt length $excerptLength = $this->renderer->getFieldValue($componentId, 'content', 'excerpt_length', '20'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // Read more text $readMoreText = $this->renderer->getFieldValue($componentId, 'content', 'read_more_text', 'Leer mas'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // No posts message $noPostsMessage = $this->renderer->getFieldValue($componentId, 'content', 'no_posts_message', 'No se encontraron publicaciones'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildLayoutGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Disposicion'; $html .= '
'; // Columns desktop $colsDesktop = $this->renderer->getFieldValue($componentId, 'layout', 'columns_desktop', '3'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // Columns tablet $colsTablet = $this->renderer->getFieldValue($componentId, 'layout', 'columns_tablet', '2'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // Columns mobile $colsMobile = $this->renderer->getFieldValue($componentId, 'layout', 'columns_mobile', '1'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // Image position $imagePosition = $this->renderer->getFieldValue($componentId, 'layout', 'image_position', 'top'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildMediaGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Medios'; $html .= '
'; // Fallback image $fallbackImage = $this->renderer->getFieldValue($componentId, 'media', 'fallback_image', ''); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // Fallback image alt $fallbackImageAlt = $this->renderer->getFieldValue($componentId, 'media', 'fallback_image_alt', 'Imagen por defecto'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildTypographyGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Tipografia'; $html .= '
'; // Heading level $headingLevel = $this->renderer->getFieldValue($componentId, 'typography', 'heading_level', 'h3'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $cardTitleSize = $this->renderer->getFieldValue($componentId, 'typography', 'card_title_size', '1.1rem'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $cardTitleWeight = $this->renderer->getFieldValue($componentId, 'typography', 'card_title_weight', '600'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; $excerptSize = $this->renderer->getFieldValue($componentId, 'typography', 'excerpt_size', '0.9rem'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $metaSize = $this->renderer->getFieldValue($componentId, 'typography', 'meta_size', '0.8rem'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildColorsGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Colores'; $html .= '
'; // Cards $html .= '

Cards

'; $html .= '
'; $cardBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_bg_color', '#ffffff'); $html .= $this->buildColorPicker('postGridCardBgColor', 'Fondo', $cardBgColor); $cardTitleColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_title_color', '#0E2337'); $html .= $this->buildColorPicker('postGridCardTitleColor', 'Titulo', $cardTitleColor); $html .= '
'; $html .= '
'; $cardHoverBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_hover_bg_color', '#f9fafb'); $html .= $this->buildColorPicker('postGridCardHoverBgColor', 'Fondo hover', $cardHoverBgColor); $cardBorderColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_border_color', '#e5e7eb'); $html .= $this->buildColorPicker('postGridCardBorderColor', 'Borde', $cardBorderColor); $html .= '
'; $html .= '
'; $cardHoverBorderColor = $this->renderer->getFieldValue($componentId, 'colors', 'card_hover_border_color', '#FF8600'); $html .= $this->buildColorPicker('postGridCardHoverBorderColor', 'Borde hover', $cardHoverBorderColor); $excerptColor = $this->renderer->getFieldValue($componentId, 'colors', 'excerpt_color', '#6b7280'); $html .= $this->buildColorPicker('postGridExcerptColor', 'Extracto', $excerptColor); $html .= '
'; $html .= '
'; $metaColor = $this->renderer->getFieldValue($componentId, 'colors', 'meta_color', '#9ca3af'); $html .= $this->buildColorPicker('postGridMetaColor', 'Metadatos', $metaColor); $categoryBgColor = $this->renderer->getFieldValue($componentId, 'colors', 'category_bg_color', '#FFF5EB'); $html .= $this->buildColorPicker('postGridCategoryBgColor', 'Fondo cat.', $categoryBgColor); $html .= '
'; $html .= '
'; $categoryTextColor = $this->renderer->getFieldValue($componentId, 'colors', 'category_text_color', '#FF8600'); $html .= $this->buildColorPicker('postGridCategoryTextColor', 'Texto cat.', $categoryTextColor); $html .= '
'; // Paginacion $html .= '

Paginacion

'; $html .= '
'; $paginationColor = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_color', '#0E2337'); $html .= $this->buildColorPicker('postGridPaginationColor', 'Color', $paginationColor); $paginationActiveBg = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_active_bg', '#FF8600'); $html .= $this->buildColorPicker('postGridPaginationActiveBg', 'Activo fondo', $paginationActiveBg); $html .= '
'; $html .= '
'; $paginationActiveColor = $this->renderer->getFieldValue($componentId, 'colors', 'pagination_active_color', '#ffffff'); $html .= $this->buildColorPicker('postGridPaginationActiveColor', 'Activo texto', $paginationActiveColor); $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildSpacingGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Espaciado'; $html .= '
'; // Separación entre cards $html .= '

Separacion entre cards:

'; $html .= '
'; // Gap horizontal (entre columnas) $gapHorizontal = $this->renderer->getFieldValue($componentId, 'spacing', 'gap_horizontal', '24px'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; // Gap vertical (entre filas) $gapVertical = $this->renderer->getFieldValue($componentId, 'spacing', 'gap_vertical', '24px'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; // Padding interno de cada card $html .= '

Padding interno de card:

'; $html .= '
'; $cardPadding = $this->renderer->getFieldValue($componentId, 'spacing', 'card_padding', '20px'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; // Margenes de la seccion $html .= '

Margenes de la seccion:

'; $html .= '
'; $sectionMarginTop = $this->renderer->getFieldValue($componentId, 'spacing', 'section_margin_top', '0px'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $sectionMarginBottom = $this->renderer->getFieldValue($componentId, 'spacing', 'section_margin_bottom', '32px'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildEffectsGroup(string $componentId): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Efectos Visuales'; $html .= '
'; $html .= '
'; $cardBorderRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_border_radius', '0.5rem'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $imageBorderRadius = $this->renderer->getFieldValue($componentId, 'visual_effects', 'image_border_radius', '0.375rem'); $html .= '
'; $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; $cardTransition = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_transition', 'all 0.3s ease'); $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $cardShadow = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_shadow', '0 1px 3px rgba(0,0,0,0.1)'); $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $cardHoverShadow = $this->renderer->getFieldValue($componentId, 'visual_effects', 'card_hover_shadow', '0 4px 12px rgba(0,0,0,0.15)'); $html .= ' '; $html .= ' '; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } private function buildSwitch(string $id, string $label, string $icon, mixed $checked): string { $checked = $checked === true || $checked === '1' || $checked === 1; $html = '
'; $html .= '
'; $html .= sprintf( ' ', esc_attr($id), $checked ? 'checked' : '' ); $html .= sprintf( ' '; $html .= '
'; $html .= '
'; return $html; } private function buildColorPicker(string $id, string $label, string $value): string { $html = '
'; $html .= sprintf( ' ', esc_html($label) ); $html .= '
'; $html .= sprintf( ' ', esc_attr($id), esc_attr($value) ); $html .= sprintf( ' %s', esc_attr($id), esc_html(strtoupper($value)) ); $html .= '
'; $html .= '
'; return $html; } private function buildPageVisibilityCheckbox(string $id, string $label, string $icon, mixed $checked): string { $checked = $checked === true || $checked === '1' || $checked === 1; $html = '
'; $html .= sprintf( ' ', esc_attr($id), $checked ? 'checked' : '' ); $html .= sprintf( ' '; $html .= '
'; return $html; } private function buildShortcodeGuide(): string { $html = '
'; $html .= '
'; $html .= '
'; $html .= ' '; $html .= ' Shortcode [roi_post_grid]'; $html .= '
'; $html .= '

'; $html .= ' Usa este shortcode para insertar grids de posts en cualquier pagina o entrada. '; $html .= ' Los estilos se heredan de la configuracion de este componente.'; $html .= '

'; // Uso basico $html .= '

'; $html .= ' '; $html .= ' Uso basico (9 posts, 3 columnas)'; $html .= '

'; $html .= '
'; $html .= ' [roi_post_grid]'; $html .= '
'; // Por categoria $html .= '

'; $html .= ' '; $html .= ' Filtrar por categoria'; $html .= '

'; $html .= '
'; $html .= ' [roi_post_grid category="precios-unitarios"]'; $html .= '
'; // Personalizar cantidad y columnas $html .= '

'; $html .= ' '; $html .= ' 6 posts en 2 columnas'; $html .= '

'; $html .= '
'; $html .= ' [roi_post_grid posts_per_page="6" columns="2"]'; $html .= '
'; // Con paginacion $html .= '

'; $html .= ' '; $html .= ' Con paginacion'; $html .= '

'; $html .= '
'; $html .= ' [roi_post_grid posts_per_page="12" show_pagination="true"]'; $html .= '
'; // Filtrar por tag $html .= '

'; $html .= ' '; $html .= ' Filtrar por etiqueta'; $html .= '

'; $html .= '
'; $html .= ' [roi_post_grid tag="tutorial"]'; $html .= '
'; // Ejemplo completo $html .= '

'; $html .= ' '; $html .= ' Ejemplo completo'; $html .= '

'; $html .= '
'; $html .= ' [roi_post_grid category="cursos" posts_per_page="6" columns="3" show_meta="false" show_categories="true"]'; $html .= '
'; // Tabla de atributos $html .= '
'; $html .= '

'; $html .= ' '; $html .= ' Atributos disponibles'; $html .= '

'; $html .= '
'; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= ' '; $html .= '
AtributoDefaultDescripcion
posts_per_page9Cantidad de posts
columns3Columnas (1-4)
category-Slug de categoria
exclude_category-Excluir categoria
tag-Slug de etiqueta
author-ID o username
orderbydatedate, title, rand
orderDESCDESC o ASC
show_paginationfalseMostrar paginacion
show_thumbnailtrueMostrar imagen
show_excerpttrueMostrar extracto
show_metatrueFecha y autor
show_categoriestrueBadges categoria
excerpt_length20Palabras extracto
exclude_posts-IDs separados por coma
offset0Saltar N posts
id-ID unico (multiples grids)
class-Clase CSS adicional
'; $html .= '
'; $html .= '
'; $html .= '
'; return $html; } }