Profile editor and validation
academic- is the
canonical settings source for academic_persons and
academic_persons_edit. It contains one ordered profile schema and
the related inline maps:
profile- The public detail layout together with direct Profile fields grouped into
visual sections. The
structureanddetailskeys configure public rendering; the remaining entries define editable fields and their shared validation metadata. special- Composed or dedicated components such as the title, image and sync switch.
contracts- The reusable Contract document type. Its ordered
fieldsmap drives the Contract editor;contactcontains the physical-address, email and phone editors and their respective ordered fields.Sections documentSections - Ordered structured collections. The Contract entry only references
type: contracts; ordinary profile-information entries remain inline.
All consumers receive the same normalized settings graph. This keeps public
rendering, profile editing, frontend validation and the corresponding backend
TCA state aligned. Public layout stays below
profile
; the other maps
remain technical sections in the same file.
Loading and overrides
The central factory reads the same relative path from every active package and
merges the maps recursively. A site package can therefore override the shared
configuration by providing
Configuration/ that names the keys it
changes and nothing else. A list - a
validators
list, a
structure
column - is replaced as a whole, and
~
removes a key;
an entry left out is kept as shipped. The overriding the file
section of academic_persons has the complete rules.
Flush TYPO3 caches after a change so the unified typed settings graph and its cache entry are rebuilt.
Field validators
Regular fields declare an ordered list of flags:
profile:
website:
section: information
fieldType: input
renderType: combinedLink
validators:
- url
Supported flags are:
| Flag | Effect |
|---|---|
required | Adds Not plus the frontend HTML, marker and JSON
metadata. |
readonly | Prevents editing in the frontend editor. A submitted value is ignored. |
frontendreadonly | Prevents editing in the frontend editor like readonly, and keeps
the field editable in the TYPO3 backend. |
disabled | Disables editing and implies readonly. A locked field can never
remain required. |
email | Adds Email and email input metadata. |
url | Adds Url and URL input metadata. |
number, tel and date | Select the matching frontend input type. date is the exception
to that: it selects the date field type, which the profile editor
renders as a plain text control showing d.. A date picker is
deliberately not shipped yet, and the native
<input type="date"> is not used - see
the contract dates. |
textarea and html | Select text-area input; html also activates sanitized rich text. |
Rules remain attached to the configured profile, contact or document section. They are not collected from a sibling section. Only submitted fields are validated during a partial AJAX update.
Profile CKEditor character limit
A profile field configured as CKEditor may declare its character limit directly on the field:
profile:
miscellaneous:
section: aboutme
fieldType: textarea
renderType: ckeditor
characterLimit: 1000
validators:
- html
A positive integer character adds a live current / limit counter
and prevents the editor from accepting additional visible characters beyond
the limit. The partial AJAX update is checked independently by the same
server-side Extbase validation. HTML tags do not count. The property is ignored
when render is not ckeditor or its value is invalid or non-positive.
The key is case-sensitive; characterlimit is not normalized.
This deliberately differs from document descriptions, which keep their
existing nested editor. schema. Both forms normalize to the same typed
validation metadata. Character limits do not alter backend TCA or the database
schema.
Document validators and aliases
Document aliases map presentation names to DTO and database properties:
| Settings key | DTO property | Domain/database field |
|---|---|---|
from | year | year_ |
to | year | year_ |
contracts. | valid | valid_ |
contracts. | valid | valid_ |
year | year | year |
description | bodytext | bodytext |
The shipped year rules are deliberately dynamic:
documentSections:
cooperation:
validators:
from:
- number
to:
- number
year:
- required
- number
Consequently year receives a required attribute and marker while from
and to remain optional. Removing or adding required in a site override
changes the JSON metadata, the rendered controls, the Extbase validation and the corresponding
backend TCA field state together; no field name is hard-coded as mandatory.
The richer description form remains supported:
description:
editor:
limit: 500
type: ckeditor
editor. is normalized to the html validation/input
metadata so the editor and the server side sanitizer agree. A positive integer
editor. additionally defines the maximum number of visible
characters. HTML tags do not consume that allowance; entities, non-breaking
spaces and repeated whitespace are normalized before counting. The editor
returns the limit in its JSON field metadata, displays a live current / limit
counter and prevents CKEditor from accepting further characters beyond it.
Both the document JSON actions and the Extbase form-data validator enforce the
same limit on the server.
editor. is frontend validation metadata, not TCA configuration. It is
ignored for non-CKEditor controls, and removing it or setting it to a non-
positive value disables both the counter and the additional validation without
changing backend FormEngine.
Project fields
A column a site package adds to the profile table can be edited in the profile
editor. The site package ships the column itself, its SQL and its TCA, and
declares it below
profile
as a project field with
custom: true
:
CREATE TABLE tx_academicpersons_domain_model_profile (
tx_mysitepackage_name_prefix varchar(30) DEFAULT '' NOT NULL
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
'tx_academicpersons_domain_model_profile',
[
'tx_mysitepackage_name_prefix' => [
'label' => 'LLL:EXT:my_sitepackage/Resources/Private/Language/locallang_db.xlf:profile.name_prefix',
'config' => ['type' => 'input', 'max' => 30],
],
],
);
profile:
namePrefix:
custom: true
section: information
fieldName: tx_mysitepackage_name_prefix
fieldType: input
renderType: text
validators:
- required
The identifier,
name here, is the name the editor submits the value
under. It must not be a property of the profile model, and a
property is ignored.
field names the column and is
required. The field appears after the shipped fields of its section.
The column has to be in the TCA of the profile table with the type input,
text, email, link, number or check. It must be neither a
system column, such as the language column or the column that hides the
profile, nor a column of the shipped profile model. A column a project maps in
an XCLASS of the model is not a column of the shipped model and can be used.
The renderer has to fit the column:
| TCA type of the column | Renderer and validators |
|---|---|
input, number | text, textarea or a renderer of an input type, such as
phone |
text | text, textarea or ckeditor |
email | The email validator, which the DataHandler would otherwise apply
after the other fields of the request are stored |
link | The url validator, for the same reason, and allowed
that include url. The field takes web addresses, http and
https, and no other link of TYPO3 |
check | checkbox, and no other column takes it |
select and combined are not available. A checkbox shows
Yes or No, labels that are overridden like every other
label of the editor, see Labels.
A project field is validated, limited and sanitised like any other field with
the same configuration, in the same pass, so an invalid value stores nothing of
the request. Its validators reach the backend form of the column as well, a
required
project field is required there too. The flags
readonly
,
frontendreadonly
and
disabled
and the
managed map lock it like any other field.
The editor reads the value from the row of the edited language and writes it
there, through the DataHandler: a translation keeps its own value, and the
change gets a history entry. A column with l10n_ is written to
the default-language record instead, from which every translation takes it. A
column with allow keeps the value a translation is
given as the translation's own, as the backend does when an editor types one.
The value is written after the regular fields of the same request and before the
update is announced, so the translation synchronisation sees it, and the answer
carries the value as it was stored. An update made in a translation is not
announced, as for every other field. That holds for a shared column written to
the default-language record as well, which the DataHandler carries into the
translations itself. A workspace preview cannot write a project field and is
answered with 409.
The two writes of one request are not one transaction. A value that passed the
validation and is refused by the DataHandler nonetheless, by a hook of the
installation for example, is answered with 500 and logged, and the regular
fields of the request stay stored.
The label is
profile.<identifier>. of the editor, set like any
other label, see Labels:
plugin.tx_academicpersonsedit._LOCAL_LANG {
default.profile.namePrefix.label = Name prefix
de.profile.namePrefix.label = Namenszusatz
}
A column that cannot be used raises a deprecation notice while the TCA is
compiled, which names the field, the column and the reason. The backend and
the install tool keep working, the settings of the field are not applied to the
TCA, and a test run that fails on deprecations fails on it. The profile editor
fails with an exception carrying the same message whenever it renders the
page, and answers a request writing the field with 500 and the error
invalid_. Where deprecation notices are not logged, that
exception is what points to the mistake.
Contract form and contact sections
The order of
contracts. is the form order returned by the JSON
endpoint. Every entry declares its frontend field and render type, validation,
option source and helptext together. The shipped organisational,
function and locations option sources resolve their records
through the corresponding repositories. Removing or reordering an entry
therefore removes or reorders that control without changing the template.
Physical addresses, email addresses and phone numbers are ordered structural
children below
contracts.. Each child owns an ordered
fields map and an isolated validation set:
contracts:
type: contracts
fields:
position:
fieldType: input
renderType: text
validators:
- required
organisationalUnit:
fieldType: select
renderType: select
options: organisationalUnits
contactSections:
physicalAddresses:
fields:
country:
fieldType: input
renderType: select
autocomplete: country
helptext: 'LLL:EXT:site/Resources/Private/Language/locallang.xlf:address.country.helptext'
validators:
- required
emailAddresses:
fields:
emailAddress:
propertyName: email
fieldType: input
renderType: email
autocomplete: email
phoneNumbers:
fields:
phoneNumber:
fieldType: input
renderType: phone
autocomplete: tel
documentSections:
contracts:
type: contracts
The shipped physical-address country control obtains its localized labels and
ISO alpha-2 values from TYPO3's Country. Keeping field as
input preserves the domain extension's existing backend TCA while
render selects the frontend control and its option validation.
Every Contract and contact field helptext is rendered as a Bootstrap popover
in add/edit mode.
The shipped autocomplete tokens are street-, postal-,
address-, country, email and tel. They describe the
purpose of the corresponding control without changing validation or storage.
Backend TCA integration
The domain extension still owns the base TCA and the column configuration. It applies the normalized validation metadata from the unified
settings graph to the relevant Profile, contact and Profile-information TCA
fields. Consequently required, readonly and field-type metadata remain
consistent between frontend validation, profile editing and FormEngine in
TYPO3 13 and TYPO3 14. Character limits remain frontend/server-side metadata
and do not change the database schema.
Year row
year, year and year each receive col-. They
therefore stack on small screens and share one row from the medium breakpoint.
Each is an <input type="number"> carrying the bounds of its TCA range
as min, max and step.