Skip to content

Commit 11a5320

Browse files
committed
refact: Page create dialog as section dialog
1 parent 88f5132 commit 11a5320

File tree

6 files changed

+357
-228
lines changed

6 files changed

+357
-228
lines changed

config/areas/site/dialogs.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
'pattern' => 'pages/(:any)/changeTitle',
3535
'action' => PageChangeTitleDialogController::class
3636
],
37+
/**
38+
* @deprecated 6.0.0 Use section dialog route instead
39+
*/
3740
'page.create' => [
3841
'pattern' => 'pages/create',
3942
'action' => PageCreateDialogController::class

config/sections/pages.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Kirby\Cms\Site;
77
use Kirby\Exception\InvalidArgumentException;
88
use Kirby\Panel\Collector\PagesCollector;
9+
use Kirby\Panel\Controller\Dialog\PageCreateDialogController;
910
use Kirby\Panel\Ui\Item\PageItem;
1011
use Kirby\Toolkit\A;
1112
use Kirby\Toolkit\I18n;
@@ -262,6 +263,16 @@
262263
]
263264
];
264265
},
266+
'dialogs' => function () {
267+
return [
268+
'create' => [
269+
'action' => fn () => new PageCreateDialogController(
270+
parent: $this->parentModel(),
271+
section: $this
272+
),
273+
]
274+
];
275+
},
265276
// @codeCoverageIgnoreEnd
266277
'toArray' => function () {
267278
return [

panel/src/components/Sections/PagesSection.vue

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,12 @@ export default {
6363
methods: {
6464
onAdd() {
6565
if (this.canAdd) {
66-
this.$dialog("pages/create", {
67-
query: {
68-
parent: this.options.link ?? this.parent,
69-
view: this.parent,
70-
section: this.name
71-
}
72-
});
66+
this.$panel.dialog.open(
67+
(this.options.link ?? this.parent) +
68+
"/sections/" +
69+
this.name +
70+
"/create"
71+
);
7372
}
7473
},
7574
async onChange(event) {
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
namespace Kirby\Panel\Controller\Dialog;
4+
5+
use Kirby\Cms\Blueprint;
6+
use Kirby\Cms\ModelWithContent;
7+
use Kirby\Cms\Page;
8+
use Kirby\Cms\Section;
9+
use Kirby\Cms\Site;
10+
use Kirby\Cms\User;
11+
use Kirby\Exception\InvalidArgumentException;
12+
use Kirby\Form\Form;
13+
use Kirby\Panel\Controller\DialogController;
14+
15+
/**
16+
* Controls a Panel dialog to create a new model
17+
*
18+
* @package Kirby Panel
19+
* @author Bastian Allgeier <[email protected]>
20+
* @link https://getkirby.com
21+
* @copyright Bastian Allgeier
22+
* @license https://getkirby.com/license
23+
* @since 6.0.0
24+
*/
25+
abstract class ModelCreateDialogController extends DialogController
26+
{
27+
public static array $fieldTypes = [];
28+
29+
protected Blueprint $blueprint;
30+
public ModelWithContent $model;
31+
public Page|Site|User $parent;
32+
33+
public function __construct(
34+
Page|Site|User|null $parent = null,
35+
public Section|null $section = null
36+
) {
37+
parent::__construct();
38+
39+
$this->parent = $parent ?? $this->site;
40+
}
41+
42+
/**
43+
* Get the blueprint for the new page
44+
*/
45+
public function blueprint(): Blueprint
46+
{
47+
return $this->blueprint ??= $this->model()->blueprint();
48+
}
49+
50+
/**
51+
* All the default fields for the dialog
52+
*/
53+
abstract public function coreFields(): array;
54+
55+
/**
56+
* Loads custom fields for the page type
57+
*/
58+
public function customFields(): array
59+
{
60+
$custom = [];
61+
$fields = $this->blueprint()->fields();
62+
$ignore = $this->customFieldsIgnore();
63+
64+
foreach ($this->blueprint()->create()['fields'] ?? [] as $name) {
65+
$field = $fields[$name] ?? null;
66+
67+
if ($field === null) {
68+
throw new InvalidArgumentException(
69+
message: 'Unknown field "' . $name . '" in create dialog'
70+
);
71+
}
72+
73+
if (in_array($field['type'], static::$fieldTypes, true) === false) {
74+
throw new InvalidArgumentException(
75+
message: 'Field type "' . $field['type'] . '" not supported in create dialog'
76+
);
77+
}
78+
79+
if (in_array($name, $ignore, true) === true) {
80+
throw new InvalidArgumentException(
81+
message: 'Field name "' . $name . '" not allowed as custom field in create dialog'
82+
);
83+
}
84+
85+
// switch all fields to 1/1
86+
$field['width'] = '1/1';
87+
88+
// add the field to the form
89+
$custom[$name] = $field;
90+
}
91+
92+
// create form so that field props, options etc.
93+
// can be properly resolved
94+
$form = new Form(
95+
fields: $custom,
96+
model: $this->model()
97+
);
98+
99+
return $form->fields()->toProps();
100+
}
101+
102+
protected function customFieldsIgnore(): array
103+
{
104+
return array_keys($this->coreFields());
105+
}
106+
107+
/**
108+
* Loads all the fields for the dialog
109+
*/
110+
public function fields(): array
111+
{
112+
return [
113+
...$this->coreFields(),
114+
...$this->customFields()
115+
];
116+
}
117+
118+
/**
119+
* Temporary model to be created,
120+
* used to properly render the blueprint for fields
121+
*/
122+
abstract public function model(): ModelWithContent;
123+
124+
/**
125+
* Generates values for title and slug
126+
* from template strings from the blueprint
127+
*/
128+
public function resolveFieldTemplates(array $input, array $fields): array
129+
{
130+
// create temporary page object to resolve the template strings
131+
$page = $this->model()->clone(['content' => $input]);
132+
133+
foreach ($fields as $field) {
134+
$template = $this->blueprint()->create()[$field] ?? null;
135+
136+
if (is_string($template) === true) {
137+
$input[$field] = $page->toSafeString($template);
138+
}
139+
}
140+
141+
return $input;
142+
}
143+
144+
public function value(): array
145+
{
146+
$value = [];
147+
148+
// add default values for custom fields
149+
foreach ($this->customFields() as $name => $field) {
150+
if ($default = $field['default'] ?? null) {
151+
$value[$name] = $default;
152+
}
153+
}
154+
155+
return $value;
156+
}
157+
}

0 commit comments

Comments
 (0)