fields

object

%field

/phlo/resources/fields/field.phlo

Base ORM field

Every field type extends this one and is made with field(type: 'x'), which resolves to the resource field_x; anything else you pass becomes a property, so title, required, length, pattern and enum need no declaration. Override input() for the form and label() for the list, and let objColumns name the columns the field owns, so a field that stores nothing returns an empty array.

fieldorm
function

function field ($type, ...$args):field

line 11
Creates a field with a specified type and additional arguments, using the phlo function to generate a unique identifier for the field.
phlo("field_$type", ...$args, type: $type)
static

field :: __handle

line 13
This property is used to access the internal handle of a field object in Phlo.
null
prop

%field -> title:string

line 15
This expression retrieves the 'name' property of the current object, capitalizing the first letter.
ucfirst($this->name)
method

%field -> input ($record):string

line 17
Generates an input field based on the specified type, name, and value from the provided record, with optional attributes for maxlength and placeholder.
input(type: $this->type, name: $this->name, value: $record->{$this->name} ?? $this->default, maxlength: $this->length, placeholder: $this->placeholder, class: 'field')
method

%field -> label ($record)

line 18
Retrieves the label of a field from the specified record using the field's name.
$record->{$this->name};
prop

%field -> objColumns:array

line 20
This property retrieves the columns of the specified obj in the context of a field.
[]
method

%field -> objValidate ($value):?string

line 22
Validates the given value against specified rules such as required, length, pattern, and enumeration constraints, returning error messages if validation fails.
if (($value === null || $value === void) && $this->required) return $this->title.' is required'
if ($value === null || $value === void) return null
if ($this->length && is_string($value) && mb_strlen($value) > $this->length) return $this->title.' is too long (max '.$this->length.')'
if ($this->pattern && is_string($value) && !preg_match('/'.str_replace('/', '\\/', $this->pattern).'/', $value)) return $this->title.' has invalid format'
if ($this->enum && !in_array($value, (array)$this->enum, true)) return $this->title.' must be one of: '.implode(', ', (array)$this->enum)
return null
object

%field_bool

/phlo/resources/fields/bool.phlo

Boolean field

Stores 1 or 0 and never null, so a checkbox that is left alone still saves a value. Set true and false to change the two symbols a list shows.

fieldbooleaninput
prop

%field_bool -> true

line 12
Represents a boolean field with a true value, displayed as a checkmark symbol '✅'.
'✅'
prop

%field_bool -> false

line 13
Represents a boolean field with a default value of false, displayed as '❌'.
'❌'
method

%field_bool -> label ($record):string

line 15
Returns the label corresponding to a boolean field in the given record, returning either the true label or the false label based on the field's value.
$record->{$this->name} ? $this->true : $this->false
method

%field_bool -> input ($record):string

line 16
Generates a checkbox input field for a boolean value, with a label and a slider for visual enhancement, based on the provided record's value.
tag('label', inner: input(type: 'checkbox', name: $this->name, value: 1, checked: $record->{$this->name} ? true : null).tag('span', class: 'slider', inner: void))
method

%field_bool -> parse ($record):int

line 17
$record->{$this->name} = %payload->{$this->name} ? 1 : 0
method

%field_bool -> nullable:bool

line 18
This function converts a boolean field to a nullable type, allowing it to represent true, false, or null values.
false
prop

%field_bool -> objColumns:array

line 20
Accesses the column associated with the boolean field in the object context.
[$this->name]
object

%field_child

/phlo/resources/fields/child.phlo

Child relation field

The mirror of a parent field elsewhere: it reads the records that point back at this one and owns no column itself. It cannot be edited here, only followed, so change a child from its own record. Set key when the foreign key is not named after the parent model.

fieldrelationchild
prop

%field_child -> list

line 12
Accesses the 'count' property of the field_child object within the list.
'count'
prop

%field_child -> change

line 13
The field_child->$change property indicates whether the child field has undergone any changes, with a boolean value of false meaning no changes have occurred.
false
prop

%field_child -> create

line 14
This expression evaluates to false, indicating that the field_child property does not support the create operation.
false
prop

%field_child -> record

line 15
Accesses the child record of the current field in a list.
'list'
method

%field_child -> count ($record):string

