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
创建一个具有指定类型和附加参数的字段,使用phlo函数为字段生成唯一标识符。
phlo("field_$type", ...$args, type: $type)
static

field :: __handle

line 13
此属性用于访问Phlo中字段对象的内部句柄。
null
prop

%field -> title:string

line 15
此表达式获取当前对象的'name'属性,并将首字母大写。
ucfirst($this->name)
method

%field -> input ($record):string

line 17
根据指定的类型、名称和提供的记录中的值生成输入字段,并可选地添加maxlength和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
使用字段的名称从指定记录中检索字段的标签。
$record->{$this->name};
prop

%field -> objColumns:array

line 20
此属性在字段的上下文中检索指定obj的列。
[]
method

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

line 22
根据指定的规则(如必需、长度、模式和枚举约束)验证给定的值,如果验证失败则返回错误消息。
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
表示一个布尔字段,其值为真,显示为勾号符号 '✅'。
'✅'
prop

%field_bool -> false

line 13
表示默认值为 false 的布尔字段,显示为 '❌'。
'❌'
method

%field_bool -> label ($record):string

line 15
返回给定记录中布尔字段对应的标签,根据字段的值返回真标签或假标签。
$record->{$this->name} ? $this->true : $this->false
method

%field_bool -> input ($record):string

line 16
生成一个布尔值的复选框输入字段,带有标签和视觉增强的滑块,基于提供的记录值。
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
此函数将布尔字段转换为可空类型,使其能够表示真、假或空值。
false
prop

%field_bool -> objColumns:array

