diff --git a/app/HomeSlide.php b/app/HomeSlide.php index f3ea80be5..3cd7889fd 100644 --- a/app/HomeSlide.php +++ b/app/HomeSlide.php @@ -71,7 +71,22 @@ public function descriptionForLocale(?string $locale = null): string if (! empty($overrides[$locale]['description'])) { return (string) $overrides[$locale]['description']; } - return (string) __($this->description ?? ''); + + return (string) ($this->description ?? ''); + } + + /** + * Resolve lang keys to translated strings, or return rich text / plain content as stored. + */ + public static function resolveLocalizedRichText(string $value): string + { + $plain = trim(strip_tags($value)); + + if ($plain !== '' && $plain === trim($value) && str_contains($plain, '.') && ! str_contains($plain, ' ')) { + return (string) __($plain); + } + + return $value; } public function buttonTextForLocale(?string $locale = null): string @@ -96,7 +111,7 @@ public function button2TextForLocale(?string $locale = null): ?string } /** - * Sanitize homepage slide description HTML, allowing only safe links. + * Sanitize homepage slide description HTML, allowing Trix-style formatting and links. */ public static function sanitizeDescriptionHtml(string $html): string { @@ -104,6 +119,12 @@ public static function sanitizeDescriptionHtml(string $html): string return ''; } + $html = trim($html); + + if ($html === strip_tags($html)) { + return nl2br(e($html), false); + } + return (string) Purify::config('home_slide')->clean($html); } diff --git a/app/Nova/HomeSlide.php b/app/Nova/HomeSlide.php index 4f674054a..4e481d6ee 100644 --- a/app/Nova/HomeSlide.php +++ b/app/Nova/HomeSlide.php @@ -10,6 +10,7 @@ use Laravel\Nova\Fields\Number; use Laravel\Nova\Fields\Text; use Laravel\Nova\Fields\Textarea; +use Laravel\Nova\Fields\Trix; use Laravel\Nova\Http\Requests\NovaRequest; use Laravel\Nova\Panel; use App\Nova\Actions\ExportHomeSlideLocaleOverrides; @@ -174,6 +175,7 @@ public function fields(Request $request): array ->nullable() ->onlyOnForms() ->hideFromIndex() + ->help('Plain text or HTML (line breaks and links supported). Copy from the English Trix editor if needed.') ->resolveUsing(function () use ($locale) { $overrides = $this->resource->locale_overrides ?? []; return $overrides[$locale]['description'] ?? ''; @@ -241,9 +243,9 @@ public function fields(Request $request): array ->rules('required') ->help('Lang key (e.g. home.banner4_title) for automatic translation per locale from resources/lang/en/home.php, or plain text. English is default.'), - Textarea::make('Description', 'description') + Trix::make('Description', 'description') ->nullable() - ->help('Lang key (e.g. home.banner4_description) or plain text. HTML links allowed, e.g. Check our Careers in Digital page! Translated via resources/lang per locale.'), + ->help('Rich text: links, line breaks, and bold text. Or use a lang key (e.g. home.banner4_description) for automatic translation per locale.'), Text::make('Primary button URL', 'url')->rules('required')->hideFromIndex(), Text::make('Primary button label', 'button_text') diff --git a/config/purify.php b/config/purify.php index 26eea827b..42024f131 100644 --- a/config/purify.php +++ b/config/purify.php @@ -52,7 +52,7 @@ 'home_slide' => [ 'Core.Encoding' => 'utf-8', 'HTML.Doctype' => 'HTML 4.01 Transitional', - 'HTML.Allowed' => 'a[href|target|rel]', + 'HTML.Allowed' => 'div,p,br,strong,b,em,i,a[href|target|rel]', 'HTML.ForbiddenElements' => '', 'CSS.AllowedProperties' => '', 'AutoFormat.AutoParagraph' => false, diff --git a/resources/views/static/home.blade.php b/resources/views/static/home.blade.php index c5ef99e28..5b069b4cc 100644 --- a/resources/views/static/home.blade.php +++ b/resources/views/static/home.blade.php @@ -92,10 +92,10 @@ function countdownTimer(targetDate) { class="text-[#1C4DA1] text-[30px] md:text-[60px] leading-9 md:leading-[72px] font-normal font-['Montserrat'] mb-4 max-w-[525px]"> {{ __($activity['title']) }} -
- {!! \App\HomeSlide::sanitizeDescriptionHtml(__($activity['description'] ?? '')) !!} -
+