line 17
Counts the number of child records associated with a given record and returns the count.
tag('a', href: slash.($record::$uriRecord ?? $record::class).slash.$record->{$record::idColumn()}.slash.$this->name, class: 'async', inner: $record->getCount($this->name).space.$this->title)
method

%field_child -> last ($record)

line 18
Retrieves the last value of the specified field from the given record.
$record->getLast($this->name)
method

%field_child -> label ($record):string

line 19
Retrieves the label for a child field from a given record, returning a dash if no label is found.
implode(loop($record->{$this->name}, fn($child) => $this->link($child))) ?: dash
method

%field_child -> input ($record):string

line 20
Generates an input field associated with a specific record, utilizing the label method to display the corresponding label.
$this->label($record)
method
line 21
Generates a link to a specific record using its URI and ID, creating an anchor tag with the class 'async'.
tag('a', href: slash.($record::$uriRecord ?? $record::class).slash.$record->{$record::idColumn()}, class: 'async', inner: $record)
method

%field_child -> objKey ($parentModel):string

line 23
Returns the value of the key property if it exists; otherwise, it returns the $parentModel.
$this->key ?? $parentModel
method

%field_child -> objOwns ($record, $parentId, $parentModel):bool

line 25
Does $record belong to parent $parentId via this relation? (direct foreign key).
$value = $record->{$this->objKey($parentModel)};
is_object($value) && $value = $value->{$value::idColumn()};
return (string)$value === (string)$parentId
object

%field_date

/phlo/resources/fields/date.phlo

Date field

Renders in the reader's language through IntlDateFormatter, so a Dutch visitor sees a Dutch date without any work. Without the intl extension it falls back to a built-in Dutch and English month list, so any other language reads as English there. Set format to a date() pattern when the notation has to be fixed rather than local.

fielddate
prop

%field_date -> handle

line 12
This expression retrieves the handle associated with the field_date object, returning true if it exists.
true
prop

%field_date -> format

line 13
Formats a date field according to the specified format string.
null
prop

%field_date -> months:array