line 20
访问与对象上下文中的布尔字段相关联的列。
[$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
访问列表中field_child对象的'count'属性。
'count'
prop

%field_child -> change

line 13
field_child->$change 属性指示子字段是否发生了任何更改,布尔值 false 表示没有发生更改。
false
prop

%field_child -> create

line 14
该表达式的值为false,表示field_child属性不支持create操作。
false
prop

%field_child -> record

line 15
访问列表中当前字段的子记录。
'list'
method

%field_child -> count ($record):string

line 17
计算与给定记录关联的子记录数量并返回该计数。
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
从给定记录中检索指定字段的最后一个值。
$record->getLast($this->name)
method

%field_child -> label ($record):string

line 19
从给定记录中检索子字段的标签,如果未找到标签,则返回破折号。
implode(loop($record->{$this->name}, fn($child) => $this->link($child))) ?: dash
method

%field_child -> input ($record):string

line 20
生成一个与特定记录相关联的输入字段,使用标签方法显示相应的标签。
$this->label($record)
method
line 21
使用记录的 URI 和 ID 生成指向特定记录的链接,创建一个类为 '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
如果key属性存在,则返回其值;否则返回$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
该表达式检索与field_date对象关联的句柄,如果存在则返回true。
true
prop

%field_date -> format

line 13
根据指定的格式字符串格式化日期字段。
null
prop

%field_date -> months:array

line 14
该项提供了一个关联数组,将月份数字映射到其对应的英文和荷兰文名称。
[
	'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
从给定记录格式化日期标签,返回基于指定格式或默认本地化表示的格式化字符串。
$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
使用名称属性访问指定对象列的日期字段。
[$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
field_datetime->$handle 表达式用于访问 Phlo 中 datetime 字段的句柄。
true
prop

%field_datetime -> change

line 13
该项检查字段名称是否不是 'created' 或 'changed',然后才允许对日期时间字段进行更改。
!in_array($this->name, ['created', 'changed'])
prop

%field_datetime -> create

line 14
检查字段名称是否不是 'created' 或 'changed'。
!in_array($this->name, ['created', 'changed'])
method

%field_datetime -> label ($record):string

line 16
为记录中的日期时间字段生成标签,如果存在值,则显示图标和可读的时间格式。
($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
根据时间值(以秒为单位)返回颜色类,超过一天为'红色',超过一小时为'黄色',否则为'蓝色'。
$value > 86400 ? 'red' : ($value > 3600 ? 'yellow' : 'blue')
method

%field_datetime -> input ($record):string

line 18
为指定记录属性生成一个类型为'datetime-local'的输入字段,允许用户选择日期和时间。
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
从记录中解析日期时间字段,如果'created'尚未设置,则将其设置为当前时间,更新'changed'为当前时间,或者如果存在,则将有效负载值转换为时间戳。
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
访问与field_datetime对象相关联的列,返回其名称。
[$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
此视图为存储在记录中的电子邮件地址生成一个mailto链接,允许用户点击直接发送电子邮件。
<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
`field_file->$canDelete` 属性指示文件是否可以被删除。
true
prop

%field_file -> delete

line 13
在删除文件之前提示用户确认。
'Delete file?'
prop

%field_file -> path

line 14
`field_file->$path` 获取与资源上下文中特定文件字段关联的文件路径。
files
prop

%field_file -> uri

line 15
该属性返回存储在'/files/'目录中的文件的URI。
'/files/'
prop

%field_file -> length

line 16
`field_file` 的 `$length` 属性返回文件的大小(以字节为单位)。
100
prop

%field_file -> accept

line 17
定义表单中文件输入字段接受的文件类型。
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
从有效负载中解析文件,处理删除并在有效时写入文件,并使用文件的缩短名称和令牌更新记录。
$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
将指定的文件写入指定路径,如有必要则移动,并在写入操作失败时触发错误。
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->name, $this->name.'_token']
view

script

line 59
该脚本通过在点击相关标签时触发文件输入的点击,并在选择文件后用所选文件名更新标签文本,来处理文件输入交互。
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
向用户提示确认消息,询问他们是否要删除该图像。
'Delete image?'
prop

%field_image -> uri

line 13
该表达式通过将基本路径 '/images/' 附加到字段的值来检索图像字段的 URI。
'/images/'
prop

%field_image -> path

line 14
`field_image->$path` 访问存储在 `field_image` 资源中的图像路径。
images
prop

%field_image -> thumbPath

line 15
在`field_image`对象中的`thumbPath`字段检索存储在`thumbs`资源中的缩略图路径。
thumbs
prop

%field_image -> thumbSize

line 16
`field_image->$thumbSize` 属性定义了 Phlo 中给定字段的缩略图像大小。
64
prop

%field_image -> thumbUri

line 17
该 prop 通过将 '/thumbs/' 附加到 field_image 值来生成缩略图 URI。
'/thumbs/'
prop

%field_image -> placeholder

line 18
返回用于视图的 base64 编码 SVG 占位符图像。
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM4ODgiIHN0cm9rZS13aWR0aD0iMS40Ij48cmVjdCB4PSIzIiB5PSIzIiB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHJ4PSIyIi8+PGNpcmNsZSBjeD0iOC41IiBjeT0iOC41IiByPSIxLjYiLz48cGF0aCBkPSJNMjEgMTVsLTUtNUw1IDIxIi8+PC9zdmc+'
prop

%field_image -> record

line 20
在 field_image 上下文中访问当前记录的 'preview' 字段。
'preview'
method

%field_image -> label ($record):string

line 22
生成一个包含图像的HTML锚标签,链接到基于提供的记录数据的指定URI。如果记录不包含文件名,则返回一个破折号。
($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
为指定记录生成预览图像链接,使用记录中的文件名和令牌构建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
生成一个用于上传图像的HTML输入元素,如果可用,还会显示当前图像的预览,并提供一个可选的复选框用于删除图像。
$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
将图像文件写入指定路径,并将原始文件移动到另一个位置,同时将图像缩放到定义的缩略图大小。
%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
此表达式检索与field_image相关的列,具体来说是由对象的名称及其令牌变体定义的列名。
[$this->name, $this->name.'_token']
view

script

line 37
该脚本处理图像元素的点击事件,以触发文件输入,并在更新前一个兄弟元素的源之前处理图像上传,通过调整所选图像的大小。
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
field_many->$list 属性用于在 Phlo 应用程序中定义字段的标签列表。
'label'
prop

%field_many -> record

line 13
访问集合中每个记录的 'label' 字段。
'label'
prop

%field_many -> create

line 14
在资源中创建多个字段实例。
false
prop

%field_many -> change

line 15
field_many->$change 属性指示字段值是否发生了变化。
false
method

%field_many -> count ($record):int

line 17
返回与给定记录中指定字段名称相关联的记录数量。
$record->getCount($this->name)
method

%field_many -> label ($record):string

line 18
从给定记录生成许多对多关系中每个项目的标签,并链接到相关实体。
loop($record->{$this->name}, fn($relation) => $this->link($relation), lf) ?: dash
method
line 19
使用记录的URI和ID创建指向特定记录的链接,将其呈现为带有'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
根据提供的记录生成一组复选框输入,用于多对多关系,允许多项选择。
$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
通过删除给定父ID的现有条目并根据提供的有效负载创建新条目来同步多对多关系。
$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
通过查询父模型中定义的关系,检查记录是否属于指定的父模型。
$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
field_many->$objColumns 属性保存与 Phlo 资源中的多对多关系相关联的列对象数组。
[]
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
根据提供的记录生成多选字段的标签,将选定的值过滤并格式化为标签。
$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
生成一个基于提供选项的多选输入字段,允许用户从列表中选择多个值。
$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->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
`field_number->$decimals` 属性指定 Phlo 中数字字段的小数位数。
prop

%field_number -> length

line 13
这定义了field_number的长度属性,指定允许的最大数字位数。
5
prop

%field_number -> min

line 14
此 prop 定义了视图中数字字段的最小值。
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
生成一个类型为'number'的HTML输入元素,具有指定的属性,包括名称、值、步长和最小值,使用提供的记录中的数据。
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
使用当前对象实例的名称访问与该字段相关联的列数据。
[$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
返回给定记录的父字段的标签,如果适用则链接到模型,否则返回一个破折号。
is_a($obj = $record->{$this->name}, 'model') ? $this->link($obj) : dash
method

%field_parent -> input ($record):string

line 13
生成一个HTML <select> 输入元素,基于提供的 $record 填充选项,如果选项的ID与记录的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
生成一个锚点(`<a>`)HTML元素,链接到特定记录的URI,使用记录的ID和可选的内部内容。
tag('a', href: slash.($record::$uriRecord ?? $record::class).slash.$record->id, class: 'async', inner: $content ?? $record)
prop

%field_parent -> options:array

line 15
访问与当前对象记录上下文中的父字段相关联的选项。
$this->obj::records()
prop

%field_parent -> objColumns:array

line 17
在当前字段的上下文中访问父对象的列。
[$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
field_password->$list 表达式用于访问 Phlo 应用程序中的密码字段列表,如果不存在这样的字段,则返回 false。
false
prop

%field_password -> required

line 13
指定密码字段在表单提交时是否为必填项,值为true表示该字段是必需的。
true
prop

%field_password -> minlength

line 14
设置密码字段的最小长度要求。
8
prop

%field_password -> placeholder

line 15
将密码输入字段的占位符文本设置为 'New password'。
'New password'
method

%field_password -> input ($record):string

line 17
生成一个密码输入字段,具有指定的属性,如类型、名称、占位符和类。
input(type: $this->type, name: $this->name, placeholder: $this->placeholder, class: 'field')
method

%field_password -> label ($record):string

line 18
根据提供的记录生成密码字段的标签。
'••••••••'
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
使用当前对象的名称作为键,从objColumns数组中访问密码字段。
[$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
此属性定义价格字段的小数位数。
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
根据提供的 $record 生成一个选择输入字段,如果当前选项与 $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
在字段选择的上下文中访问与当前对象名称相关联的列数据。
[$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
field_text->$length 属性返回字段中文本的长度,作为一个整数。
100
prop

%field_text -> multiline:bool

line 13
field_text->$multiline 属性根据长度超过 250 个字符的条件来确定文本字段是否允许多行输入。
$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
生成一个文本输入字段,根据multiline属性使用多行输入或单行输入。
$this->multiline ? $this->inputMulti($record) : $this->inputField($record)
method

%field_text -> inputField ($record):string

line 17
生成一个表单的输入字段,使用指定的类型、名称、值、最大长度、占位符和类属性。
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
使用textarea元素生成多行文本输入字段,如果提供的记录中没有值,则用默认值预填充。
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
访问与字段名称关联的对象中的列数据。
[$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
返回 field_token 的长度,类型为整数。
8
prop

%field_token -> default:string

line 13
使用token函数生成指定长度的默认令牌。
token($this->length)
prop

%field_token -> create

line 14
在资源的上下文中创建一个新的字段令牌,如果操作失败则返回false。
false
prop

%field_token -> change

line 15
field_token->$change 表达式的值为 false,表示字段令牌没有变化。
false
prop

%field_token -> search

line 16
field_token->$search 表达式的值为 true,表示该字段令牌的搜索功能已启用。
true
prop

%field_token -> handle

line 17
该表达式从'field_token'对象中检索'handle'属性的值,如果存在则返回true。
true
method

%field_token -> label ($record):string

line 19
此函数从给定记录中检索字段令牌的标签,并将其包装在'div'标签中,转义任何特殊字符。
tag('div', inner: esc($record->{$this->name}))
method

%field_token -> parse ($record)

line 20
从给定记录中解析字段令牌,如果令牌不存在,则分配默认值。
$record->{$this->name} ??= $this->default
prop

%field_token -> objColumns:array

line 22
访问与当前对象上下文中的字段令牌关联的列数据。
[$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
此属性指示该字段是否为虚拟字段,并应动态创建。
false
prop

%field_virtual -> change

line 13
field_virtual->$change 属性指示虚拟字段是否已从其先前值更改。
false
prop

%field_virtual -> objColumns:array

line 15
field_virtual->$objColumns 属性用于访问对象中虚拟字段的列。
[]
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
生成一个所见即所得的编辑器输入字段,包括一个用于文本格式化的工具栏和一个隐藏输入以存储值。
$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
将WYSIWYG字段的列作为对象访问,允许对字段的数据结构进行操作。
[$this->name]
view

script

line 22
该脚本通过处理按钮点击来启用WYSIWYG编辑器,并在输入事件中用编辑器的HTML内容更新隐藏的textarea。
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
创建一个具有指定类型和附加参数的字段,使用phlo函数为字段生成唯一标识符。
phlo("field_$type", ...$args, type: $type)

最近更新于 2026年8月23日

我们使用必要的cookie来使该网站正常工作。在您的许可下,我们还使用分析工具来改善网站。