- Added standard Laravel directory structure and configuration. - Included Svelte and Tailwind configuration for the admin interface. - Added core PHPUnit and testing scripts.
100 lines
3.4 KiB
PHP
100 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
use Illuminate\Support\Facades\Blade;
|
|
use Illuminate\Support\Facades\File;
|
|
|
|
class PageRenderer
|
|
{
|
|
/**
|
|
* Render the page content from JSON.
|
|
*/
|
|
public function render(array $content): string
|
|
{
|
|
$html = '';
|
|
|
|
// Handle multi-locale content structure: { "en": [...], "es": [...] }
|
|
$locale = app()->getLocale();
|
|
$blocks = [];
|
|
|
|
if (isset($content[$locale]) && is_array($content[$locale])) {
|
|
$blocks = $content[$locale];
|
|
} elseif (isset($content[0]) && is_array($content[0])) {
|
|
// Support legacy array format for internal test compatibility if still needed
|
|
// or if content was already extracted to an array.
|
|
$blocks = $content;
|
|
} else {
|
|
// If requested locale not found, try default
|
|
$defaultLocale = config('app.fallback_locale', 'en');
|
|
if (isset($content[$defaultLocale]) && is_array($content[$defaultLocale])) {
|
|
$blocks = $content[$defaultLocale];
|
|
} elseif (!empty($content)) {
|
|
// Last resort: grab the first available locale if any
|
|
$firstLocale = array_key_first($content);
|
|
if (isset($content[$firstLocale]) && is_array($content[$firstLocale])) {
|
|
$blocks = $content[$firstLocale];
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($blocks as $block) {
|
|
$html .= $this->renderBlock($block);
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Render a single block.
|
|
*/
|
|
public function renderBlock(array $block): string
|
|
{
|
|
$type = $block['type'] ?? 'text';
|
|
$data = $block['data'] ?? [];
|
|
|
|
// Map simplified editor types to theme block types if necessary
|
|
$typeMap = [
|
|
'paragraph' => 'paragraph',
|
|
'heading' => 'heading',
|
|
'media' => 'media',
|
|
'text' => 'paragraph', // Alias for text
|
|
'header' => 'heading', // Alias for header
|
|
];
|
|
|
|
$resolvedType = $typeMap[$type] ?? $type;
|
|
|
|
// Support for Grid/Columns layout blocks (pass blocks to them)
|
|
if ($resolvedType === 'columns' || $resolvedType === 'grid') {
|
|
$data['renderer'] = $this;
|
|
}
|
|
|
|
// Determine if a theme-specific component exists
|
|
$themeManager = new ThemeManager();
|
|
$activeTheme = $themeManager->getActiveTheme();
|
|
$themePath = base_path("themes/{$activeTheme}/blocks/{$resolvedType}.blade.php");
|
|
|
|
// Use core views first if in testing or if preferred, but usually themes override core.
|
|
// For testing, we might want to ensure we're using what we just edited.
|
|
// Let's add a debug log or just ensure the path is correct.
|
|
|
|
if (File::exists($themePath)) {
|
|
// We need to use a temporary view or evaluate the blade file
|
|
return Blade::render(File::get($themePath), $data);
|
|
}
|
|
|
|
// Fallback to core block components
|
|
$coreViewPath = "blocks.{$resolvedType}";
|
|
if (view()->exists($coreViewPath)) {
|
|
return view($coreViewPath, $data)->render();
|
|
}
|
|
|
|
// Final fallback: just dump text if it's a text-like block
|
|
if (($resolvedType === 'paragraph' || $resolvedType === 'text') && isset($data['text'])) {
|
|
return "<div>{$data['text']}</div>";
|
|
}
|
|
|
|
return "<!-- Block type [{$type}] not found (resolved as [{$resolvedType}]) -->";
|
|
}
|
|
}
|