Custom fields
Extend field definitions and write your own field types.
On this page
Extending a field
A field definition, or a view's entry for a field, can extends another field. It keeps that field's type, label and options and replaces whichever keys it sets; a nested fields map is replaced whole, not merged:
// site/views/post/_index.json
{
"fields": {
"summary": { "extends": "description", "label": "Summary" }
}
}
// site/fields/password/_index.json
{
"extends": "@phlat/password",
"options": { "required": true }
}
A name that resolves to nothing, a definition with no type, a type that doesn't exist and a field that extends itself are all errors when the definition is read.
Names from addons
A field or type from an addon carries its owner in the name, the way a view does: @theme/theme is the theme addon's field. A field type is a PHP class in phlat/fieldtypes/{type}/, an addon's fieldtypes/{type}/ or site/fieldtypes/{type}/.
Custom field types
Create site/fieldtypes/{type}/{type}.php, extending the primitive base that matches the JSON shape the type stores: FieldTypeText, FieldTypeNumber, FieldTypeList or FieldTypeObject. Your fields name it bare: "type": "rating".
<?php
namespace Phlat;
class FieldTypeRating extends FieldTypeNumber
{
public function decode(FieldValue $field): mixed
{
// clamp stored value to 0-5
return max(0, min(5, (int) $field->value));
}
public function stars(FieldValue $field): string
{
$rating = (int) $this->decode($field);
return str_repeat('★', $rating) . str_repeat('☆', 5 - $rating);
}
}
site/fieldtypes/
rating/
rating.php ← class FieldTypeRating extends FieldTypeNumber
_index.json ← optional, default search behaviour
edit.latte ← optional, admin field-editing UI
render.latte ← optional, |render output
To control |render output, add render.latte beside the type (site/fieldtypes/{type}/render.latte, or site/fieldtypes/@phlat/{type}/render.latte to override a core type). It receives $field and $value (the decoded value). A render.latte beside a field's own definition, site/fields/{name}/render.latte, takes precedence, and site/views/fields/{view}/{name}.latte wins over both. edit.latte is a separate template for the admin editor.
A type in site/fieldtypes/ is your own and can't share a core type's name. To change a core type's editor templates or defaults, see Overrides; different behaviour is a type of your own.