diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6e13734032e..580c3cab509 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -24,6 +24,7 @@ This serves two purposes: - Minor: The documentation article component now supports disabling the semantic rendering using a falsy value in https://github.com/hydephp/develop/pull/1566 - Minor: Changed the default build task message to make it more concise in https://github.com/hydephp/develop/pull/1659 - Minor: Data collection files are now validated for syntax errors during discovery in https://github.com/hydephp/develop/pull/1732 +- Minor: Methods in the `Includes` facade now return `HtmlString` objects instead of `string` in https://github.com/hydephp/develop/pull/1738. For more information, see below. - The `hasFeature` method on the Hyde facade and HydeKernel now only accepts a Feature enum value instead of a string for its parameter. - Changed how the documentation search is generated, to be an `InMemoryPage` instead of a post-build task. - Media asset files are now copied using the new build task instead of the deprecated `BuildService::transferMediaAssets()` method. @@ -223,6 +224,22 @@ For example, if you triggered the media transfer with a build service method cal (new TransferMediaAssets())->run(); ``` +### Includes facade changes + +The following methods in the `Includes` facade now return `HtmlString` objects instead of `string`: + +- `Includes::html()` +- `Includes::blade()` +- `Includes::markdown()` + +- This means that you no longer need to use `{!! !!}` to render the output of these methods in Blade templates, instead just use `{{ }}`. +- If you have used the return value of these methods in custom code, you may need to adjust your code to work with the new return type. +- **Note:** Remember that this means that includes are **no longer escaped** by default, so make sure to escape the output if necessary, for example if the content is user-generated. + - (Use `{{ e(Includes::html('foo')) }}` instead of `{{ Includes::html('foo') }}` to escape the output, matching the previous behavior.) + +For more information, see the RFC that proposed this change: https://github.com/hydephp/develop/issues/1734 +The RFC wasd implemented in https://github.com/hydephp/develop/pull/1738 + ### DataCollection API changes The DataCollection feature has been reworked to improve the developer experience and make it more consistent with the rest of the API. diff --git a/docs/digging-deeper/helpers.md b/docs/digging-deeper/helpers.md index 20984bd12eb..8cde4e71f1d 100644 --- a/docs/digging-deeper/helpers.md +++ b/docs/digging-deeper/helpers.md @@ -75,6 +75,14 @@ All methods will return `null` if the file does not exist. However, you can supply a default value as the second argument to be used instead. Remember that Markdown and Blade defaults will also be rendered to HTML. +Includes are particularly useful in Blade views, as you can echo them directly. You do not need to import the namespace, as it is already aliased. + +```blade + +``` + ```php use Hyde\Support\Includes; diff --git a/packages/framework/src/Support/Includes.php b/packages/framework/src/Support/Includes.php index 6e88fb4506f..182ce218c7b 100644 --- a/packages/framework/src/Support/Includes.php +++ b/packages/framework/src/Support/Includes.php @@ -6,6 +6,7 @@ use Hyde\Hyde; use Hyde\Facades\Filesystem; +use Illuminate\Support\HtmlString; use Hyde\Markdown\Models\MarkdownDocument; use Hyde\Markdown\Models\Markdown; use Illuminate\Support\Facades\Blade; @@ -61,17 +62,17 @@ public static function get(string $filename, ?string $default = null): ?string * * @param string $filename The name of the partial file, with or without the extension. * @param string|null $default The default value to return if the partial is not found. - * @return string|null The raw contents of the partial file, or the default value if not found. + * @return HtmlString|null The contents of the partial file, or the default value if not found. */ - public static function html(string $filename, ?string $default = null): ?string + public static function html(string $filename, ?string $default = null): ?HtmlString { $path = static::normalizePath($filename, '.html'); if (! Filesystem::exists($path)) { - return $default === null ? null : $default; + return $default === null ? null : new HtmlString($default); } - return Filesystem::get($path); + return new HtmlString(Filesystem::get($path)); } /** @@ -79,17 +80,17 @@ public static function html(string $filename, ?string $default = null): ?string * * @param string $filename The name of the partial file, with or without the extension. * @param string|null $default The default value to return if the partial is not found. - * @return string|null The rendered contents of the partial file, or the default value if not found. + * @return HtmlString|null The rendered contents of the partial file, or the default value if not found. */ - public static function markdown(string $filename, ?string $default = null): ?string + public static function markdown(string $filename, ?string $default = null): ?HtmlString { $path = static::normalizePath($filename, '.md'); if (! Filesystem::exists($path)) { - return $default === null ? null : trim(Markdown::render($default, MarkdownDocument::class)); + return $default === null ? null : new HtmlString(trim(Markdown::render($default, MarkdownDocument::class))); } - return trim(Markdown::render(Filesystem::get($path), MarkdownDocument::class)); + return new HtmlString(trim(Markdown::render(Filesystem::get($path), MarkdownDocument::class))); } /** @@ -97,17 +98,17 @@ public static function markdown(string $filename, ?string $default = null): ?str * * @param string $filename The name of the partial file, with or without the extension. * @param string|null $default The default value to return if the partial is not found. - * @return string|null The rendered contents of the partial file, or the default value if not found. + * @return HtmlString|null The rendered contents of the partial file, or the default value if not found. */ - public static function blade(string $filename, ?string $default = null): ?string + public static function blade(string $filename, ?string $default = null): ?HtmlString { $path = static::normalizePath($filename, '.blade.php'); if (! Filesystem::exists($path)) { - return $default === null ? null : Blade::render($default); + return $default === null ? null : new HtmlString(Blade::render($default)); } - return Blade::render(Filesystem::get($path)); + return new HtmlString(Blade::render(Filesystem::get($path))); } protected static function normalizePath(string $filename, string $extension): string diff --git a/packages/framework/tests/Feature/IncludesFacadeTest.php b/packages/framework/tests/Feature/IncludesFacadeTest.php index 860467c5656..92ccdd2cb9a 100644 --- a/packages/framework/tests/Feature/IncludesFacadeTest.php +++ b/packages/framework/tests/Feature/IncludesFacadeTest.php @@ -8,6 +8,7 @@ use Hyde\Support\Includes; use Hyde\Hyde; use Hyde\Testing\TestCase; +use Illuminate\Support\HtmlString; use Illuminate\Support\Facades\Blade; /** @@ -58,20 +59,20 @@ public function testHtmlReturnsRenderedPartial() { $expected = '
$placeholder
", $rendered); + $this->assertStringNotContainsString($attribution, $rendered->toHtml()); + $this->assertHtmlStringIsSame("$placeholder
", $rendered); } public function testAdvancedMarkdownDocumentIsCompiledToHtml() @@ -192,7 +193,7 @@ public function testAdvancedMarkdownDocumentIsCompiledToHtml() HTML; $this->file('resources/includes/advanced.md', $markdown); - $this->assertSame($expected, Includes::markdown('advanced.md')); + $this->assertHtmlStringIsSame($expected, Includes::markdown('advanced.md')); } public function testAdvancedBladePartialIsCompiledToHtml() @@ -217,7 +218,7 @@ public function testAdvancedBladePartialIsCompiledToHtml() HTML; $this->file('resources/includes/advanced.blade.php', $blade); - $this->assertSame($expected, Includes::blade('advanced.blade.php')); + $this->assertHtmlStringIsSame($expected, Includes::blade('advanced.blade.php')); } public function testIncludesUsageFromBladeView() @@ -257,11 +258,17 @@ public function testIncludesUsageFromBladeView()