diff --git a/src/Cms/ModelWithContent.php b/src/Cms/ModelWithContent.php index 090d782d38..e945b81e2d 100644 --- a/src/Cms/ModelWithContent.php +++ b/src/Cms/ModelWithContent.php @@ -129,14 +129,25 @@ abstract protected function commit( */ public function content(string|null $languageCode = null): Content { + // get the targeted language + $language = Language::ensure($languageCode); + + // fetch a specific version in preview render mode + // @todo this entire block can be radically simplified as soon + // as the models use the versions exclusively. + if (VersionId::$render ?? null) { + $version = $this->version(VersionId::$render); + + if ($version->exists($language) === true) { + return $version->content($language); + } + } + // single language support if ($this->kirby()->multilang() === false) { - return $this->content ??= $this->version()->content('default'); + return $this->content ??= $this->version()->content($language); } - // get the targeted language - $language = Language::ensure($languageCode); - // only fetch from cache for the current language if ($languageCode === null && $this->content instanceof Content) { return $this->content; diff --git a/src/Content/VersionId.php b/src/Content/VersionId.php index 62b2c5be47..58a06aaee9 100644 --- a/src/Content/VersionId.php +++ b/src/Content/VersionId.php @@ -32,7 +32,13 @@ class VersionId implements Stringable /** * Latest changes to the content (optional) */ - public const CHANGES = 'changes'; + public const CHANGES = 'changes'; + + /** + * A global store for a version id that should be + * rendered for each model in a live preview scenario. + */ + public static self|null $render = null; /** * @throws \Kirby\Exception\InvalidArgumentException If the version ID is not valid diff --git a/src/Panel/Model.php b/src/Panel/Model.php index 707e2f1a5f..dc6798cc35 100644 --- a/src/Panel/Model.php +++ b/src/Panel/Model.php @@ -37,7 +37,21 @@ abstract public function buttons(): array; */ public function content(): array { - return Form::for($this->model)->values(); + $version = $this->model->version('changes'); + $changes = []; + + if ($version->exists() === true) { + $changes = $version->content()->toArray(); + } + + // create a form which will collect the published values for the model, + // but also pass along unpublished changes as overwrites + return Form::for( + model: $this->model, + props: [ + 'values' => $changes + ] + )->values(); } /** diff --git a/src/Panel/Page.php b/src/Panel/Page.php index 07dd87a497..1f92d007ef 100644 --- a/src/Panel/Page.php +++ b/src/Panel/Page.php @@ -371,13 +371,11 @@ public function props(): array */ public function view(): array { - $page = $this->model; - return [ - 'breadcrumb' => $page->panel()->breadcrumb(), + 'breadcrumb' => $this->model->panel()->breadcrumb(), 'component' => 'k-page-view', 'props' => $this->props(), - 'title' => $page->title()->toString(), + 'title' => $this->model->title()->toString(), ]; } } diff --git a/tests/Cms/Models/ModelWithContentTest.php b/tests/Cms/Models/ModelWithContentTest.php index 8540e4aa04..52dd2668cf 100644 --- a/tests/Cms/Models/ModelWithContentTest.php +++ b/tests/Cms/Models/ModelWithContentTest.php @@ -230,6 +230,39 @@ public function testContentLockWithNoDirectory() $this->assertNull($model->lock()); } + public function testContentWithChanges() + { + $app = new App([ + 'roots' => [ + 'index' => static::TMP + ], + 'site' => [ + 'children' => [ + [ + 'slug' => 'foo', + ] + ], + ] + ]); + + $page = $app->page('foo'); + + $this->assertSame(null, $page->content()->title()->value()); + + // create some changes + $page->version('changes')->save([ + 'title' => 'Test' + ]); + + VersionId::$render = VersionId::changes(); + + $this->assertSame('Test', $page->content()->title()->value()); + + VersionId::$render = null; + + $this->assertSame(null, $page->content()->title()->value()); + } + /** * @dataProvider modelsProvider */