Templates 

This extension ships Fluid partials the academic extensions share: the responsive image they render their images through, and the fields of a frontend form. Their paths and arguments are public API, and change only with a breaking changelog entry.

The responsive image partial 

EXT:academic_base/Resources/Private/Partials/Academic/Image.html renders one image of a record for the frontend:

  • a raster image as a <picture> with one WebP <source> per breakpoint of the preset, and a fallback <img> in the original format that loads lazily and states its width and height;
  • an SVG image as one <img> of the original file, without sources and without processing;
  • the placeholder as one <img> when there is no image, and nothing when there is no placeholder either.

A template of an academic extension renders it like this, here the card of EXT:academic_persons, Partials/Profile/Item/Image.html, with the settings that choose the crop variant of its view and the placeholder:

<f:render
    partial="Academic/Image"
    arguments="{
        image: profile.image,
        preset: 'card',
        cropVariant: '{settings.image.{imageView}.cropVariant}',
        placeholder: placeholder
    }"
/>
Copied!

For a raster image of the development instances, that renders, shortened to the elements and their attributes:

<picture class="ace-picture">
    <source srcset="/fileadmin/_processed_/0/5/csm_profile-01_1d3403aae7.webp" type="image/webp" media="(min-width: 992px)" />
    <source srcset="/fileadmin/_processed_/0/5/csm_profile-01_99f8b09a62.webp" type="image/webp" media="(min-width: 768px)" />
    <source srcset="/fileadmin/_processed_/0/5/csm_profile-01_395eaf11e8.webp" type="image/webp" media="(min-width: 576px)" />
    <source srcset="/fileadmin/_processed_/0/5/csm_profile-01_dfbfe7773a.webp" type="image/webp" />
    <img class="ace-image " loading="lazy" src="/fileadmin/…/profile-01.png" width="600" height="800" alt="Portrait of Jane Doe" title="Jane Doe" />
</picture>
Copied!

The fallback <img> is the original file here, because it is narrower than the 690 pixels of the preset, and an image is never scaled up. The card passes no class of its own, so the image carries ace-image alone, followed by the space the empty argument leaves. The alternative text and the title are those of the file reference. The template of the persons card picks the crop variant of its view and a placeholder per gender before it renders the partial, see the Profile image chapter of EXT:academic_persons.

Arguments 

Argument Meaning
image An Extbase or a core file reference. Empty renders the placeholder.
preset card, detail, logo or teaser. Required: an unknown preset fails the rendering instead of silently rendering no image.
cropVariant The crop variant applied to every source and to the fallback image, default when empty. A variant without a crop area on the image renders the image uncropped.
placeholder An EXT: path to a public file, rendered when there is no image. Empty renders nothing. A path that does not resolve fails the rendering, as <f:image> does.
alt The alternative text. Empty uses the alternative text of the file.
class The class of the image element: the fallback <img> , the SVG or the placeholder. The partial puts its own class ace-image in front of it.
showCaption Renders the description of the file in a <figcaption> .
showCopyright Renders the copyright of the file in the <figcaption> . The field exists with the core extension filemetadata only; without it, nothing is rendered and no error is raised.

The <figure> around the image is rendered only when a caption or a copyright is requested and the file has one. The partial gives its elements the classes ace-picture, ace-figure, ace-caption, ace-description and ace-copyright.

Presets 

Every preset is a section of the partial holding its sources and the width of its fallback image. A width is a maximum: an image is never scaled up.

Preset Sources (media query: maximum width) Fallback
card min-width: 992px: 390, min-width: 768px: 370, min-width: 576px: 690, otherwise 535 690
detail min-width: 992px: 1200, min-width: 576px: 960, otherwise 540 1200
logo min-width: 768px: 320, otherwise 240 320
teaser min-width: 992px: 600, min-width: 576px: 720, otherwise 540 720

teaser has no upstream consumer yet; it gives a project a stable name for teaser images rather than a section of its own in an override.

