Profile sections
Configuration/ describes a profile in six
top-level maps. It ships with academic_persons, which owns the
records and their TCA, and it is the one file the backend record editor, the
public detail view and the editing frontend of EXT:academic_persons_edit read.
| Map | Describes |
|---|---|
profile
| The public detail layout (
structure
and
details
),
and every directly editable profile property with its section,
control and validators. |
special
| The components of the editing frontend that are not one property: the composed display name, the image and the synchronisation switch. |
contracts
| The contract fields, and the address, email and phone sections a contract owns. |
document | The sortable lists attached to a profile: the seven timeline entry types and the contracts. |
frontend | Which
fe_ column feeds which property when profiles are
synchronised from frontend users, see
Frontend user synchronisation. |
managed | Which fields are read-only in the backend on the records a synchronisation wrote, see Managed fields. |
The order of every map and list is preserved and is what the editing frontend renders. The validator flags are documented on their own page.
Attention
The syntax of this file is still considered experimental and may change in a future release.
The profile map
Two keys describe the public layout, everything else is a field:
profile:
structure:
left:
- menuSections
right:
- headline
- position
- profileImage
- contact
- subline
- profileEntries
- menuSectionsDatas
details:
headline:
- title
- firstName
- middleName
- lastName
subline: 'LLL:EXT:academic_persons/Resources/Private/Language/locallang.xlf:detail.subline'
gender:
section: information
fieldType: select
renderType: select
validators:
- required
firstName:
section: information
fieldType: input
renderType: text
validators:
- readonly
- disabled
helptext: 'LLL:EXT:academic_persons/Resources/Private/Language/locallang.xlf:helptext.firstName'
miscellaneous:
section: aboutme
fieldType: textarea
renderType: ckeditor
characterLimit: 1000
validators:
- html
structure- The layout columns and the ordered elements in each column. The shipped
detail template renders
leftas the desktop navigation andrightas the main content; on mobile, theleftelements are inserted again directly beforesubline. details- Per element, the ordered profile properties, the relation map, the label
reference or the special renderer it renders. Supported elements are
menu,Sections headline,position,profile,Image contact,subline,profileandEntries menu; an unknown element renders nothing.Sections Datas positionandcontacttake the special rendererspecial: datas, and choose their contracts withFrom Contracts contractsandonly- see The contracts of the position and contact blocks.Valid positionalso lists what its line shows, see What the position line shows.menulists stable navigation identifiers andSections menumaps each of them to the profile relation it shows.Sections Datas
The contracts of the position and contact blocks
A block rendered with
special: datas chooses which of the
profile's contracts it renders. The shipped file states the defaults:
profile:
details:
position:
special: datasFromContracts
contracts: all
onlyValid: false
fields:
- position
contact:
special: datasFromContracts
contracts: all
onlyValid: false
contractsallrenders every contract,firstonly the first in the editor's order thatonlyleaves. Anything else isValid all.onlyValid trueleaves out the contracts that have ended or not started yet, and limits the page cache lifetime as described in The page cache follows the validity. A boolean, or a value PHP reads as one (1,'true','yes','on'); anything else isfalse.
The two blocks are configured one by one, so a profile page may list every position and the contact data of the first contract only. The unit and function type filter of the list elements has no counterpart here: the detail view shows one profile, not a restricted list. See Which contracts a profile shows for how the options of the content elements relate.
What the position line shows
profile. lists what the position line shows of
each contract, in this order. Three values are accepted:
position- The position text of the contract.
functionType - The name of the contract's function type. A profile with the gender
msgets the female name and one withmrthe male name, where the function type has one. Every other profile, and a function type without the gendered name, gets the general name. organisationalUnit - The display text of the contract's organisational unit, or its unit name where the display text is empty.
The shipped value is
[position]
, the line as it was before the key
existed. Other values are dropped, and a list that keeps none of the three is
the shipped value. A contract that has none of the listed values gets no line.
Settings files merge key by key, so a site package that wants the function type next to the position states only the list:
profile:
details:
position:
fields:
- position
- functionType
Each value is rendered in an element of its own, an ace- with the
class of its field: ace-, ace- or
ace-. The values of one contract share one line,
ace-. The stylesheet of the site separates
them, the example of How the layout is rendered with a
comma.
How the layout is rendered
The shipped Resources/Private/Templates/Profile/Detail.html receives
the two keys as public and dispatches every identifier of
structure
to a partial of the same name below
Resources/:
| Element |
details
entry |
Renders |
|---|---|---|
menu | Ordered navigation identifiers | One link per identifier whose relation has records |
headline
| Ordered profile properties | The non-empty ones as the parts of the heading |
position
|
special: datas | The values
fields
lists of every contract
contracts
and
only select |
profile | Ordered image properties | Every non-empty one, in an ace- |
contact
|
special: datas | Email addresses, phone numbers, postal addresses, location with
room, and office hours of every contract
contracts
and
only select, see
Office hours in the contact block |
subline
| An LLL: reference | The translated heading, and the point before which the
left
elements are repeated below the large breakpoint |
profile | Ordered rich text properties | The non-empty ones as fold-out entries |
links
| Ordered link properties | The non-empty ones, each with its companion title property
(
website
with website) as the link text |
menu | Navigation identifier to relation map | One timeline section per identifier whose relation has records |
Overriding a partial changes how an element renders, overriding
profile
changes what renders and where. The years of a timeline entry
are printed as they are stored - a single year, a range, or an open range
prefixed with a "since" or "till" label - and nothing about them is locale
dependent.
Below the large breakpoint the elements of the
left
column are
rendered a second time, directly before the
subline
element of the
right
column. A layout without
subline
in
right
therefore has no mobile navigation.
The view is a content element and renders no <main>, no <aside> and no
<h1> - a page may carry two profile plugins, and those belong to the page
template. Its headings start at <h2> for the headline, with the block
headings one level below it.
The template loads the module @fgtclb/
through the asset collector.
The module toggles the fold-out entries, keeps the sticky navigation below a
page header with the id page- and, when the site loads Bootstrap,
marks the section in view through its ScrollSpy. The icons of the contact rows
and the fold-out entries are the shared identifiers
tx-, tx-,
tx-, tx-,
tx-, tx- and
tx-. They are frontend icons, registered in
the Configuration/ of academic_base and
rendered by its ab: ViewHelper. A site package that depends on
academic_base replaces a glyph by registering the identifier in its
own Configuration/, an entry in its
Configuration/Icons.php does not reach the detail view. The
replacement applies wherever an academic extension renders the identifier. To
replace an icon on the profile only, override the partial and render an
identifier of the site package. The icons are Font Awesome Free icons, see Third-party icons.
The extension ships no stylesheet, the site package styles the view through its
speaking ace-* classes, see The profile detail. Two parts of the view
depend on rules of that stylesheet: a fold-out entry renders its expand and its
collapse glyph and the stylesheet shows the one that matches its
aria- state, and the navigation of the
left
column is
only sticky when a rule makes it so. The shipped icons carry a size of their
own, 1em. A replacement drawing without a width and a height of its own needs
a rule that sizes the icon, as the example below sizes it to its container. The
module keeps a sticky navigation below the page header and writes the offset to
-- on the root element.
The mono repository the extension is developed in carries an example to start
from, the stylesheet of its development instances:
_academic-persons.scss of EXT:academics_dev_site.
It themes the view through custom properties declared on the
.academic- root element, and touches nothing outside that
element. The development versions of 3.0 shipped it with the extension, see
Breaking: The profile views ship no stylesheet.
Note
A theme that wraps its content sections in overflow: hidden clips a
sticky navigation. Lift it in the site's stylesheet on the wrapper that has
it, for example:
body:has(.academic-persons-detail) .my-theme-section {
overflow: unset;
}
Office hours in the contact block
A contract with office hours gets a row of its own in the contact block, after
the location and room, with the label "Office hours" (detail.).
A contract without them gets no row. The row carries the classes
ace-, so a site that does not want it hides it in
its stylesheet.
The editor of EXT: stores office hours as HTML, the
backend form and an import as plain text. The row turns line breaks into
<br> and then passes the value through the core HTML sanitizer, the
default build of
<f:. Paragraphs, lists, emphasis and
links are kept. Event handler attributes are removed, and an element the
sanitizer does not allow, a script among them, is printed as escaped text and
never runs. A plain text value keeps its lines. HTML from the editor carries no
line breaks between its blocks, so it renders as it was written.
Plain text is read as HTML as well. A < in it starts a tag for the
sanitizer, so 10: loses the < and Room <A 1. renders
as an empty link. Write such values without angle brackets.
The contract fields of the list, list and detail, card, selected profiles and
selected contracts elements, and of the contacts element of
EXT:, render office hours the same way, when office
hours are among their fields to show.
What an override of the detail template loses
Until 2.4 Templates/ was the view: it rendered the
image, the contact data and every timeline section itself. Since 3.0.0 it is a
dispatcher over the
structure
map, and the eleven partials below
Partials/ are what renders.
A project that overrides the template keeps rendering its own copy. Nothing looks broken, and two things are silently gone:
- The configurable layout.
profile.andstructure profile.are handed to the template asdetails publicand are read by the new partials only, so changing them has no effect at all while the old template renders.Profile - Three partials the detail view no longer renders.
Partials/andProfile/ Header. html Partials/are still shipped and still rendered - by the list and card views, and by the profile editing view of academic_persons_edit - so an override of one of them made for the detail view no longer reaches it.Profile/ Section Header. html Partials/had the detail view as its only caller and is deleted: a project template that still rendersProfile/ Data Header. html Profile/fails at render time rather than rendering nothing. Breaking: The partials of the detail view change has the migration.Data Header
Adopt the new template instead, and move the project's changes into the partial of the element they belong to: they are one file per element, and overriding one of them is what How the layout is rendered describes.
The fields
Every other key is a field, and fields share one shape across
profile
,
contracts. and
contracts.:
| Key | Meaning |
|---|---|
section
| Profile fields only. Fields with the same section are grouped and rendered together, in file order; the first field of a section decides where the section appears. |
property | The domain and form data property, when it differs from the key. Optional. |
field | The database column, when it differs from the underscored property name. Optional. |
field |
input
,
select
,
textarea
or
check
.
Describes the frontend control; the TCA column keeps the type its
TCA file declares. |
render | The renderer of the editing frontend:
text
,
select
,
checkbox
,
email
,
phone
,
date
,
combined or
ckeditor
. |
validators
| The flag list. |
character | Rich text fields (
render) only: the maximum
number of readable characters. Checked on the server, never copied
into the TCA. |
helptext
| An LLL: reference rendered next to the control; for
contract and contact fields also literal text. A translation domain
reference of TYPO3 v14 does not resolve here, see
Labels. |
autocomplete
| Contract and contact fields only: an HTML autocomplete token. |
options
| Contract selects only:
organisational,
function or
locations
. |
custom
| Profile fields only:
true
declares a project field, a
column a site package adds to the profile table and makes
editable in the profile editor. Its
field is required,
and its key is its property name. See project fields
of academic_persons_edit. |
A field is dropped silently when it has no section (profile fields), no
field or no
render. Removing a field from the file
removes it from the editing frontend and from the validation; it never removes
a column or stored data. Apart from a project field, the settings describe
columns and properties the extensions ship and create none.
The special map
special:
title:
type: special
renderType: title
fields:
- title
- firstName
- middleName
- lastName
image:
type: special
renderType: cropper
skipSync:
type: special
fieldType: check
renderType: checkbox
hidden:
type: special
fieldType: check
renderType: checkbox
title
composes the display name from the listed profile properties,
image
is the profile image,
skip the switch that keeps
a profile out of the synchronisation from its frontend user, and
hidden
the owner's switch Show my profile publicly, see
Profiles that are not public. A special entry
with a
field and without composed
fields
addresses one
profile column directly and takes part in the profile validation; the other
two do not.
The contracts map
contracts:
label: 'LLL:EXT:academic_persons/Resources/Private/Language/locallang_tca.xlf:tx_academicpersons_domain_model_profile.columns.contracts.label'
type: contracts
fieldName: contracts
rowFields:
- position
actions:
- view
- down
- up
- delete
- edit
fields:
position:
fieldType: input
renderType: text
validators:
- required
organisationalUnit:
fieldType: select
renderType: select
options: organisationalUnits
validFrom:
fieldType: input
renderType: date
validators:
- required
- date
contactSections:
emailAddresses:
fields:
emailAddress:
propertyName: email
fieldName: email
fieldType: input
renderType: email
autocomplete: email
validators:
- required
- email
emailAddressType:
propertyName: type
fieldName: type
fieldType: select
renderType: select
fields
are the contract fields in editor order. The three contact
sections -
physical,
email and
phone - each carry their own
fields
map. Their keys
are unique across the file, which is why
email names the
email property and column and each <section>Type key names the
type property of its own record.
label
,
type
,
field,
row and
actions
complete the
contracts
entry of the document sections
below.
The document sections
documentSections:
contracts:
type: contracts
publications:
label: 'LLL:EXT:academic_persons/Resources/Private/Language/locallang_tca.xlf:tx_academicpersons_domain_model_profile.columns.publications.label'
type: publication
fieldName: publications
rowFields:
- year
- title
actions:
- view
- down
- up
- delete
- edit
validators:
title:
- required
link:
- url
from:
- number
to:
- number
year:
- required
- number
description:
editor:
limit: 500
type: ckeditor
Each key is a stable section identifier; the map order is the display order.
| Key | Meaning |
|---|---|
label
| An LLL: reference for the section heading. |
type
| The record type of the rows, i.e. the type of the profile
information records.
contracts
is the reserved value for
the contract section, which takes everything it does not declare
from the top-level
contracts
map. |
field | The profile relation the rows hang off. |
readonly
|
true
disables creation and every mutating action; the
section still offers view. |
row | The values shown in a compact row, in order. Timeline entries
support from, to, year, title and description;
contracts support from, to and position. |
actions
| The actions offered per row, in order: view, down, up,
delete and edit. An action not listed is not available.
Listing both up and down also enables drag sorting. |
validators
| A map from field to flag list, or to a map with
validators
,
individual <flag>: true entries and an
editor
block.
editor. implies the html flag and takes a
readable-text
limit
;
editor. implies
textarea. The contract section validates against
contracts. instead. |
helptext
| A map from field to an LLL: reference or literal text. |
Warning
type
and
field describe the editing frontend. The seven
profile relations, and the record type each of them selects, are declared
by the TCA of the profile table since 3.0.0 and are not generated from
this file any more. Renaming either of them for one of the seven shipped
sections therefore leaves a backend inline column that stores one record
type and a frontend editor that writes another - the records created in one
context are invisible in the other. A section of an own record type needs
its own column in a TCA override of the profile table; the loop over the
seven relations in
Configuration/TCA/tx_academicpersons_domain_model_profile.php is the
template for it.
The validators of a timeline section address the record type of that section
only: a required title of publications does not make the title of a lecture
required, neither in the editing frontend nor in the backend, where the flags
land in the columns of that record type. The field keys from,
to and description are aliases of the year, year and
bodytext properties (columns year_, year_ and
bodytext); year addresses the year property and column.
Unknown row fields and actions are discarded, as are duplicates; both lists are matched without regard to case.
Overriding the file
The file is collected from all installed extensions: every package that
contains Configuration/ contributes, and
the package loaded later wins per key. The files are merged recursively: a
map is merged key by key at any depth, so a site package states only what it
changes and keeps every entry it does not name - including the entries a later
academic_persons release adds.
Four rules decide what happens to a value, and they hold at every depth:
| The later file has | Result |
|---|---|
| a map | merged key by key with the earlier map |
| a list | replaces the earlier list as a whole, an empty list included |
| a value of another type | replaces the earlier value |
null
(
~
) | removes the key, as if no package had configured it |
A list is replaced rather than combined because the entries of a flag list have
no identity to merge by: an override that could only add entries could never
drop
required
. A YAML map whose keys happen to be 0 to n- is a
list as well, and an empty map,
{}
, is the same empty array as an empty
sequence - it clears a map the way
[]
clears a list.
The key order of a merged map is the order of the later file when that file names every key of the earlier map; otherwise the earlier order stays and the keys only the later file names are appended. A file that names a map completely therefore decides the display order - and stops deciding it as soon as a later academic_persons release adds an entry the file does not name, which is the moment to add that entry to the file.
To change the shipped configuration:
- Add
Configuration/to your site package.Academic Persons/ Settings. yaml - Make the site package depend on academic_persons in its
composer.orjson ext_, so that it is loaded after it.emconf. php -
Name the keys that differ from
EXT:, and nothing else:academic_ persons/ Configuration/ Academic Persons/ Settings. yaml profile: # one flag list; the layout, the other fields and every other key of # this field stay as shipped title: validators: - required # a field the installation does not want at all middleName: ~ documentSections: # one label; the record type, relation, rows and actions stay lectures: label: 'LLL:EXT:my_site/Resources/Private/Language/db.xlf:lectures'Copied! - Flush the TYPO3 caches. The normalised graph is cached in the core cache.
Note
An entry is not removed by leaving it out - leaving it out means "do
not change it", at every level. Set the key to
~
to remove it, and
a flag list that is to be empty to
[]
. An override written before
3.0, which removed entries by restating a map without them, has to be
migrated - see Breaking: Settings files merge recursively.
To see what an override changes, run
vendor/. It prints,
for every package after academic_persons, the smallest file with
the same effect - replacing the package's file with it changes nothing - and
names, as comments, the entries a map the package copied leaves out and
therefore inherits. The Status report of EXT:reports lists the same
entries, and the ones a package removes with
~
, under
Academic Persons. See Feature: Settings overrides are reported and shrunk.
There is no TypoScript and no site set equivalent for these settings.
Note
The backend record editor reads the same maps. Unlocking a field for the editing frontend, or requiring one, changes the backend form of that record the same way.