Add language support for HTML in template forms: Updated HeaderTemplateForm and SectionTemplateForm to include language specification for CodeEditor components. Introduced a method in TemplatePreviewService to convert relative asset paths to absolute URLs in HTML content, enhancing template rendering accuracy.

This commit is contained in:
Ümit Tunç
2025-10-31 17:24:13 -03:00
parent 8d7b3f0914
commit 6ec04cfdde
3 changed files with 93 additions and 0 deletions
@@ -8,6 +8,7 @@ use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\Forms\Components\CodeEditor\Enums\Language;
class HeaderTemplateForm
{
@@ -27,6 +28,7 @@ class HeaderTemplateForm
->label(__('header-templates.field_html_content'))
->required()
->live(onBlur: false) // Real-time updates
->language(Language::Html)
->columnSpanFull()
->helperText(__('header-templates.field_html_content_help'))
->extraAttributes([
@@ -8,6 +8,7 @@ use Filament\Forms\Components\Toggle;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\View;
use Filament\Schemas\Schema;
use Filament\Forms\Components\CodeEditor\Enums\Language;
class SectionTemplateForm
{
@@ -27,6 +28,7 @@ class SectionTemplateForm
->label(__('section-templates.field_html_content'))
->required()
->live(onBlur: false) // Real-time updates
->language(Language::Html)
->columnSpanFull()
->helperText(__('section-templates.field_html_content_help'))
->extraAttributes([
+89
View File
@@ -106,6 +106,90 @@ class TemplatePreviewService
return $html;
}
/**
* Convert relative asset paths to absolute URLs in HTML content
*
* @param string $html The HTML content
* @return string HTML with absolute URLs
*/
public static function convertRelativePathsToAbsolute(string $html): string
{
// Base URL for assets
$baseUrl = rtrim(url('/'), '/');
// Pattern 1: Match attributes with relative paths (src, href, data-src, etc.)
// Matches: src="assets/...", href="assets/...", data-src="assets/..."
// Also matches: src="/assets/...", href="./assets/...", etc.
$html = preg_replace_callback(
'/(\s+(?:src|href|data-src|data-href|srcset|action|poster|background)\s*=\s*["\'])((?:(?:\.\/|\.\.\/)*)?(?:assets|html|images?|img|css|js|fonts?|media|uploads?)[\/\w\-\.]+)(["\'])/i',
function ($matches) use ($baseUrl) {
$path = $matches[2];
// Skip if already absolute URL (http://, https://, //, data:, mailto:, etc.)
if (preg_match('/^(https?:|\/\/|data:|mailto:|#|javascript:)/i', $path)) {
return $matches[0];
}
// Remove leading slash if exists (we'll add it via asset helper)
$path = ltrim($path, '/');
// Convert to absolute URL using Laravel's asset helper
$absoluteUrl = asset($path);
return $matches[1] . $absoluteUrl . $matches[3];
},
$html
);
// Pattern 2: Match CSS url() functions with relative paths
// Matches: url('assets/...'), url("assets/..."), url(assets/...)
$html = preg_replace_callback(
'/url\s*\(\s*(["\']?)((?:(?:\.\/|\.\.\/)*)?(?:assets|html|images?|img|css|js|fonts?|media|uploads?)[\/\w\-\.]+)\1\s*\)/i',
function ($matches) use ($baseUrl) {
$path = $matches[2];
// Skip if already absolute URL
if (preg_match('/^(https?:|\/\/|data:)/i', $path)) {
return $matches[0];
}
// Remove leading slash
$path = ltrim($path, '/');
// Convert to absolute URL
$absoluteUrl = asset($path);
return 'url(' . $matches[1] . $absoluteUrl . $matches[1] . ')';
},
$html
);
// Pattern 3: Match inline style attributes with background-image or background
// This is already covered by Pattern 2 (url()), but we ensure it works
$html = preg_replace_callback(
'/(style\s*=\s*["\'])([^"\']*)(["\'])/i',
function ($matches) {
// Process url() in style attribute
return $matches[1] . preg_replace_callback(
'/url\s*\(\s*(["\']?)((?:(?:\.\/|\.\.\/)*)?(?:assets|html|images?|img|css|js|fonts?|media|uploads?)[\/\w\-\.]+)\1\s*\)/i',
function ($urlMatches) {
$path = $urlMatches[2];
if (preg_match('/^(https?:|\/\/|data:)/i', $path)) {
return $urlMatches[0];
}
$path = ltrim($path, '/');
$absoluteUrl = asset($path);
return 'url(' . $urlMatches[1] . $absoluteUrl . $urlMatches[1] . ')';
},
$matches[2]
) . $matches[3];
},
$html
);
return $html;
}
/**
* Get full HTML structure for preview
*
@@ -121,6 +205,10 @@ class TemplatePreviewService
$viewport = $meta['viewport'] ?? 'width=device-width, initial-scale=1';
$charset = $meta['charset'] ?? 'utf-8';
$baseUrl = rtrim(url('/'), '/');
// Convert relative paths to absolute URLs in content
$content = self::convertRelativePathsToAbsolute($content);
// Wrap content based on type
$bodyContent = match($type) {
@@ -137,6 +225,7 @@ class TemplatePreviewService
<meta charset="{$charset}">
<meta name="viewport" content="{$viewport}">
<title>Template Preview</title>
<base href="{$baseUrl}">
{$cssLinks}
</head>
<body style="margin: 0; padding: 0;">