Profile sections 

Configuration/AcademicPersons/Settings.yaml 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.
documentSections The sortable lists attached to a profile: the seven timeline entry types and the contracts.
frontendUserSync Which fe_users column feeds which property when profiles are synchronised from frontend users, see Frontend user synchronisation.
managedFields 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.

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
Copied!
structure
The layout columns and the ordered elements in each column. The shipped detail template renders left as the desktop navigation and right as the main content; on mobile, the left elements are inserted again directly before subline.
details
Per element, the ordered profile properties, the relation map, the label reference or the special renderer it renders. Supported elements are menuSections , headline , position , profileImage , contact , subline , profileEntries and menuSectionsDatas ; an unknown element renders nothing. position and contact take the special renderer special: datasFromContracts , and choose their contracts with contracts and onlyValid - see The contracts of the position and contact blocks. position also lists what its line shows, see What the position line shows. menuSections lists stable navigation identifiers and menuSectionsDatas maps each of them to the profile relation it shows.

The contracts of the position and contact blocks 

A block rendered with special: datasFromContracts 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
Copied!
contracts
all renders every contract, first only the first in the editor's order that onlyValid leaves. Anything else is all.
onlyValid
true leaves 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 is false.

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.details.position.fields 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 ms gets the female name and one with mr the 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:

EXT:my_sitepackage/Configuration/AcademicPersons/Settings.yaml
profile:
  details:
    position:
      fields:
        - position
        - functionType
Copied!

Each value is rendered in an element of its own, an ace-value with the class of its field: ace-position, ace-function-type or ace-organisational-unit. The values of one contract share one line, ace-attribute ace-position-line. 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 publicProfile and dispatches every identifier of structure to a partial of the same name below Resources/Private/Partials/Profile/PublicProfile/:

Element details entry Renders
menuSections 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: datasFromContracts The values fields lists of every contract contracts and onlyValid select
profileImage Ordered image properties Every non-empty one, in an ace-profile-image
contact special: datasFromContracts Email addresses, phone numbers, postal addresses, location with room, and office hours of every contract contracts and onlyValid select, see Office hours in the contact block
subline An LLL:EXT: reference The translated heading, and the point before which the left elements are repeated below the large breakpoint
profileEntries 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 websiteTitle) as the link text
menuSectionsDatas 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/academic-persons/frontend/profile.js through the asset collector. The module toggles the fold-out entries, keeps the sticky navigation below a page header with the id page-header 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-academicbase-info-email, tx-academicbase-info-phone, tx-academicbase-info-location, tx-academicbase-info-room, tx-academicbase-info-time, tx-academicbase-action-expand and tx-academicbase-action-collapse. They are frontend icons, registered in the Configuration/FrontendIcons.php of academic_base and rendered by its ab:icon ViewHelper. A site package that depends on academic_base replaces a glyph by registering the identifier in its own Configuration/FrontendIcons.php, 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-expanded 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 --academic-persons-detail-scroll-offset 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-persons-detail 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.

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.officeHours). A contract without them gets no row. The row carries the classes ace-attribute ace-office-hours, so a site that does not want it hides it in its stylesheet.

The editor of EXT:academic_persons_edit 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:sanitize.html> . 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:00 < 12:00 loses the < and Room <A 1.23> 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:academic_contacts4pages, 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/Profile/Detail.html 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/Profile/PublicProfile/ 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.structure and profile.details are handed to the template as publicProfile and are read by the new partials only, so changing them has no effect at all while the old template renders.
  • Three partials the detail view no longer renders. Partials/Profile/Header.html and Partials/Profile/SectionHeader.html 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. Partials/Profile/DataHeader.html had the detail view as its only caller and is deleted: a project template that still renders Profile/DataHeader fails at render time rather than rendering nothing. Breaking: The partials of the detail view change has the migration.

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.fields and contracts.contactSections.<section>.fields :

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.
propertyName The domain and form data property, when it differs from the key. Optional.
fieldName The database column, when it differs from the underscored property name. Optional.
fieldType input , select , textarea or check . Describes the frontend control; the TCA column keeps the type its TCA file declares.
renderType The renderer of the editing frontend: text , select , checkbox , email , phone , date , combinedLink or ckeditor .
validators The flag list.
characterLimit Rich text fields ( renderType: ckeditor ) only: the maximum number of readable characters. Checked on the server, never copied into the TCA.
helptext An LLL:EXT: 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: organisationalUnits , functionTypes 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 fieldName 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 fieldType or no renderType . 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
Copied!

title composes the display name from the listed profile properties, image is the profile image, skipSync 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 fieldType 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
Copied!

fields are the contract fields in editor order. The three contact sections - physicalAddresses , emailAddresses and phoneNumbers - each carry their own fields map. Their keys are unique across the file, which is why emailAddress names the email property and column and each <section>Type key names the type property of its own record.

label , type , fieldName , rowFields 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
Copied!

Each key is a stable section identifier; the map order is the display order.

Key Meaning
label An LLL:EXT: 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.
fieldName The profile relation the rows hang off.
readonly true disables creation and every mutating action; the section still offers view.
rowFields 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.type: ckeditor implies the html flag and takes a readable-text limit ; editor.type: textarea implies textarea. The contract section validates against contracts.fields instead.
helptext A map from field to an LLL:EXT: reference or literal text.

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 columnsOverrides of that record type. The field keys from, to and description are aliases of the yearStart, yearEnd and bodytext properties (columns year_start, year_end 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/AcademicPersons/Settings.yaml 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-1 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:

  1. Add Configuration/AcademicPersons/Settings.yaml to your site package.
  2. Make the site package depend on academic_persons in its composer.json or ext_emconf.php, so that it is loaded after it.
  3. Name the keys that differ from EXT:academic_persons/Configuration/AcademicPersons/Settings.yaml, and nothing else:

    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!
  4. Flush the TYPO3 caches. The normalised graph is cached in the core cache.

To see what an override changes, run vendor/bin/typo3 academic:persons:settings:migrate --delta . 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.