line 14
This item provides an associative array mapping month numbers to their corresponding names in English and Dutch.
[
	'nl' => [1 => 'januari', 2 => 'februari', 3 => 'maart', 4 => 'april', 5 => 'mei', 6 => 'juni', 7 => 'juli', 8 => 'augustus', 9 => 'september', 10 => 'oktober', 11 => 'november', 12 => 'december'],
	'en' => [1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December'],
]
method

%field_date -> label ($record):string

line 19
Formats a date label from a given record, returning a formatted string based on the specified format or defaulting to a locale-aware representation.
$v = $record->{$this->name};
if ($v === null || $v === void) return dash
$ts = is_numeric($v) ? (int)$v : strtotime($v)
if (!$ts) return esc($v)
if ($this->format) return date($this->format, $ts)
$lang = substr((string)(%app->lang ?? 'en'), 0, 2)
if (class_exists('IntlDateFormatter')) return (new \IntlDateFormatter($lang, \IntlDateFormatter::LONG, \IntlDateFormatter::NONE))->format($ts)
return date('j', $ts).space.(($this->months[$lang] ?? $this->months['en'])[(int)date('n', $ts)]).space.date('Y', $ts)
prop

%field_date -> objColumns:array

line 30
Accesses the date field of the specified object columns using the name property.
[$this->name]
object

%field_datetime

/phlo/resources/fields/datetime.phlo

Date-time field

Stores a unix timestamp rather than a formatted string, and shows an age icon that runs blue under an hour, yellow under a day and red beyond. Fields called created and changed are kept out of the form because the model writes those itself.

fielddatetime
prop

%field_datetime -> handle

line 12
The field_datetime->$handle expression is used to access the handle of a datetime field in Phlo.
true
prop

%field_datetime -> change

line 13
This item checks if the field name is not 'created' or 'changed' before allowing a change to the datetime field.
!in_array($this->name, ['created', 'changed'])
prop

%field_datetime -> create

line 14
Checks if the field name is not 'created' or 'changed'.
!in_array($this->name, ['created', 'changed'])
method

%field_datetime -> label ($record):string

line 16
Generates a label for a datetime field in a record, displaying an icon and a human-readable time format if a value exists.
($value = $record->{$this->name}) ? tag('i', class: 'icon clock-'.$this->labelIconClass(time() - $value), inner: void).tag('span', data_ts: $record->{$this->name}, inner: time_human($record->{$this->name})) : dash
method

%field_datetime -> labelIconClass ($value):string

line 17
Returns a color class based on the value of time in seconds, categorizing it as 'red' for more than a day, 'yellow' for more than an hour, and 'blue' for less.
$value > 86400 ? 'red' : ($value > 3600 ? 'yellow' : 'blue')
method

%field_datetime -> input ($record):string

line 18
Generates an input field of type 'datetime-local' for a specified record property, allowing users to select a date and time.
input(type: 'datetime-local', name: $this->name, value: $record->{$this->name} ? date('Y-m-d\TH:i', $record->{$this->name}) : void, class: 'field')
method

%field_datetime -> parse ($record):void

line 19
Parses a datetime field from a record, setting 'created' to the current time if it is not already set, updating 'changed' to the current time, or converting a payload value to a timestamp if it exists.
if ($this->name === 'created') $record->created ??= time()
elseif ($this->name === 'changed') $record->{$this->name} = time()
elseif ($payload = %payload->{$this->name}) $record->{$this->name} = strtotime($payload)
prop

%field_datetime -> objColumns:array

line 25
Accesses the column associated with the field_datetime object, returning its name.
[$this->name]
object

%field_email

/phlo/resources/fields/email.phlo

Email field

Only changes how a stored address is shown, as a mailto link. It validates nothing, so add pattern or required when the address has to be real.

fieldemail
view

%field_email -> label ($record)

line 13
This view generates a mailto link for an email address stored in the record, allowing users to click and send an email directly.
<a href="mailto:{{ $record->{$this->name} }}">{{ $record->{$this->name} }}</a>
object

%field_file

/phlo/resources/fields/file.phlo

File field

An upload is stored under a random token instead of its own name, so two people can send the same filename and no visitor can guess a neighbouring URL. That takes two columns, name and name_token, which objColumns already claims. Set accept to narrow the picker, and path and uri when the files live somewhere other than the default. On disk the extension is lowercase whatever the upload said, so a route that lowercases it as well finds FOTO.JPG under token.jpg.

fieldfileupload
prop

%field_file -> canDelete

line 12
The `field_file->$canDelete` property indicates whether the file can be deleted.
true
prop

%field_file -> delete

line 13
Prompts the user for confirmation before deleting a file.
'Delete file?'
prop

%field_file -> path

line 14
The `field_file->$path` retrieves the file path associated with a specific file field in the context of a resource.
files
prop

%field_file -> uri

line 15
This property returns the URI for a file stored in the '/files/' directory.
'/files/'
prop

%field_file -> length

line 16
The `$length` property of `field_file` returns the size of the file in bytes.
100
prop

%field_file -> accept

line 17
Defines the accepted file types for a file input field in a form.
null
method

%field_file -> label ($record):string

line 19
($filename = $record->{$this->name}) ? tag('a', href: $this->uri.$record->{$this->name.'_token'}.slash.rawurlencode($filename), target: 'file', inner: tag('i', class: 'icon '.$this->ext($filename), inner: void).esc($filename)) : dash
method

%field_file -> input ($record):string

line 20
$input = void
$file = ($filename = $record->{$this->name}) ? $this->read($record) : null
$input .= lf.tab.tag('div', class: 'file', inner: $file ? tag('i', class: 'icon '.$this->ext($filename), inner: void).esc($filename) : '-select-')
$input .= lf.tab.input(type: 'file', class: 'file-input', name: $this->name, accept: $this->accept)
$file && $this->canDelete && $input .= lf.tab.tag('div', inner: tag('label', inner: input(type: 'checkbox', name: $this->name.'Delete')." $this->delete"))
return $input.lf
method

%field_file -> parse ($record):void

line 29
Parses a file from the payload, handling deletion and writing the file if valid, and updates the record with the file's shortened name and token.
$file = %payload->{$this->name};
if ($delete = %payload->{$this->name.'Delete'}) unset(%payload->{$this->name.'Delete'})
if ($record->{$this->name} && $delete && $this->canDelete) $record->{$this->name} = $record->{$this->name.'_token'} = null
if (is_a($file, 'file')){
	$token = $file->token
	if (!$this->write($file)) return
	$record->{$this->name} = $file->shortenTo($this->length)
	$record->{$this->name.'_token'} = $token
}
method

%field_file -> read ($record, $path = null):file

line 41
$filename = $record->{$this->name};
$token = $record->{$this->name.'_token'};
return %file(($path ?? $this->path).($info = substr($token, 0, 2).slash.substr($token, 2).dot.$this->ext($filename)), name: $filename, info: $info)
method

%field_file -> write ($file)

line 47
Writes the specified file to the designated path, moving it if necessary, and triggers an error if the write operation fails.
file_exists($dest = $this->writePath($file)) || $file->move($dest) || error("Couldn't write: $dest")
method

%field_file -> writePath ($file, $path = null):string

line 48
$token = $file->token
$path = ($path ?? $this->path).substr($token, 0, 2)
is_dir($path) || mkdir($path) || error("Couldn't create: $path")
return $path.slash.substr($token, 2).dot.$this->ext($file->name)
method

%field_file -> ext (string $filename):string

line 55
strtolower(pathinfo($filename, PATHINFO_EXTENSION))
prop

%field_file -> objColumns:array

line 57
This property retrieves an array containing the name of the field and its associated token for the specified object columns.
[$this->name, $this->name.'_token']
view

script

line 59
This script handles file input interactions by triggering a click on the file input when the associated label is clicked and updating the label text with the selected file name upon file selection.
on('click', '.input.file .file', file => file.nextElementSibling.click())
on('change', '.input.file .file-input', input => input.previousElementSibling.innerText = input.files[0].name)
object

%field_image

/phlo/resources/fields/image.phlo

Image field

A file field that also writes a thumbnail, and the browser scales the picture down before it is sent, so a phone photo does not travel at full size. thumbSize is the thumbnail edge in pixels; a list shows the thumbnail and a record shows the full image.

fieldimageupload
prop

%field_image -> delete

line 12
Prompts the user with a confirmation message asking if they want to delete the image.
'Delete image?'
prop

%field_image -> uri

line 13
This expression retrieves the URI of an image field by appending the base path '/images/' to the field's value.
'/images/'
prop

%field_image -> path

line 14
The `field_image->$path` accesses the path of the image stored in the `field_image` resource.
images
prop

%field_image -> thumbPath

line 15
The `thumbPath` field in the `field_image` object retrieves the path to the thumbnail image stored in the `thumbs` resource.
thumbs
prop

%field_image -> thumbSize

line 16
The `field_image->$thumbSize` property defines the size of the thumbnail image for a given field in Phlo.
64
prop

%field_image -> thumbUri

line 17
This prop generates a thumbnail URI by appending '/thumbs/' to the field_image value.
'/thumbs/'
prop

%field_image -> placeholder

line 18
Returns a base64-encoded SVG placeholder image for use in views.
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM4ODgiIHN0cm9rZS13aWR0aD0iMS40Ij48cmVjdCB4PSIzIiB5PSIzIiB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHJ4PSIyIi8+PGNpcmNsZSBjeD0iOC41IiBjeT0iOC41IiByPSIxLjYiLz48cGF0aCBkPSJNMjEgMTVsLTUtNUw1IDIxIi8+PC9zdmc+'
prop

%field_image -> record

line 20
Accesses the 'preview' field of the current record in a field_image context.
'preview'
method

%field_image -> label ($record):string

line 22
Generates an HTML anchor tag containing an image, linking to a specified URI based on the provided record data. If the record does not contain a filename, it returns a dash instead.
($filename = $record->{$this->name}) ? tag('a', href: $this->uri.($url = $record->{$this->name.'_token'}.slash.rawurlencode($filename)), target: 'image', inner: tag('img', src: $this->thumbUri.$url)) : dash
method

%field_image -> preview ($record):string

line 23
Generates a preview image link for a specified record, using the filename and token from the record to construct the URL.
($filename = $record->{$this->name}) ? tag('a', href: $this->uri.($url = $record->{$this->name.'_token'}.slash.rawurlencode($filename)), target: 'image', inner: tag('img', src: $this->uri.$url, class: 'preview')) : dash
method

%field_image -> input ($record):string

line 24
Generates an HTML input element for uploading an image, along with a preview of the current image if available, and an optional checkbox for deleting the image.
$input = void
$file = $record->{$this->name} ? $this->read($record, $this->thumbPath) : null
$input .= lf.tab.tag('img', src: $file ? $this->thumbUri.$record->{$this->name.'_token'}.slash.rawurlencode($record->{$this->name}) : $this->placeholder, class: 'image')
$input .= lf.tab.input(type: 'file', class: 'image-input',  name: $this->name, accept: 'image/*', data_size: $this->thumbSize)
$file && $this->canDelete && $input .= lf.tab.tag('div', inner: tag('label', inner: input(type: 'checkbox', name: $this->name.'Delete')." $this->delete"))
return $input.lf
method

%field_image -> write ($file)

line 33
Writes an image file to a specified path and moves the original file to another location, while also scaling the image to a defined thumbnail size.
%img($file->file)->scale($this->thumbSize, $this->thumbSize)->save($this->writePath($file, $this->thumbPath)) && $file->move($this->writePath($file))
prop

%field_image -> objColumns:array

line 35
This expression retrieves the columns associated with the field_image, specifically the column names defined by the object's name and its token variant.
[$this->name, $this->name.'_token']
view

script

line 37
This script handles click events on image elements to trigger a file input and processes image uploads by resizing the selected image before updating the source of the previous sibling element.
on('click', '.input.image .image', img => img.nextElementSibling.click())
on('change', '.input.image .image-input', input => imageResizer(input.files[0], input.dataset.size, input.dataset.size, image => input.previousElementSibling.src = image))
object

%field_many

/phlo/resources/fields/many.phlo

Many-to-many relation field

Editing is opt-in: a model that sets create/change on a many field gets the checkbox picker from input(); CMS.API::syncMany() then rewrites the pivot table on save.

fieldrelationmany
prop

%field_many -> list

line 12
The field_many->$list property is used to define a list of labels for a field in a Phlo application.
'label'
prop

%field_many -> record

line 13
Accesses the 'label' field of each record in a collection of records.
'label'
prop

%field_many -> create

line 14
Creates multiple instances of a field in a resource.
false
prop

%field_many -> change

line 15
The field_many->$change property indicates whether changes have occurred in the field's value.
false
method

%field_many -> count ($record):int

line 17
Returns the count of records associated with the specified field name in the given record.
$record->getCount($this->name)
method

%field_many -> label ($record):string

line 18
Generates a label for each item in a many-to-many relationship from the given record, linking to the related entities.
loop($record->{$this->name}, fn($relation) => $this->link($relation), lf) ?: dash
method
line 19
Creates a link to a specific record using its URI and ID, rendering it as an anchor tag with the class 'async'.
tag('a', href: slash.($record::$uriRecord ?? $record::class).slash.$record->{$record::idColumn()}, class: 'async', inner: $record)
method

%field_many -> input ($record):string

line 21
Generates a set of checkbox inputs for a many-to-many relationship based on the provided record, allowing for multiple selections.
$pk = $this->obj::idColumn()
$current = array_keys($record->{$this->name} ?: [])
$boxes = loop($this->obj::records(), fn($o) => tag('label', tag('input', type: 'checkbox', name: $this->name.'[]', value: $o->$pk, checked: in_array($o->$pk, $current) ? true : null).esc((string)$o), class: 'ms-opt'), void)
return tag('div', $boxes ?: tag('span', 'no options', class: 'muted'), class: 'ms-grid')
method

%field_many -> sync ($model, $parentId)

line 28
Synchronizes a many-to-many relationship by deleting existing entries for a given parent ID and creating new entries based on the provided payload.
$rel = $model::objMany()[$this->name]
$ids = array_values(array_unique(array_filter((array)(%payload->{$this->name} ?? []), fn($id) => (string)$id !== '')))
$db = $model::DB()
$db->delete($rel['table'], $rel['localKey'].'=?', $parentId)
foreach ($ids AS $id) $db->create($rel['table'], ...[$rel['localKey'] => $parentId, $rel['foreignKey'] => $id])
method

%field_many -> objOwns ($record, $parentId, $parentModel):bool

line 36
Checks if a record is owned by a specified parent model by querying the database for a relationship defined in the parent model.
$rel = $parentModel::objMany()[$this->name]
return (bool)$parentModel::DB()->record($rel['table'], ...[$rel['localKey'] => $parentId, $rel['foreignKey'] => $record->{$record::idColumn()}])
prop

%field_many -> objColumns:array

line 41
The field_many->$objColumns property holds an array of column objects associated with a many-to-many relationship in a Phlo resource.
[]
object

%field_multiselect

/phlo/resources/fields/multiselect.phlo

Multi-select via checkboxes; stores the choice as CSV in one hidden field (no save change needed).

Joins the checked boxes into one comma separated column, so it needs no pivot table and no extra save logic. Reach for many instead when the choices are records with a life of their own.

fieldselectmulti
method

%field_multiselect -> label ($record):string

line 12
Generates a label for a multi-select field based on the provided record, filtering and formatting the selected values into tags.
$values = array_filter(array_map('trim', explode(comma, (string)($record->{$this->name} ?? void))))
return $values ? loop($values, fn($v) => tag('span', esc($v), class: 'ms-tag'), space) : dash
method

%field_multiselect -> input ($record):string

line 17
Generates a multi-select input field with checkboxes based on the provided options, allowing users to select multiple values from a list.
$current = array_filter(array_map('trim', explode(comma, (string)($record->{$this->name} ?? void))))
$js = "var f=this.closest('.field');f.querySelector('input.msv').value=[...f.querySelectorAll('input.msc:checked')].map(c=>c.value).join(',')"
$boxes = loop((array)$this->options, fn($o) => tag('label', tag('input', type: 'checkbox', value: (string)$o, class: 'msc', checked: in_array((string)$o, $current) ? true : null, onchange: $js).esc((string)$o), class: 'ms-opt'), void)
return tag('input', type: 'hidden', name: $this->name, value: implode(comma, $current), class: 'msv').tag('div', $boxes ?: tag('span', 'no options', class: 'muted'), class: 'ms-grid')
prop

%field_multiselect -> objColumns:array

line 24
This retrieves the value of the field identified by the name property from the current object context.
[$this->name]
object

%field_number

/phlo/resources/fields/number.phlo

Number field

decimals sets both the step of the input and the formatting of the list. min is 0 out of the box, so state it yourself when negative values are allowed.

fieldnumber
prop

%field_number -> decimals

line 12
The `field_number->$decimals` property specifies the number of decimal places for a numeric field in Phlo.
prop

%field_number -> length

line 13
This defines the length property of a field_number, specifying the maximum number of digits allowed.
5
prop

%field_number -> min

line 14
This prop defines the minimum value for a number field in a view.
method

%field_number -> label ($record):string

line 16
($value = $record->{$this->name}) === null || $value === void ? dash : number_format($value, $this->decimals, comma, dot)
method

%field_number -> input ($record):string

line 17
Generates an HTML input element of type 'number' with specified attributes, including name, value, step, and min, using data from the provided record.
input(type: 'number', name: $this->name, value: $record->{$this->name} ?? $this->default, step: $this->decimals ? dot.str_repeat('0', $this->decimals - 1).'1' : null, min: $this->min, class: 'field')
method

%field_number -> parse ($record):void

line 19
$name = $this->name
if (!%payload->hasData($name)) return
$value = %payload->$name
$record->$name = ($value === null || (is_string($value) && trim($value) === void)) ? ($this->default ?? 0) : $value
prop

%field_number -> objColumns:array

line 26
Accesses the column data associated with the field represented by the current object instance using its name.
[$this->name]
object

%field_parent

/phlo/resources/fields/parent.phlo

Parent relation field

Points at another model through obj and offers every record of it in one select, so keep it to sets a person can still scroll. Reading the field gives you the record itself, not the id.

fieldrelationparent
method

%field_parent -> label ($record):string

line 12
Returns the label of the parent field for a given record, linking to the model if applicable, otherwise returning a dash.
is_a($obj = $record->{$this->name}, 'model') ? $this->link($obj) : dash
method

%field_parent -> input ($record):string

line 13
Generates an HTML <select> input element populated with options based on the provided $record, marking the option as selected if it matches the record's ID.
select(name: $this->name, inner: loop($this->options, fn($parent) => '<option'.($parent->id === $record->{$this->name}?->id ? ' selected' : void).' value="'.$parent->id.'">'.$parent, void))
method
line 14
Generates an anchor (`<a>`) HTML element linking to a specific record's URI, using the record's ID and an optional inner content.
tag('a', href: slash.($record::$uriRecord ?? $record::class).slash.$record->id, class: 'async', inner: $content ?? $record)
prop

%field_parent -> options:array

line 15
Accesses the options associated with the parent field in the context of the current object records.
$this->obj::records()
prop

%field_parent -> objColumns:array

line 17
Accesses the columns of the parent object in the context of the current field.
[$this->name]
object

%field_password

/phlo/resources/fields/password.phlo

Password field

Never gives the stored value back: a list prints dots and an empty form field leaves the current password untouched. It hashes with bcrypt on save, so keep the plain value nowhere.

fieldpassword
prop

%field_password -> list

line 12
The field_password->$list expression is used to access a list of password fields in a Phlo application, returning false if no such fields exist.
false
prop

%field_password -> required

line 13
Specifies whether the password field is required for form submission, with a value of true indicating that it is mandatory.
true
prop

%field_password -> minlength

line 14
Sets the minimum length requirement for the password field.
8
prop

%field_password -> placeholder

line 15
Sets the placeholder text for the password input field to 'New password'.
'New password'
method

%field_password -> input ($record):string

line 17
Generates an input field for a password with specified attributes such as type, name, placeholder, and class.
input(type: $this->type, name: $this->name, placeholder: $this->placeholder, class: 'field')
method

%field_password -> label ($record):string

line 18
Generates a label for a password field based on the provided record.
'••••••••'
method

%field_password -> parse ($record)

line 19
($password = trim((string)%payload->{$this->name})) && $record->{$this->name} = password_hash($password, PASSWORD_BCRYPT)
prop

%field_password -> objColumns:array

line 21
Accesses the password field from the objColumns array using the current object's name as the key.
[$this->name]
object

%field_price

/phlo/resources/fields/price.phlo

Price field

A number field fixed at two decimals. Store the amount in the unit you bill in and leave the formatting to the field.

fieldpricemoney
prop

%field_price -> decimals

line 12
This property defines the number of decimal places for the price field.
2
object

%field_select

/phlo/resources/fields/select.phlo

Select field

Stores the chosen option itself rather than a key, so renaming an option later leaves older records pointing at wording you no longer offer. Pass the accepted values as options.

fieldselect
method

%field_select -> input ($record):string

line 12
Generates a select input field with options based on the provided $record, marking the current option as selected if it matches the value in $record.
select(name: $this->name, inner: loop($this->options, fn($option) => "<option".($record->{$this->name} === $option ? ' selected' : void).">$option", void))
prop

%field_select -> objColumns:array

line 14
Accesses the column data associated with the current object's name in the context of a field selection.
[$this->name]
object

%field_text

/phlo/resources/fields/text.phlo

Text field

length is both the limit and the choice of input: over 250 characters the field renders a textarea instead of a single line.

fieldtext
prop

%field_text -> length

line 12
The field_text->$length property returns the length of the text in the field as an integer.
100
prop

%field_text -> multiline:bool

line 13
The field_text->$multiline property determines if the text field allows multiline input based on the condition that the length exceeds 250 characters.
$this->length > 250
method

%field_text -> label ($record):string

line 15
($value = $record->{$this->name}) === null ? dash : strtr(esc(strlen($value) > 100 ? substr($value, 0, 80).'...' : $value), [lf => br])
method

%field_text -> input ($record):string

line 16
Generates an input field for text entry, using either a multi-line input or a single-line input based on the multiline property.
$this->multiline ? $this->inputMulti($record) : $this->inputField($record)
method

%field_text -> inputField ($record):string

line 17
Generates an input field for a form, using the specified type, name, value, maxlength, placeholder, and class attributes.
input(type: $this->type, name: $this->name, value: ($value = $record->{$this->name}) ? esc($value) : $this->default, maxlength: $this->length, placeholder: $this->placeholder, class: 'field')
method

%field_text -> inputMulti ($record):string

line 18
Generates a multi-line text input field using a textarea element, pre-filling it with a value from the provided record or a default value if none exists.
textarea(name: $this->name, inner: ($value = $record->{$this->name}) ? esc($value) : $this->default ?? void, placeholder: $this->placeholder, class: 'field')
prop

%field_text -> objColumns:array

line 20
Accesses the column data associated with the field's name in the object.
[$this->name]
object

%field_token

/phlo/resources/fields/token.phlo

Token field

Fills itself with a random token when a record is made and refuses to change afterwards, which makes it the id to use for anything that ends up in a URL. handle is true, so a record can be looked up by this column instead of by its id.

fieldtoken
prop

%field_token -> length

line 12
Returns the length of the field_token as an integer.
8
prop

%field_token -> default:string

line 13
Generates a default token of a specified length using the token function.
token($this->length)
prop

%field_token -> create

line 14
Creates a new field token in the context of a resource, returning false if the operation fails.
false
prop

%field_token -> change

line 15
The field_token->$change expression evaluates to false, indicating that there is no change in the field token.
false
prop

%field_token -> search

line 16
The field_token->$search expression evaluates to true, indicating that the search functionality is enabled for the field token.
true
prop

%field_token -> handle

line 17
This expression retrieves the value of the 'handle' property from the 'field_token' object, returning true if it exists.
true
method

%field_token -> label ($record):string

line 19
This function retrieves the label for a field token from a given record and wraps it in a 'div' tag, escaping any special characters.
tag('div', inner: esc($record->{$this->name}))
method

%field_token -> parse ($record)

line 20
Parses a field token from the given record, assigning a default value if the token is not present.
$record->{$this->name} ??= $this->default
prop

%field_token -> objColumns:array

line 22
Accesses the column data associated with the field token in the current object context.
[$this->name]
object

%field_virtual

/phlo/resources/fields/virtual.phlo

Virtual field

Owns no column and is never saved, so use it to show something derived next to the real fields. The record supplies the value through a prop or method of the same name.

fieldvirtual
prop

%field_virtual -> create

line 12
This property indicates whether the field is virtual and should be created dynamically.
false
prop

%field_virtual -> change

line 13
The field_virtual->$change property indicates whether the virtual field has changed from its previous value.
false
prop

%field_virtual -> objColumns:array

line 15
The field_virtual->$objColumns property is used to access the columns of a virtual field in an object.
[]
object

%field_wysiwyg

/phlo/resources/fields/wysiwyg.phlo

WYSIWYG field

Stores whatever HTML the editor produces, including anything a user pasted in, so clean or escape it before it reaches a public page.

fieldwysiwygeditor
method

%field_wysiwyg -> input ($record):string

line 12
Generates a WYSIWYG editor input field, including a toolbar for text formatting and a hidden input to store the value.
$value = $record->{$this->name} ?? $this->default ?? void
$toolbar = tag('div', class: 'toolbar', inner: tag('button', type: 'button', data_command: 'bold', inner: '<b>B</b>').tag('button', type: 'button', data_command: 'italic', inner: '<i>I</i>').tag('button', type: 'button', data_command: 'underline', inner: '<u>U</u>').tag('button', type: 'button', data_command: 'insertUnorderedList', inner: '•').tag('button', type: 'button', data_command: 'insertOrderedList', inner: '1.'))
$editor = tag('div', class: 'editor', contenteditable: 'true', inner: $value)
$hiddenInput = textarea(name: $this->name, class: 'hidden-value', inner: $value)
return tag('div', class: 'wysiwyg-container', inner: "$toolbar$editor$hiddenInput")
prop

%field_wysiwyg -> objColumns:array

line 20
Accesses the WYSIWYG field's columns as an object, allowing manipulation of the field's data structure.
[$this->name]
view

script

line 22
This script enables a WYSIWYG editor by handling button clicks to execute commands and updating a hidden textarea with the editor's HTML content on input events.
on('click', '.wysiwyg-container .toolbar button', (button, e) => {
	e.preventDefault()
	const command = button.dataset.command
	document.execCommand(command, false, null)
})

on('input', '.wysiwyg-container .editor', editor => {
	const container = editor.closest('.wysiwyg-container')
	const hiddenInput = container.querySelector('textarea.hidden-value')
	hiddenInput.value = editor.innerHTML
})
on('click', '.wysiwyg-container .editor a', a => window.open(a.href))

Functions

function

field($type, ...$args):field

/phlo/resources/fields/field.phlo line 11

Base ORM field

Every field type extends this one and is made with field(type: 'x'), which resolves to the resource field_x; anything else you pass becomes a property, so title, required, length, pattern and enum need no declaration. Override input() for the form and label() for the list, and let objColumns name the columns the field owns, so a field that stores nothing returns an empty array.

fieldorm
Creates a field with a specified type and additional arguments, using the phlo function to generate a unique identifier for the field.
phlo("field_$type", ...$args, type: $type)

Last updated on 23 August 2026

We use essential cookies to make this site work. With your permission we also use analytics to improve the site.