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\Section;
|
||||||
use Filament\Schemas\Components\View;
|
use Filament\Schemas\Components\View;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Forms\Components\CodeEditor\Enums\Language;
|
||||||
|
|
||||||
class HeaderTemplateForm
|
class HeaderTemplateForm
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,7 @@ class HeaderTemplateForm
|
|||||||
->label(__('header-templates.field_html_content'))
|
->label(__('header-templates.field_html_content'))
|
||||||
->required()
|
->required()
|
||||||
->live(onBlur: false) // Real-time updates
|
->live(onBlur: false) // Real-time updates
|
||||||
|
->language(Language::Html)
|
||||||
->columnSpanFull()
|
->columnSpanFull()
|
||||||
->helperText(__('header-templates.field_html_content_help'))
|
->helperText(__('header-templates.field_html_content_help'))
|
||||||
->extraAttributes([
|
->extraAttributes([
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use Filament\Forms\Components\Toggle;
|
|||||||
use Filament\Schemas\Components\Section;
|
use Filament\Schemas\Components\Section;
|
||||||
use Filament\Schemas\Components\View;
|
use Filament\Schemas\Components\View;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Forms\Components\CodeEditor\Enums\Language;
|
||||||
|
|
||||||
class SectionTemplateForm
|
class SectionTemplateForm
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,7 @@ class SectionTemplateForm
|
|||||||
->label(__('section-templates.field_html_content'))
|
->label(__('section-templates.field_html_content'))
|
||||||
->required()
|
->required()
|
||||||
->live(onBlur: false) // Real-time updates
|
->live(onBlur: false) // Real-time updates
|
||||||
|
->language(Language::Html)
|
||||||
->columnSpanFull()
|
->columnSpanFull()
|
||||||
->helperText(__('section-templates.field_html_content_help'))
|
->helperText(__('section-templates.field_html_content_help'))
|
||||||
->extraAttributes([
|
->extraAttributes([
|
||||||
|
|||||||
@@ -106,6 +106,90 @@ class TemplatePreviewService
|
|||||||
return $html;
|
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
|
* Get full HTML structure for preview
|
||||||
*
|
*
|
||||||
@@ -121,6 +205,10 @@ class TemplatePreviewService
|
|||||||
|
|
||||||
$viewport = $meta['viewport'] ?? 'width=device-width, initial-scale=1';
|
$viewport = $meta['viewport'] ?? 'width=device-width, initial-scale=1';
|
||||||
$charset = $meta['charset'] ?? 'utf-8';
|
$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
|
// Wrap content based on type
|
||||||
$bodyContent = match($type) {
|
$bodyContent = match($type) {
|
||||||
@@ -137,6 +225,7 @@ class TemplatePreviewService
|
|||||||
<meta charset="{$charset}">
|
<meta charset="{$charset}">
|
||||||
<meta name="viewport" content="{$viewport}">
|
<meta name="viewport" content="{$viewport}">
|
||||||
<title>Template Preview</title>
|
<title>Template Preview</title>
|
||||||
|
<base href="{$baseUrl}">
|
||||||
{$cssLinks}
|
{$cssLinks}
|
||||||
</head>
|
</head>
|
||||||
<body style="margin: 0; padding: 0;">
|
<body style="margin: 0; padding: 0;">
|
||||||
|
|||||||
Reference in New Issue
Block a user