Referência
Tipos de campo
Os tipos de campo suportados e sua configuração.
Tipos de campo
| Tipo | Descrição |
|---|---|
text |
Texto de uma linha |
textarea |
Texto simples de várias linhas |
html |
Texto formatado (editor bubble e barra do campo, veja Botões do editor) |
slug |
Campo de slug seguro para URL, calculado a partir dos campos de origem configurados |
boolean |
Chave verdadeiro/falso |
date |
Seletor de data |
email |
Endereço de e-mail |
url |
URL |
password |
Campo de senha criptografado |
image |
Envio de uma imagem |
file |
Envio de um arquivo |
upload |
Envio genérico |
gallery |
Envio de várias imagens |
select |
Lista de opções, fixas ou de um recurso |
number |
Entrada numérica, com min e max opcionais |
color |
Seletor de cor |
location-picker |
Mapa-múndi interativo que guarda a latitude no campo e a longitude no campo associado configurado em longitude_field |
Os nomes dos tipos de campo precisam corresponder exatamente.
Configuração de campos
Opções comuns por campo:
| Chave | Tipo | Descrição |
|---|---|---|
name |
string | Rótulo exibido no admin |
required |
boolean | Validação; defina em todos os campos de título e nome |
admin_col |
boolean | Mostrar na tabela da visão geral do admin (padrão: true) |
admin_filter |
boolean ou objeto | Acrescenta um filtro à visão geral do admin para um campo select ou boolean. Use { "default": <stored-value> } para ativá-lo com uma seleção padrão, e o "feature": "permission-name" opcional para mostrá-lo só a usuários com essa permissão. Independente de admin_col. |
multi |
boolean | Permitir vários valores |
i18n |
boolean | Traduzir por idioma |
accept |
string | Restrição de tipo de arquivo para campos image e file |
Campos HTML devem usar explicitamente uma de duas configurações:
Simples (blocos curtos de texto, como uma introdução):
"buttons": "bold,italic",
"admin_col": false
Rica (conteúdo completo, como um corpo de texto):
"buttons": "h2,h3,h4,bold,italic,orderedlist,unorderedlist,quote,anchor",
"media": true,
"media_sizes": "sm-90,md-70,lg-60,xl-50,xxl-40",
"admin_col": false
Nunca defina um campo html sem escolher uma delas. media_sizes é obrigatório quando media: true.
Botões do editor. buttons lista os botões de formatação de um campo html, em ordem. Sem buttons, um campo recebe bold,italic,removeFormat. Integrados:
| Botão | Faz |
|---|---|
bold, italic |
Formatação no texto (Ctrl/Cmd+B, Ctrl/Cmd+I) |
h2, h3, h4, quote, pre |
Formato de bloco; repetir volta a ser parágrafo |
orderedlist, unorderedlist |
Listas |
anchor |
Link: adicionar, editar (pré-preenchido) ou remover; Ctrl/Cmd+K |
removeFormat |
Limpar formatação |
strikethrough, subscript, superscript, underline |
Opcionais, em nenhum conjunto padrão |
Os mesmos botões aparecem em dois lugares: a barra bubble no texto selecionado e a barra do campo. Nos formulários do admin a barra do campo faz parte da caixa do campo; na edição na página ela flutua acima do campo em foco e também tem Media (quando media: true) e Save (Ctrl/Cmd+S). Alt+F10 leva o foco do teclado à barra do campo. Colar mantém só texto simples, a menos que o campo defina "paste_html": true, que mantém a formatação básica e remove o markup do Word e do Google Docs.
Botões próprios do editor. Um projeto declara seus próprios botões como JSON em ext/tpl/bubble-editor-buttons/index.tpl (o template pode usar shortcodes, como [#text ...#] para rótulos) e os lista no buttons de um campo como os integrados:
{
"highlight": { "kind": "wrap", "tag": "mark", "label": "[#text Highlight#]", "icon": "M" },
"h5": { "kind": "block", "tag": "h5", "label": "Heading 5", "icon": "H5" },
"poi": {
"kind": "event", "event": "nb:insert-point", "insert": true, "bubble": true,
"active": "[data-poi-link]", "label": "[#text Point of interest#]", "icon": "<svg ...></svg>"
}
}
| Tipo | Faz |
|---|---|
command |
Um comando de formatação ("command": "bold") |
block |
Formato de bloco ("tag": "h5") |
list |
Comando de lista |
wrap |
Envolve a seleção num elemento ("tag", "class" opcional); repetir desfaz |
insert |
Insere um HTML fixo no cursor ("html") |
event |
Dispara um evento DOM no campo ("event", com bubbling, detail: { editor, range }) para o código próprio do projeto, por exemplo para abrir um seletor |
link |
Pede uma URL, como anchor |
Opções: "insert": true coloca um botão ao lado de Media na barra do campo em vez de junto dos botões de formatação; acrescente "bubble": true quando ele também age sobre texto selecionado; "active" é um seletor que marca o botão como ativo quando o cursor está dentro de uma correspondência. Links são a[href]: um projeto pode usar <a> sem href para elementos próprios no texto. O código também pode registrar botões com nb.bubble_editor.register(name, { label, icon, run(ctx), is_active(ctx) }).
As ferramentas de edição de um projeto (o modal e o script por trás de um botão event) ficam em ext/tpl/edit-extras/index.tpl, exibido para usuários que podem editar na página, em páginas do site e do admin.
Campos de slug:
Slugs são campos explícitos. Não acrescente "slug": true a outro campo. Defina um campo separado com "type": "slug" e um source que aponte para o campo ou os campos de que ele é derivado.
O formulário do admin calcula o slug no navegador a partir dos campos de origem, antes do envio. A API não inventa campos de slug que faltam ao salvar; ela guarda o valor do campo de slug que recebe. Se um código cria ou importa registros fora do formulário do admin, ele também precisa definir o valor do campo de slug.
Defina "preserve_existing": true no campo de slug para gerar slugs que faltam, mantendo inalteradas as URLs já salvas quando o formulário abre ou quando o título de origem muda. Os editores ainda podem mudar um slug salvo de propósito.
"url_slug": {
"name": "URL slug",
"type": "slug",
"source": "title",
"admin_col": false
}
Várias origens são separadas por vírgula; os valores são unidos com um espaço antes de virar slug:
"url_slug": {
"name": "URL slug",
"type": "slug",
"source": "title,date",
"admin_col": false
}
Com "source": "title,date", título "Jazz Night" e data "2026-04-09", o slug vira jazz-night-2026-04-09. Acrescente sempre url_slug à lista index do recurso, para que ele possa ser buscado no route.inc.
Se o campo de origem é i18n, o campo de slug também é tratado como i18n. Por exemplo, title.nl, title.en e title.fr geram valores correspondentes em title_slug.nl, title_slug.en e title_slug.fr. Não traduza slugs à mão; deixe o campo de slug derivá-los dos valores de origem de cada idioma.
Campos de seleção:
Opções fixas:
"type": "select",
"options": {
"new": "New",
"active": "Active",
"closed": "Closed"
}
Opções de outro recurso:
"type": "select",
"resource": "categories"
Os filtros da visão geral do admin são ativados por campo, em campos select e boolean:
"status": {
"type": "select",
"options": { "active": "Active", "closed": "Closed" },
"admin_filter": { "default": "active" }
},
"published": {
"type": "boolean",
"admin_col": false,
"admin_filter": true
}
Os filtros comparam os valores brutos guardados, enquanto exibem as opções configuradas ou os rótulos do recurso relacionado. Seleções com vários valores correspondem quando o registro contém o valor escolhido. Vários filtros se combinam com E e continuam funcionando com busca, ordenação e paginação. As seleções ficam na URL como filter[field]=value. Um parâmetro ausente usa o padrão configurado; um parâmetro vazio escolhe explicitamente All. Valores inválidos na URL viram All.
Campos de localização:
Use location-picker quando os editores devem escolher coordenadas num mapa em vez de digitá-las. O campo seletor guarda a latitude no próprio campo e atualiza um campo numérico separado de longitude, indicado em longitude_field. Oculte o campo associado com wrapper_class: "hidden", para que o editor veja um único controle enquanto o recurso guarda coordenadas simples:
"location_lat": {
"name": "Location",
"type": "location-picker",
"longitude_field": "location_lng",
"required": true,
"admin_col": false
},
"location_lng": {
"name": "Longitude",
"type": "number",
"required": true,
"min": -180,
"max": 180,
"wrapper_class": "hidden",
"admin_col": false
}
Como os campos de formulário são gerados
Esta seção mostra o caminho completo, da definição de um campo num recurso até o campo exibido no formulário. Leia antes de criar um novo tipo de campo.
Visão geral
.meta field definition
↓
render_field() - PHP (core/modules/forms/lib/render-field.php)
↓
_f.* template variables
↓
[#field-{type}#] template (core/modules/forms/tpl/field-{type}/index.tpl)
↓
Alpine.js form_data.{field} ← x-model binding
↓
API POST/PUT on submit
render_field() e o contexto _f.*
render_field() é a porta de entrada. Ele:
- Recebe um array com a definição do campo, a chave do campo e parâmetros opcionais de valor, armazenamento e origem
- Espalha a definição inteira do campo em
_f.*viaset_variable_dot('_f', $def); todo atributo do.metafica disponível automaticamente no template - Define variáveis calculadas por cima:
_f.key,_f.title,_f.value,_f.model,_f.required,_f.ai,_f.bg - Passa para
[#field-{type}#], o template desse tipo de campo
_f.model é a expressão do Alpine.js para x-model, calculada como {store}.{field}. O armazenamento padrão é form_data. Em campos i18n ela vira form_data.{field}[{lang}].
Variáveis _f.* padrão disponíveis em todo template de campo:
| Variável | Conteúdo |
|---|---|
_f.key |
Nome do campo / atributo name do HTML |
_f.title |
Rótulo (de name no .meta) |
_f.value |
Valor pré-preenchido |
_f.model |
Expressão x-model do Alpine, por exemplo form_data.email |
_f.required |
Se o campo é obrigatório |
_f.bg |
Classe da cor de fundo do rótulo flutuante |
_f.* (qualquer) |
Todas as outras chaves da definição do campo: _f.accept, _f.options, _f.resource etc. |
form_data: o store do Alpine.js
form_data é o objeto reativo do Alpine.js que guarda todos os valores atuais dos campos. Ele é declarado no elemento <form>. Cada campo grava seu valor ali via x-model="[#_f.model#]".
No envio, form_data é colocado no payload da API e enviado por POST para /api/v1/{resource}. Campos com editor rico (HTML, gallery, image) gravam seus valores por um mecanismo separado (nb.edit.get_field_values()), que é combinado automaticamente; os templates de campo não precisam cuidar disso.
O template de campo mais simples
field-default/index.tpl é a base dos campos de texto:
<div class="[#_f.wrapper_class#]">
<input type="[#_f.type#]" value="[#_f.value#]" name="[#_f.key#]"
x-init="[#_f.model#]=`[#_f.value#]`"
x-model="[#_f.model#]"
[#if _f.required=(not-empty) echo=required#]
class="input input-bordered w-full" />
<label class="pointer-events-none absolute left-3 -top-2.5 px-1
font-bold text-sm leading-tight [#get _f.bg default=bg-neutral-50#]">
[#_f.title#][#if _f.required=(not-empty) echo=" *"#]
</label>
</div>
Acrescentando um novo tipo de campo
-
Crie o template:
core/modules/forms/tpl/field-{type}/index.tpl ← core types ext/tpl/field-{type}/index.tpl ← project-specific types -
No template:
- Ligue ao Alpine via
x-model="[#_f.model#]" - Defina o valor inicial com
x-init="[#_f.model#]='[#_f.value#]'" - Use
[#_f.key#]como atributonamedo HTML - Acesse opções específicas do tipo via
_f.*(por exemplo[#_f.accept#]para restrições de arquivo)
- Ligue ao Alpine via
-
Use o nome do tipo no
.meta; ele funciona assim que o template existe. -
Se o campo gerencia um estado complexo (como um seletor de arquivo ou um botão do navegador de mídia), aninhe um
x-datapróprio dentro dox-datado formulário. Oform_dataexterno continua acessível a partir dos escopos aninhados.
Campos próprios usam a convenção de template field-{type} e o contexto _f.* (_f.model, _f.key, _f.title, _f.bg etc.). Templates de campo de uma geração anterior, com _fmodel, _fid, _ftitle, _fbg, _bf_render_field() ou atributos data-te-* do Tailwind Elements, são refeitos nessa forma em vez de mantidos.
Campos aninhados e repetidores precisam gerenciar explicitamente os caminhos de modelo aninhados do Alpine. Por exemplo, um campo group que guarda locations deve ligar os campos filhos a caminhos como form_data.locations[ix].location, ou passar um modelo explícito ao reutilizar render_field(). Não suponha que o renderizador do core consiga deduzir caminhos de arrays aninhados a partir de uma chave de campo plana.