first version
This commit is contained in:
64
kirby/config/fields/checkboxes.php
Executable file
64
kirby/config/fields/checkboxes.php
Executable file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'mixins' => ['options'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Arranges the checkboxes in the given number of columns
|
||||
*/
|
||||
'columns' => function (int $columns = 1) {
|
||||
return $columns;
|
||||
},
|
||||
/**
|
||||
* Default value for the field, which will be used when a Page/File/User is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return Str::split($default, ',');
|
||||
},
|
||||
/**
|
||||
* Maximum number of checked boxes
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Minimum number of checked boxes
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return Str::split($value, ',');
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'options' => function (): array {
|
||||
return $this->getOptions();
|
||||
},
|
||||
'default' => function () {
|
||||
return $this->sanitizeOptions($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->sanitizeOptions($this->value);
|
||||
},
|
||||
],
|
||||
'save' => function ($value): string {
|
||||
return A::join($value, ', ');
|
||||
},
|
||||
'validations' => [
|
||||
'options',
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
76
kirby/config/fields/date.php
Executable file
76
kirby/config/fields/date.php
Executable file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Default date when a new Page/File/User gets created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
/**
|
||||
* Changes the calendar icon to something custom
|
||||
*/
|
||||
'icon' => function (string $icon = "calendar") {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Youngest date, which can be selected/saved
|
||||
*/
|
||||
'max' => function (string $max = null) {
|
||||
return $this->toDate($max);
|
||||
},
|
||||
/**
|
||||
* Oldest date, which can be selected/saved
|
||||
*/
|
||||
'min' => function (string $min = null) {
|
||||
return $this->toDate($min);
|
||||
},
|
||||
/**
|
||||
* The placeholder is not available
|
||||
*/
|
||||
'placeholder' => null,
|
||||
/**
|
||||
* Pass true or an array of time field options to show the time selector.
|
||||
*/
|
||||
'time' => function ($time = false) {
|
||||
return $time;
|
||||
},
|
||||
/**
|
||||
* Must be a parseable date string
|
||||
*/
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toDate($this->default);
|
||||
},
|
||||
'format' => function () {
|
||||
return $this->props['format'] ?? ($this->time() === false ? 'Y-m-d' : 'Y-m-d H:i');
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toDate($this->value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'toDate' => function ($value) {
|
||||
if ($timestamp = timestamp($value, $this->time['step'] ?? 5)) {
|
||||
return date(DATE_W3C, $timestamp);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
],
|
||||
'save' => function ($value) {
|
||||
if ($value !== null && $date = strtotime($value)) {
|
||||
return date($this->format(), $date);
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
'validations' => [
|
||||
'date'
|
||||
]
|
||||
];
|
38
kirby/config/fields/email.php
Executable file
38
kirby/config/fields/email.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete mode for the input
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'email') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the email icon to something custom
|
||||
*/
|
||||
'icon' => function (string $icon = 'email') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom placeholder text, when the field is empty.
|
||||
*/
|
||||
'placeholder' => function ($value = null) {
|
||||
return I18n::translate($value, $value) ?? I18n::translate('email.placeholder');
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'email'
|
||||
]
|
||||
];
|
188
kirby/config/fields/files.php
Executable file
188
kirby/config/fields/files.php
Executable file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'autofocus' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Sets the file(s), which are selected by default when a new page is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* The placeholder text if no pages have been selected yet
|
||||
*/
|
||||
'empty' => function ($empty = null) {
|
||||
return I18n::translate($empty, $empty);
|
||||
},
|
||||
|
||||
/**
|
||||
* Image settings for each item
|
||||
*/
|
||||
'image' => function (array $image = null) {
|
||||
return $image ?? [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Info text
|
||||
*/
|
||||
'info' => function (string $info = null) {
|
||||
return $info;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the layout of the selected files. Available layouts: list, cards
|
||||
*/
|
||||
'layout' => function (string $layout = 'list') {
|
||||
return $layout;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required files
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed files
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
|
||||
/**
|
||||
* If false, only a single file can be selected
|
||||
*/
|
||||
'multiple' => function (bool $multiple = true) {
|
||||
return $multiple;
|
||||
},
|
||||
|
||||
/**
|
||||
* Query for the files to be included
|
||||
*/
|
||||
'query' => function (string $query = 'page.files') {
|
||||
return $query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards
|
||||
*/
|
||||
'size' => function (string $size = null) {
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Main text
|
||||
*/
|
||||
'text' => function (string $text = '{{ file.filename }}') {
|
||||
return $text;
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'parentModel' => function () {
|
||||
if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
return $this->model();
|
||||
},
|
||||
'parent' => function () {
|
||||
return $this->parentModel->apiUrl(true);
|
||||
},
|
||||
'default' => function () {
|
||||
return $this->toFiles($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toFiles($this->value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'fileResponse' => function ($file) {
|
||||
if ($this->layout === 'list') {
|
||||
$thumb = [
|
||||
'width' => 100,
|
||||
'height' => 100
|
||||
];
|
||||
} else {
|
||||
$thumb = [
|
||||
'width' => 400,
|
||||
'height' => 400
|
||||
];
|
||||
}
|
||||
|
||||
$image = $file->panelImage($this->image, $thumb);
|
||||
$model = $this->model();
|
||||
$uuid = $file->parent() === $model ? $file->filename() : $file->id();
|
||||
|
||||
return [
|
||||
'filename' => $file->filename(),
|
||||
'text' => $file->toString($this->text),
|
||||
'link' => $file->panelUrl(true),
|
||||
'id' => $file->id(),
|
||||
'uuid' => $uuid,
|
||||
'url' => $file->url(),
|
||||
'info' => $file->toString($this->info ?? false),
|
||||
'image' => $image,
|
||||
'icon' => $file->panelIcon($image),
|
||||
'type' => $file->type(),
|
||||
];
|
||||
},
|
||||
'toFiles' => function ($value = null) {
|
||||
$files = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Yaml::decode($value) as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) {
|
||||
$files[] = $this->fileResponse($file);
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$files = $field->model()->query($field->query(), 'Kirby\Cms\Files');
|
||||
$data = [];
|
||||
|
||||
foreach ($files as $index => $file) {
|
||||
$data[] = $field->fileResponse($file);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'uuid');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
27
kirby/config/fields/headline.php
Executable file
27
kirby/config/fields/headline.php
Executable file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'save' => false,
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'default' => null,
|
||||
'disabled' => null,
|
||||
'help' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
'required' => null,
|
||||
'translate' => null,
|
||||
|
||||
/**
|
||||
* If false, the prepended number will be hidden
|
||||
*/
|
||||
'numbered' => function (bool $numbered = true) {
|
||||
return $numbered;
|
||||
}
|
||||
]
|
||||
];
|
3
kirby/config/fields/hidden.php
Executable file
3
kirby/config/fields/hidden.php
Executable file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
return [];
|
23
kirby/config/fields/info.php
Executable file
23
kirby/config/fields/info.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
'text' => function ($value = null) {
|
||||
return I18n::translate($value, $value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'text' => function () {
|
||||
$text = $this->text;
|
||||
|
||||
if ($model = $this->model()) {
|
||||
$text = $this->model()->toString($text);
|
||||
}
|
||||
|
||||
return kirbytext($text);
|
||||
}
|
||||
],
|
||||
'save' => false,
|
||||
];
|
5
kirby/config/fields/line.php
Executable file
5
kirby/config/fields/line.php
Executable file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'save' => false
|
||||
];
|
43
kirby/config/fields/mixins/options.php
Executable file
43
kirby/config/fields/mixins/options.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Form\Options;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* API settings for options requests. This will only take affect when <code>options</code> is set to <code>api</code>.
|
||||
*/
|
||||
'api' => function ($api = null) {
|
||||
return $api;
|
||||
},
|
||||
/**
|
||||
* An array with options
|
||||
*/
|
||||
'options' => function ($options = []) {
|
||||
return $options;
|
||||
},
|
||||
/**
|
||||
* Query settings for options queries. This will only take affect when <code>options</code> is set to <code>query</code>.
|
||||
*/
|
||||
'query' => function ($query = null) {
|
||||
return $query;
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'getOptions' => function () {
|
||||
return Options::factory(
|
||||
$this->options(),
|
||||
$this->props,
|
||||
$this->model()
|
||||
);
|
||||
},
|
||||
'sanitizeOption' => function ($option) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return in_array($option, $allowed, true) === true ? $option : null;
|
||||
},
|
||||
'sanitizeOptions' => function ($options) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return array_intersect($options, $allowed);
|
||||
},
|
||||
]
|
||||
];
|
25
kirby/config/fields/multiselect.php
Executable file
25
kirby/config/fields/multiselect.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'tags',
|
||||
'props' => [
|
||||
/**
|
||||
* Custom icon to replace the arrow down.
|
||||
*/
|
||||
'icon' => function (string $icon = null) {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Enable/disable the search in the dropdown
|
||||
*/
|
||||
'search' => function (bool $search = true) {
|
||||
return $search;
|
||||
},
|
||||
/**
|
||||
* If true, entries will be sorted alphabetically on selection
|
||||
*/
|
||||
'sort' => function (bool $sort = false) {
|
||||
return $sort;
|
||||
},
|
||||
]
|
||||
];
|
49
kirby/config/fields/number.php
Executable file
49
kirby/config/fields/number.php
Executable file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Default number that will be saved when a new Page/User/File is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->toNumber($default);
|
||||
},
|
||||
/**
|
||||
* The lowest allowed number
|
||||
*/
|
||||
'min' => function (float $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* The highest allowed number
|
||||
*/
|
||||
'max' => function (float $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Allowed incremental steps between numbers (i.e 0.5)
|
||||
*/
|
||||
'step' => function ($step = 1) {
|
||||
return $this->toNumber($step);
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $this->toNumber($value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toNumber' => function ($value) {
|
||||
if ($this->isEmpty($value) === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$value = str_replace(',', '.', $value);
|
||||
$value = floatval($value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
188
kirby/config/fields/pages.php
Executable file
188
kirby/config/fields/pages.php
Executable file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default selected page(s) when a new Page/File/User is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->toPages($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* The placeholder text if no pages have been selected yet
|
||||
*/
|
||||
'empty' => function ($empty = null) {
|
||||
return I18n::translate($empty, $empty);
|
||||
},
|
||||
|
||||
/**
|
||||
* Image settings for each item
|
||||
*/
|
||||
'image' => function (array $image = null) {
|
||||
return $image ?? [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Info text
|
||||
*/
|
||||
'info' => function (string $info = null) {
|
||||
return $info;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the layout of the selected files. Available layouts: list, cards
|
||||
*/
|
||||
'layout' => function (string $layout = 'list') {
|
||||
return $layout;
|
||||
},
|
||||
|
||||
/**
|
||||
* The minimum number of required selected pages
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
|
||||
/**
|
||||
* The maximum number of allowed selected pages
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
|
||||
/**
|
||||
* If false, only a single page can be selected
|
||||
*/
|
||||
'multiple' => function (bool $multiple = true) {
|
||||
return $multiple;
|
||||
},
|
||||
|
||||
/**
|
||||
* Optional query to select a specific set of pages
|
||||
*/
|
||||
'query' => function (string $query = null) {
|
||||
return $query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards
|
||||
*/
|
||||
'size' => function (string $size = null) {
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Main text
|
||||
*/
|
||||
'text' => function (string $text = null) {
|
||||
return $text;
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $this->toPages($value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'pageResponse' => function ($page) {
|
||||
if ($this->layout === 'list') {
|
||||
$thumb = [
|
||||
'width' => 100,
|
||||
'height' => 100
|
||||
];
|
||||
} else {
|
||||
$thumb = [
|
||||
'width' => 400,
|
||||
'height' => 400
|
||||
];
|
||||
}
|
||||
|
||||
$image = $page->panelImage($this->image, $thumb);
|
||||
$model = $this->model();
|
||||
|
||||
return [
|
||||
'text' => $page->toString($this->text ?? '{{ page.title }}'),
|
||||
'link' => $page->panelUrl(true),
|
||||
'id' => $page->id(),
|
||||
'info' => $page->toString($this->info ?? false),
|
||||
'image' => $image,
|
||||
'icon' => $page->panelIcon($image),
|
||||
'hasChildren' => $page->hasChildren(),
|
||||
];
|
||||
},
|
||||
'toPages' => function ($value = null) {
|
||||
$pages = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Yaml::decode($value) as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if ($id !== null && ($page = $kirby->page($id))) {
|
||||
$pages[] = $this->pageResponse($page);
|
||||
}
|
||||
}
|
||||
|
||||
return $pages;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$query = $field->query();
|
||||
|
||||
if ($query) {
|
||||
$pages = $field->model()->query($query, 'Kirby\Cms\Pages');
|
||||
$model = null;
|
||||
} else {
|
||||
if (!$parent = $this->site()->find($this->requestQuery('parent'))) {
|
||||
$parent = $this->site();
|
||||
}
|
||||
|
||||
$pages = $parent->children();
|
||||
$model = [
|
||||
'id' => $parent->id() == '' ? null : $parent->id(),
|
||||
'title' => $parent->title()->value()
|
||||
];
|
||||
}
|
||||
|
||||
$children = [];
|
||||
|
||||
foreach ($pages as $index => $page) {
|
||||
if ($page->isReadable() === true) {
|
||||
$children[] = $field->pageResponse($page);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'model' => $model,
|
||||
'pages' => $children
|
||||
];
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'id');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
32
kirby/config/fields/radio.php
Executable file
32
kirby/config/fields/radio.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'mixins' => ['options'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Arranges the radio buttons in the given number of columns
|
||||
*/
|
||||
'columns' => function (int $columns = 1) {
|
||||
return $columns;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'options' => function (): array {
|
||||
return $this->getOptions();
|
||||
},
|
||||
'default' => function () {
|
||||
return $this->sanitizeOption($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->sanitizeOption($this->value) ?? '';
|
||||
}
|
||||
]
|
||||
];
|
24
kirby/config/fields/range.php
Executable file
24
kirby/config/fields/range.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'number',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* The maximum value on the slider
|
||||
*/
|
||||
'max' => function (float $max = 100) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Enables/disables the tooltip and set the before and after values
|
||||
*/
|
||||
'tooltip' => function ($tooltip = true) {
|
||||
return $tooltip;
|
||||
},
|
||||
]
|
||||
];
|
18
kirby/config/fields/select.php
Executable file
18
kirby/config/fields/select.php
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'radio',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'columns' => null,
|
||||
|
||||
/**
|
||||
* Custom icon to replace the arrow down.
|
||||
*/
|
||||
'icon' => function (string $icon = null) {
|
||||
return $icon;
|
||||
},
|
||||
]
|
||||
];
|
159
kirby/config/fields/structure.php
Executable file
159
kirby/config/fields/structure.php
Executable file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Form\Form;
|
||||
use Kirby\Cms\Blueprint;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'autofocus' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Optional columns definition to only show selected fields in the structure table.
|
||||
*/
|
||||
'columns' => function (array $columns = []) {
|
||||
// lower case all keys, because field names will
|
||||
// be lowercase as well.
|
||||
return array_change_key_case($columns);
|
||||
},
|
||||
/**
|
||||
* Fields setup for the structure form. Works just like fields in regular forms.
|
||||
*/
|
||||
'fields' => function (array $fields) {
|
||||
return $fields;
|
||||
},
|
||||
/**
|
||||
* The number of entries that will be displayed on a single page. Afterwards pagination kicks in.
|
||||
*/
|
||||
'limit' => function (int $limit = null) {
|
||||
return $limit;
|
||||
},
|
||||
/**
|
||||
* Maximum allowed entries in the structure. Afterwards the "Add" button will be switched off.
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Minimum required entries in the structure
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* Toggles drag & drop sorting
|
||||
*/
|
||||
'sortable' => function (bool $sortable = null) {
|
||||
return $sortable;
|
||||
},
|
||||
/**
|
||||
* Sorts the entries by the given field and order (i.e. title desc)
|
||||
* Drag & drop is disabled in this case
|
||||
*/
|
||||
'sortBy' => function (string $sort = null) {
|
||||
return $sort;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->rows($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->rows($this->value);
|
||||
},
|
||||
'fields' => function () {
|
||||
return $this->form()->fields()->toArray();
|
||||
},
|
||||
'columns' => function () {
|
||||
$columns = [];
|
||||
|
||||
if (empty($this->columns)) {
|
||||
foreach ($this->fields as $field) {
|
||||
|
||||
// Skip hidden fields.
|
||||
// They should never be included as column
|
||||
if ($field['type'] === 'hidden') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns[$field['name']] = [
|
||||
'type' => $field['type'],
|
||||
'label' => $field['label'] ?? $field['name']
|
||||
];
|
||||
}
|
||||
} else {
|
||||
foreach ($this->columns as $columnName => $columnProps) {
|
||||
if (is_array($columnProps) === false) {
|
||||
$columnProps = [];
|
||||
}
|
||||
|
||||
$field = $this->fields[$columnName] ?? null;
|
||||
|
||||
if (empty($field) === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns[$columnName] = array_merge($columnProps, [
|
||||
'type' => $field['type'],
|
||||
'label' => $field['label'] ?? $field['name']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $columns;
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'rows' => function ($value) {
|
||||
$rows = Yaml::decode($value);
|
||||
$value = [];
|
||||
|
||||
foreach ($rows as $index => $row) {
|
||||
if (is_array($row) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value[] = $this->form($row)->values();
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
'form' => function (array $values = []) {
|
||||
return new Form([
|
||||
'fields' => $this->attrs['fields'],
|
||||
'values' => $values,
|
||||
'model' => $this->model
|
||||
]);
|
||||
},
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => 'validate',
|
||||
'method' => 'ALL',
|
||||
'action' => function () {
|
||||
return array_values($this->field()->form($this->requestBody())->errors());
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function () {
|
||||
$data = [];
|
||||
|
||||
foreach ($this->value() as $row) {
|
||||
$data[] = $this->form($row)->data();
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
91
kirby/config/fields/tags.php
Executable file
91
kirby/config/fields/tags.php
Executable file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'mixins' => ['options'],
|
||||
'props' => [
|
||||
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* If set to <code>all</code>, any type of input is accepted. If set to <code>options</code> only the predefined options are accepted as input.
|
||||
*/
|
||||
'accept' => function ($value = 'all') {
|
||||
return V::in($value, ['all', 'options']) ? $value : 'all';
|
||||
},
|
||||
/**
|
||||
* Changes the tag icon
|
||||
*/
|
||||
'icon' => function ($icon = 'tag') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Minimum number of required entries/tags
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* Maximum number of allowed entries/tags
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Custom tags separator, which will be used to store tags in the content file
|
||||
*/
|
||||
'separator' => function (string $separator = ',') {
|
||||
return $separator;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'options' => function () {
|
||||
return $this->getOptions();
|
||||
},
|
||||
'default' => function (): array {
|
||||
return $this->toTags($this->default);
|
||||
},
|
||||
'value' => function (): array {
|
||||
return $this->toTags($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toTags' => function ($value) {
|
||||
$options = $this->options();
|
||||
|
||||
// transform into value-text objects
|
||||
return array_map(function ($option) use ($options) {
|
||||
|
||||
// already a valid object
|
||||
if (is_array($option) === true && isset($option['value'], $option['text']) === true) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$index = array_search($option, array_column($options, 'value'));
|
||||
|
||||
if ($index !== false) {
|
||||
return $options[$index];
|
||||
}
|
||||
|
||||
return [
|
||||
'value' => $option,
|
||||
'text' => $option,
|
||||
];
|
||||
}, Str::split($value));
|
||||
}
|
||||
],
|
||||
'save' => function (array $value = null): string {
|
||||
return A::join(
|
||||
A::pluck($value, 'value'),
|
||||
$this->separator() . ' '
|
||||
);
|
||||
},
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
27
kirby/config/fields/tel.php
Executable file
27
kirby/config/fields/tel.php
Executable file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
'spellcheck' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete attribute
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'tel') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the phone icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'phone') {
|
||||
return $icon;
|
||||
}
|
||||
]
|
||||
];
|
103
kirby/config/fields/text.php
Executable file
103
kirby/config/fields/text.php
Executable file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
|
||||
/**
|
||||
* The field value will be converted with the selected converter before the value gets saved. Available converters: lower, upper, ucfirst, slug
|
||||
*/
|
||||
'converter' => function ($value = null) {
|
||||
if ($value !== null && in_array($value, array_keys($this->converters())) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'field.converter.invalid',
|
||||
'data' => ['converter' => $value]
|
||||
]);
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows or hides the character counter in the top right corner
|
||||
*/
|
||||
'counter' => function (bool $counter = true) {
|
||||
return $counter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
'maxlength' => function (int $maxlength = null) {
|
||||
return $maxlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required characters
|
||||
*/
|
||||
'minlength' => function (int $minlength = null) {
|
||||
return $minlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* A regular expression, which will be used to validate the input
|
||||
*/
|
||||
'pattern' => function (string $pattern = null) {
|
||||
return $pattern;
|
||||
},
|
||||
|
||||
/**
|
||||
* If false, spellcheck will be switched off
|
||||
*/
|
||||
'spellcheck' => function (bool $spellcheck = false) {
|
||||
return $spellcheck;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->convert($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return (string)$this->convert($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'convert' => function ($value) {
|
||||
if ($this->converter() === null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
$converter = $this->converters()[$this->converter()];
|
||||
|
||||
if (is_array($value) === true) {
|
||||
return array_map($converter, $value);
|
||||
}
|
||||
|
||||
return call_user_func($converter, $value);
|
||||
},
|
||||
'converters' => function (): array {
|
||||
return [
|
||||
'lower' => function ($value) {
|
||||
return Str::lower($value);
|
||||
},
|
||||
'slug' => function ($value) {
|
||||
return Str::slug($value);
|
||||
},
|
||||
'ucfirst' => function ($value) {
|
||||
return Str::ucfirst($value);
|
||||
},
|
||||
'upper' => function ($value) {
|
||||
return Str::upper($value);
|
||||
},
|
||||
];
|
||||
},
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength'
|
||||
]
|
||||
];
|
61
kirby/config/fields/textarea.php
Executable file
61
kirby/config/fields/textarea.php
Executable file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
|
||||
/**
|
||||
* Enables/disables the format buttons. Can either be true/false or a list of allowed buttons. Available buttons: headlines, italic, bold, link, email, list, code, ul, ol
|
||||
*/
|
||||
'buttons' => function ($buttons = true) {
|
||||
return $buttons;
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables/disables the character counter in the top right corner
|
||||
*/
|
||||
'counter' => function (bool $counter = true) {
|
||||
return $counter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the default text when a new Page/File/User is created
|
||||
*/
|
||||
'default' => function (string $default = null) {
|
||||
return trim($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
'maxlength' => function (int $maxlength = null) {
|
||||
return $maxlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required characters
|
||||
*/
|
||||
'minlength' => function (int $minlength = null) {
|
||||
return $minlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the size of the textarea. Available sizes: small, medium, large, huge
|
||||
*/
|
||||
'size' => function (string $size = null) {
|
||||
return $size;
|
||||
},
|
||||
|
||||
'value' => function (string $value = null) {
|
||||
return trim($value);
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength'
|
||||
]
|
||||
];
|
68
kirby/config/fields/time.php
Executable file
68
kirby/config/fields/time.php
Executable file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Sets the default time when a new Page/File/User is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
/**
|
||||
* Changes the clock icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'clock') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* 12 or 24 hour notation. If 12, an AM/PM selector will be shown.
|
||||
*/
|
||||
'notation' => function (int $value = 24) {
|
||||
return $value === 24 ? 24 : 12;
|
||||
},
|
||||
/**
|
||||
* The interval between minutes in the minutes select dropdown.
|
||||
*/
|
||||
'step' => function (int $step = 5) {
|
||||
return $step;
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toTime($this->default);
|
||||
},
|
||||
'format' => function () {
|
||||
return $this->notation === 24 ? 'H:i' : 'h:i a';
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toTime($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toTime' => function ($value) {
|
||||
if ($timestamp = timestamp($value, $this->step)) {
|
||||
return date('H:i', $timestamp);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
],
|
||||
'save' => function ($value): string {
|
||||
if ($timestamp = strtotime($value)) {
|
||||
return date($this->format, $timestamp);
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
'validations' => [
|
||||
'time',
|
||||
]
|
||||
];
|
64
kirby/config/fields/toggle.php
Executable file
64
kirby/config/fields/toggle.php
Executable file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default value which will be saved when a new Page/User/File is created
|
||||
*/
|
||||
'default' => function ($value = null) {
|
||||
return $this->toBool($value);
|
||||
},
|
||||
/**
|
||||
* Sets the text next to the toggle. The text can be a string or an array of two options. The first one is the negative text and the second one the positive. The text will automatically switch when the toggle is triggered.
|
||||
*/
|
||||
'text' => function ($value = null) {
|
||||
if (is_array($value) === true) {
|
||||
if (A::isAssociative($value) === true) {
|
||||
return I18n::translate($value, $value);
|
||||
}
|
||||
|
||||
foreach ($value as $key => $val) {
|
||||
$value[$key] = I18n::translate($val, $val);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
return I18n::translate($value, $value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'value' => function () {
|
||||
if ($this->props['value'] === null) {
|
||||
return $this->default();
|
||||
} else {
|
||||
return $this->toBool($this->props['value']);
|
||||
}
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toBool' => function ($value) {
|
||||
return in_array($value, [true, 'true', 1, '1', 'on'], true) === true;
|
||||
}
|
||||
],
|
||||
'save' => function (): string {
|
||||
return $this->value() === true ? 'true' : 'false';
|
||||
},
|
||||
'validations' => [
|
||||
'boolean',
|
||||
'required' => function ($value) {
|
||||
if ($this->isRequired() && ($value === false || $this->isEmpty($value))) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'form.field.required'
|
||||
]);
|
||||
}
|
||||
},
|
||||
]
|
||||
];
|
39
kirby/config/fields/url.php
Executable file
39
kirby/config/fields/url.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
'spellcheck' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete attribute
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'url') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the link icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'url') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets custom placeholder text, when the field is empty
|
||||
*/
|
||||
'placeholder' => function ($value = null) {
|
||||
return I18n::translate($value, $value) ?? 'https://example.com';
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'url'
|
||||
],
|
||||
];
|
95
kirby/config/fields/users.php
Executable file
95
kirby/config/fields/users.php
Executable file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default selected user(s) when a new Page/File/User is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
if ($default === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($default === null && $user = $this->kirby()->user()) {
|
||||
return [
|
||||
$this->userResponse($user)
|
||||
];
|
||||
}
|
||||
|
||||
return $this->toUsers($default);
|
||||
},
|
||||
/**
|
||||
* The minimum number of required selected users
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* The maximum number of allowed selected users
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* If false, only a single user can be selected
|
||||
*/
|
||||
'multiple' => function (bool $multiple = true) {
|
||||
return $multiple;
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $this->toUsers($value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'userResponse' => function ($user) {
|
||||
$avatar = function ($user) {
|
||||
if ($avatar = $user->avatar()) {
|
||||
return [
|
||||
'url' => $avatar->crop(512)->url()
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
return [
|
||||
'username' => $user->username(),
|
||||
'id' => $user->id(),
|
||||
'email' => $user->email(),
|
||||
'avatar' => $avatar($user)
|
||||
];
|
||||
},
|
||||
'toUsers' => function ($value = null) {
|
||||
$users = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Yaml::decode($value) as $email) {
|
||||
if (is_array($email) === true) {
|
||||
$email = $email['email'] ?? null;
|
||||
}
|
||||
|
||||
if ($email !== null && ($user = $kirby->user($email))) {
|
||||
$users[] = $this->userResponse($user);
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
],
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'email');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
Reference in New Issue
Block a user