WebP output needs webp in $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] , which the core default configuration contains on TYPO3 v13 and v14. An installation that removed it gets the exception 1618992262 of the core image view helpers for every raster image the partial renders.

Overriding the partial 

The academic extensions that render the partial register the path EXT:academic_base/Resources/Private/Partials/ in their plugin view with the key -1, below every key they use themselves. A project overrides the partial like any other partial of the plugin: it places its own Academic/Image.html in the partial root path it configures through the constant of that plugin. One override per plugin changes the markup, the presets and the breakpoints of every image that plugin renders.

The extensions that ship a page template for their page type - EXT:academic_partners, EXT:academic_programs and EXT:academic_projects - register the same path in page.10.partialRootPaths , and EXT:academic_jobs does it for the partials it registers there. That array belongs to the site package, so the key is a negative one of its own per extension rather than -1: it sorts below every theme and project path, and replaces none of them.

A project that replaces the partial root paths of such a plugin completely has to list the academic_base path itself:

plugin.tx_academicpersons.view.partialRootPaths {
    -1 = EXT:academic_base/Resources/Private/Partials/
}
Copied!

Without it, the plugin fails on the partial it cannot resolve.

The form partials 

The partials below EXT:academic_base/Resources/Private/Partials/Academic/Form/ render the fields of an Extbase form with a label, a required mark, the validation state and a help text. EXT:academic_jobs renders its new job form through them.

Partial Renders
Textfield A text field of the input type its validation settings name.
Textarea A text area, with the class ace-ckeditor when the element sets richtext.
Select A select of the element's options, read through optionValueField and optionLabelField, with an optional first option of prependOptionValue and prependOptionLabel.
Checkbox A checkbox with the value 1.
DateTime A date field showing the element's value as Y-m-d, the only format a date input accepts.
Upload A file upload.
FieldWrapper The label, the required mark, the validation state, the messages of a rejected field and the help text around a field. Every field partial renders it.
ErrorMessage The message of one validation error of a field, see below.
Errors One alert above the form when any field failed validation.

A field partial takes these arguments:

Argument Meaning
element The field: identifier and validations, the validation set of the form, and per field disabled, help and the options of the select.
objectName The name of the form object, job for example. The id of a field is <objectName>.<identifier>.
extensionName The extension of the label create.<objectName>.<identifier>.label and the placeholder edit.<objectName>.<identifier>.placeholder.
fieldWrapperPartial The partial around the field, Academic/Form/FieldWrapper when it is not given. It receives element, elementId, class, elementContent and extensionName.

Errors takes the form object as object, and objectName and extensionName for the message create.<objectName>.incorrectValues.

A field that failed validation gets the class invalid, in place of the class f3-form-error the form field ViewHelpers set by default, and the attributes aria-invalid="true" and aria-describedby="<elementId>-error". FieldWrapper renders the messages of the field right after it, in the element <div id="<elementId>-error" class="ace-field-errors">, one <div class="ace-field-error"> per message. The title of the required mark is the label create.required of the extension.

The elements of a field carry these classes: the wrapper ace-field, invalid when the field failed validation, and the class of its type the field partial passes, ace-text-wrap, ace-textarea-wrap, ace-select-wrap, ace-checkbox-wrap, ace-date-wrap or ace-upload-wrap, the label ace-label, the required mark ace-required, the field ace-control and its type, ace-text, ace-textarea, ace-select, ace-checkbox, ace-date or ace-upload, and the help text ace-help. Errors renders its message in an ace-errors.

ErrorMessage shows the first of these that exists, each given the arguments of the error, so a label can name the rejected value with %s: the label create.<elementId>.error.<code> for the field and the error code, the label create.error.<code> for the error code, the message of the validator.

An extension that renders the fields under partial names of its own passes its own wrapper name as fieldWrapperPartial, so a project that overrides that wrapper changes every field. The new job form does so with Job/Forms/FieldWrapper.html, and a project overrides the names below Job/Forms/ of EXT:academic_jobs, not these.