---
title: "Templates"
manual: "Academic Base"
version: "main"
permalink: "https://docs.typo3.org/permalink/fgtclb/academic-base:templates@main"
source: "Templates/Index.rst"
rendered: "2026-10-17T08:47:46+00:00"
---

# Templates {#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 {#templates-image}

[`EXT:academic_base/Resources/Private/Partials/Academic/Image.html`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/Resources/Private/Index.html#file-extension-resources-private-partials-somepartials-fluid-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:

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

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

```html
<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>
```

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 {#templates-image-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 {#templates-image-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 {#templates-image-override}

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:

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

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

## The form partials {#templates-form}

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.
