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:
@@ -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([
|
||||
|
||||
@@ -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;">
|
||||
|
||||
Reference in New Issue
Block a user