diff --git a/packages/framework/src/Pages/VirtualPage.php b/packages/framework/src/Pages/VirtualPage.php index f3efd438fad..4c94129eabe 100644 --- a/packages/framework/src/Pages/VirtualPage.php +++ b/packages/framework/src/Pages/VirtualPage.php @@ -7,6 +7,7 @@ use Hyde\Markdown\Models\FrontMatter; use Hyde\Pages\Concerns\HydePage; use Hyde\Pages\Contracts\DynamicPage; +use Illuminate\Support\Facades\View; /** * A virtual page is a page that does not have a source file. @@ -20,31 +21,58 @@ */ class VirtualPage extends HydePage implements DynamicPage { - protected string $contents; - public static string $sourceDirectory = ''; public static string $outputDirectory = ''; public static string $fileExtension = ''; - public static function make(string $identifier = '', FrontMatter|array $matter = [], string $contents = ''): static + protected string $contents; + protected string $view; + + public static function make(string $identifier = '', FrontMatter|array $matter = [], string $contents = '', string $view = ''): static { - return new static($identifier, $matter, $contents); + return new static($identifier, $matter, $contents, $view); } - public function __construct(string $identifier, FrontMatter|array $matter = [], string $contents = '') + /** + * Create a new virtual page instance. + * + * The virtual page class offers two content options. You can either pass a string to the $contents parameter, + * Hyde will then save that literally as the page's contents. Alternatively, you can pass a view name to the $view parameter, + * and Hyde will use that view to render the page contents with the supplied front matter during the static site build process. + * + * Note that $contents take precedence over $view, so if you pass both, only $contents will be used. + * + * @param string $identifier The identifier of the page. This is used to generate the route key which is used to create the output filename. + * If the identifier for a virtual page is "foo/bar" the page will be saved to "_site/foo/bar.html". + * @param \Hyde\Markdown\Models\FrontMatter|array $matter The front matter of the page. When using the Blade view rendering option, + * this will be passed to the view. + * @param string $contents The contents of the page. This will be saved as-is to the output file. + * @param string $view The view key for the view to use to render the page contents. + */ + public function __construct(string $identifier, FrontMatter|array $matter = [], string $contents = '', string $view = '') { parent::__construct($identifier, $matter); $this->contents = $contents; + $this->view = $view; } - public function contents(): string + public function getContents(): string { return $this->contents; } + public function getBladeView(): string + { + return $this->view; + } + public function compile(): string { - return $this->contents(); + if (! $this->contents && $this->view) { + return View::make($this->getBladeView(), $this->matter->toArray())->render(); + } + + return $this->getContents(); } } diff --git a/packages/framework/tests/Unit/Pages/VirtualPageUnitTest.php b/packages/framework/tests/Unit/Pages/VirtualPageUnitTest.php index b54228e7352..4a8544b92a3 100644 --- a/packages/framework/tests/Unit/Pages/VirtualPageUnitTest.php +++ b/packages/framework/tests/Unit/Pages/VirtualPageUnitTest.php @@ -4,7 +4,6 @@ namespace Hyde\Framework\Testing\Unit\Pages; -use Error; use Hyde\Foundation\HydeKernel; use Hyde\Foundation\PageCollection; use Hyde\Framework\Factories\Concerns\CoreDataObject; @@ -18,6 +17,8 @@ /** * @covers \Hyde\Pages\VirtualPage + * + * @see \Hyde\Framework\Testing\Unit\VirtualPageTest */ class VirtualPageUnitTest extends BaseHydePageUnitTest { @@ -128,8 +129,7 @@ public function testNavigationMenuGroup() public function testGetBladeView() { - $this->expectException(Error::class); - (new VirtualPage('foo'))->getBladeView(); + $this->assertSame('foo', (new VirtualPage('foo', view: 'foo'))->getBladeView()); } public function testFiles() @@ -219,25 +219,4 @@ public function testMatter() { $this->assertInstanceOf(FrontMatter::class, (new VirtualPage('404'))->matter()); } - - public function testConstructWithContentsString() - { - $this->assertInstanceOf(VirtualPage::class, new VirtualPage('foo', contents: 'bar')); - } - - public function testMakeWithContentsString() - { - $this->assertInstanceOf(VirtualPage::class, VirtualPage::make('foo', contents: 'bar')); - $this->assertEquals(VirtualPage::make('foo', contents: 'bar'), new VirtualPage('foo', contents: 'bar')); - } - - public function testContentsMethod() - { - $this->assertSame('bar', (new VirtualPage('foo', contents: 'bar'))->contents()); - } - - public function testCompileMethodUsesContentsProperty() - { - $this->assertSame('bar', (new VirtualPage('foo', contents: 'bar'))->compile()); - } } diff --git a/packages/framework/tests/Unit/VirtualPageTest.php b/packages/framework/tests/Unit/VirtualPageTest.php new file mode 100644 index 00000000000..7e4339955f1 --- /dev/null +++ b/packages/framework/tests/Unit/VirtualPageTest.php @@ -0,0 +1,54 @@ +assertInstanceOf(VirtualPage::class, new VirtualPage('foo', contents: 'bar')); + } + + public function testMakeWithContentsString() + { + $this->assertInstanceOf(VirtualPage::class, VirtualPage::make('foo', contents: 'bar')); + $this->assertEquals(VirtualPage::make('foo', contents: 'bar'), new VirtualPage('foo', contents: 'bar')); + } + + public function testContentsMethod() + { + $this->assertSame('bar', (new VirtualPage('foo', contents: 'bar'))->getContents()); + } + + public function testViewMethod() + { + $this->assertSame('bar', (new VirtualPage('foo', view: 'bar'))->getBladeView()); + } + + public function testCompileMethodUsesContentsProperty() + { + $this->assertSame('bar', (new VirtualPage('foo', contents: 'bar'))->compile()); + } + + public function testCompileMethodUsesViewProperty() + { + $this->file('_pages/foo.blade.php', 'bar'); + $this->assertSame('bar', (new VirtualPage('foo', view: 'foo'))->compile()); + } + + public function testCompileMethodPrefersContentsPropertyOverView() + { + $this->file('_pages/foo.blade.php', 'blade'); + $this->assertSame('contents', (new VirtualPage('foo', contents: 'contents', view: 'foo'))->compile()); + } +}