feat(theme): add [roi_post_grid] shortcode for static pages
- Create PostGridShortcodeRegistrar for WordPress shortcode registration - Implement RenderPostGridUseCase following Clean Architecture - Add PostGridQueryBuilder for custom WP_Query construction - Add PostGridShortcodeRenderer for HTML/CSS generation - Register shortcode in DIContainer with proper DI - Add shortcode usage guide in post-grid admin panel - Fix sidebar layout: add hide_for_logged_in check to wrapper visibility Shortcode attributes: category, tag, author, posts_per_page, columns, show_pagination, show_thumbnail, show_excerpt, show_meta, etc. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ROITheme\Shared\Infrastructure\Wordpress;
|
||||
|
||||
use ROITheme\Shared\Infrastructure\Di\DIContainer;
|
||||
use ROITheme\Shared\Application\UseCases\RenderPostGrid\RenderPostGridRequest;
|
||||
|
||||
/**
|
||||
* Registra el shortcode [roi_post_grid] en WordPress
|
||||
*
|
||||
* RESPONSABILIDAD:
|
||||
* - Registrar shortcode via add_shortcode
|
||||
* - Sanitizar atributos del shortcode
|
||||
* - Delegar ejecucion a RenderPostGridUseCase
|
||||
*
|
||||
* NO RESPONSABLE DE:
|
||||
* - Logica de negocio
|
||||
* - Construccion de queries
|
||||
* - Generacion de HTML/CSS
|
||||
*
|
||||
* @package ROITheme\Shared\Infrastructure\Wordpress
|
||||
*/
|
||||
final class PostGridShortcodeRegistrar
|
||||
{
|
||||
private const SHORTCODE_TAG = 'roi_post_grid';
|
||||
|
||||
/**
|
||||
* Registra el shortcode en WordPress
|
||||
*/
|
||||
public static function register(): void
|
||||
{
|
||||
add_shortcode(self::SHORTCODE_TAG, [new self(), 'handleShortcode']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback del shortcode
|
||||
*
|
||||
* @param array|string $atts Atributos del shortcode
|
||||
* @return string HTML del grid
|
||||
*/
|
||||
public function handleShortcode($atts): string
|
||||
{
|
||||
$atts = $this->sanitizeAttributes($atts);
|
||||
|
||||
// Obtener paged desde query var si existe
|
||||
$id = $atts['id'] ?? '';
|
||||
$queryVar = !empty($id) ? "paged_{$id}" : 'paged';
|
||||
$atts['paged'] = max(1, (int) get_query_var($queryVar, 1));
|
||||
|
||||
// Crear request DTO
|
||||
$request = RenderPostGridRequest::fromArray($atts);
|
||||
|
||||
// Obtener UseCase desde DIContainer
|
||||
$container = DIContainer::getInstance();
|
||||
$useCase = $container->getRenderPostGridUseCase();
|
||||
|
||||
return $useCase->execute($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitiza atributos del shortcode
|
||||
*
|
||||
* @param array|string $atts
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function sanitizeAttributes($atts): array
|
||||
{
|
||||
$atts = shortcode_atts([
|
||||
'category' => '',
|
||||
'exclude_category' => '',
|
||||
'tag' => '',
|
||||
'author' => '',
|
||||
'posts_per_page' => '9',
|
||||
'columns' => '3',
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'show_pagination' => 'false',
|
||||
'offset' => '0',
|
||||
'exclude_posts' => '',
|
||||
'show_thumbnail' => 'true',
|
||||
'show_excerpt' => 'true',
|
||||
'show_meta' => 'true',
|
||||
'show_categories' => 'true',
|
||||
'excerpt_length' => '20',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
], $atts, self::SHORTCODE_TAG);
|
||||
|
||||
// Sanitizar cada valor
|
||||
return array_map(function ($value) {
|
||||
return is_string($value) ? sanitize_text_field($value) : $value;
|
||||
}, $atts);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user