Styling
The profile editing plugin renders its markup with the class system of the academic extensions and ships no styling for it. The system, the classes of Bootstrap it keeps and how a site package styles the markup are described once, in the chapter Styling of academic_base. This chapter shows how the markup of the profile list and the editor is built up, and which classes the editor script writes.
The editor is an application rather than a page of text: it has more controls
and more states than any other plugin. Its buttons are Bootstrap buttons, so a
site with a Bootstrap theme shows them right away. Where the Bootstrap script
is on the page, the editor shows its messages as a Bootstrap toast and the help
text of a field, the button ace-, as a Bootstrap popover with
the class custom-. The layout of the editor, its previews, its dialogs
and its states are the work of the site stylesheet. The one stylesheet the site
links rather than writes is the one of the rich text fields, see
The rich text editor.
The outermost elements
| View | Content element type | Outermost element |
|---|---|---|
| Profile list | academicpersonsedit_ | academic- |
| Profile editor | academicpersonsedit_ | academic-, inside the element
<academic- |
Neither class follows the pattern academic-<extension>-<plugin> of the other
plugins exactly: the editor is named after the profile editing without the
-edit of the extension, and the profile list carries the class of the
extension, academic-, next to its own.
The profile list
<section class="academic-persons-edit academic-persons-profile-editing-list" …>
<h1 class="ace-title">Assigned profiles</h1>
<div class="ace-table-wrap">
<table class="ace-table">
<thead class="ace-header">
<tr>
<th class="ace-label" scope="col">Profile</th>
<th class="ace-label" scope="col">Language</th>
<th class="ace-label ace-actions" scope="col">Actions</th>
</tr>
</thead>
<tbody class="ace-content">
<tr class="ace-item">
<td class="ace-value">
<div class="ace-profile">
<img class="ace-image" … />
<span class="ace-title ace-name">Dr. Jane Doe</span>
<span class="ace-state" data-pe-profile-hidden>Hidden</span>
</div>
</td>
<td class="ace-value ace-language">English</td>
<td class="ace-actions">
<div class="ace-controls">
<a class="ace-link ace-control ace-view btn btn-link" …>…</a>
<a class="ace-link ace-control ace-edit btn btn-link" …>…</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
The head and body of the table are ace- and ace-. The table
views of EXT:academic_persons and EXT:academic_bite_jobs
name them ace- and ace-, and ace- and
ace-.
A user without a profile sees the message in a
<p class="ace-
in place of the table. The state ace- is only rendered for a hidden
profile, and a hidden profile has no link to its detail page.
The editor
<a class="ace-link ace-back-link" href="…">Back to the list</a>
<academic-persons-edit-profile-editing>
<div class="academic-persons-profile-editing" data-academic-persons-profile-editing …>
<div data-pe-image-editor-target>
<section class="ace-image-editor">…</section>
</div>
<div class="ace-profile-editing-wrapper">
<header class="ace-header">
<h1 class="ace-title">…</h1>
<div class="ace-actions">
<form class="ace-form" …>
<div class="ace-switch">…</div>
<div class="ace-message">…</div>
</form>
<button class="ace-control ace-edit btn btn-outline-secondary btn-sm">…</button>
</div>
</header>
<div class="ace-content">
<div class="row">
<div class="col-12 col-lg-4" data-pe-image-preview-column>
<div class="ace-image-column">
<div class="ace-sticky-image" data-pe-sticky-image>
<section class="ace-section">…</section>
</div>
</div>
</div>
<div class="col-12 col-lg-8" data-pe-profile-fields-column>
<div class="ace-fields-column">
<section class="ace-section">…</section>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="ace-documents">…</div>
</div>
</div>
</div>
</div>
<div class="ace-messages">…</div>
<dialog class="ace-dialog">…</dialog>
</div>
</academic-persons-edit-profile-editing>
- The link back to the list, and the message an installation without the
AJAX page type shows, an
ace-, are rendered before the editor element, outsidemessage ace- error academic-.persons- profile- editing - The header holds the title and the switches of the synchronisation and of
the visibility of the profile, each an
ace-in a form of its own with answitch ace-for its result.message - The sections are
<section class="ace-elements with ansection"> ace-: the image, the personal fields, the about me fields and one section per kind of document.title - The image editor is rendered where it is shown, above the editor, and opened by the script.
A field
Every field of the personal and the about me sections shows its value and switches to a control when it is edited. A single field renders like this:
<div class="col-12">
<div class="ace-field-group" data-pe-field-wrapper>
<div class="ace-preview" …>
<div class="ace-content">
<div class="ace-label">Room <abbr title="…">*</abbr></div>
<div class="ace-value">…</div>
</div>
<button class="ace-control ace-edit btn btn-sm" …>…</button>
</div>
<div class="ace-editor" hidden="hidden" data-pe-field-editor …>
<div class="ace-header">
<label class="ace-label" for="…">Room</label>
<!-- the help button, see "The buttons" -->
</div>
<div class="ace-controls" data-pe-field-control-group>
<!-- the control, a text area inside an ace-control-wrap -->
<div class="ace-actions btn-group btn-group-sm" role="group" hidden="hidden" …>
<button class="ace-control ace-clear btn btn-outline-danger" …>…</button>
<button class="ace-control ace-undo btn btn-outline-secondary" …>…</button>
<button class="ace-control ace-save btn btn-success" …>…</button>
</div>
</div>
<div class="ace-message" role="alert"></div>
</div>
</div>
</div>
- The
ace-and itseditor ace-are rendered with the attributeactions hidden. The editor script takes it off, so without the script a field cannot be edited. - A rich text field puts the
ace-into itsactions ace-, next to the label, and its control into anheader ace-, followed by ancontrol- wrap ace-when the field has a length limit.counter - Every other row of fields carries
ace-on itsalternate ace-.field- group - A field with a title of its own, a link with its link title for example,
is edited as a group. The group has the same
ace-. Itspreview ace-holds aeditor rowwith one grid column per field, each anace-with anfield ace-, the control and anheader ace-, and then a singlemessage ace-around aactions <div class="btn-of the buttons.group btn- group- sm"> - An empty value is an
ace-inside theempty ace-. A rich text value is avalue ce-.bodytext - The required mark is an
<abbr>without a class. The form partials of EXT:academic_base give it the classace-.required
The documents
Each kind of document, the contracts and the entries of the profile, is an
ace- with an ace- holding its ace- and an add button
ace-, and an ace- of one
<article class="ace- per
document. A document row lays out its values in ace- elements, each with
an ace- and an ace-, in grid columns, and ends with its
ace-: its state ace- and the buttons ace-,
ace-, ace-, ace-, ace-,
ace- and ace-. A section without documents shows an
ace-. A contract holds its contacts the same way, in a section of its
own with an ace- of ace- rows.
A row ends with an ace-. When a document is edited, viewed or
deleted, the script opens the document editor there, a
<section class="ace- holding an ace- with its
ace-, an ace-, a confirmation text ace- before
a deletion, the fields of the document, the contacts of a contract in an
ace-, and its buttons. A new document opens its editor in the section
of its kind.
The buttons
Every button is an ace- with the action it performs and the Bootstrap
button classes of its kind:
| Class | Action |
|---|---|
ace- | Open a field, the image or a document for editing. |
ace-, ace- | Save a field or a document, apply the open fields. ace-
means the application link of a program in
EXT:academic_programs. Scoped by the outermost element,
a rule for one does not reach the other. |
ace-, ace-, ace-, ace- | Undo a change, clear a field, discard the changes, cancel a dialog. |
ace-, ace- | Add or delete a document or the image. |
ace-, ace-, ace- | Move a document. The contacts of a contract have no handle. |
ace-, ace- | Show or hide a document on the profile, show its details. The
contacts of a contract name the same two buttons ace-
and ace-. |
ace- | Close a message, with the Bootstrap class btn-. |
ace- | Show the help text of a field. In the form partials of
EXT:academic_base, ace- is the help text itself. |
Further classes of the editor
| Class | Element |
|---|---|
ace- | An empty
<span>
in the save and delete buttons of the image
editor, the document editor and the contact editor, shown while a
request is pending. It has no content, so it is invisible without
a rule of the site stylesheet, a spinning border for example. |
ace- | The character count of a rich text field with a length limit. |
ace- | Every other row of fields, on its ace-. |
ace-, ace- | The section of the image editor, and the area of the image in it that is cropped. |
ace- | A help text of the image editor. Elsewhere, ace- names the
button of a help text in this editor and the help text itself in
the form partials of EXT:academic_base. |
ace-, ace-, ace-, ace- | The document editor, the place below a row it opens in, the
contacts of a contract in it, and the confirmation text of a
deletion, see The documents. The dialog about unsaved
changes uses ace- for its text as well. |
ace- | The
<fieldset>
of the personal fields, with a
visually- legend. |
ace- | The wrapper of a text area or of a rich text control. |
ace- | The icon inside a field action button, hidden from screen readers. |
What the editor script writes
The editor script works with the data- attributes, apart from the
ace- of a field or a group, which it finds by its class and writes the
message of a refused value into, so an override keeps that class. It writes
these classes, which a site stylesheet should show. The editor does not work
without it: plugin. switches it off only for
a site that brings an editor script of its own, see
Load the script or bring your own.
| Class | Written on |
|---|---|
is- | The control of a field whose value was rejected, and its editor
element: the ace- of the field or of its group, for a rich
text field the ace-. On a switch of the header, the
checkbox whose change was rejected. This is the name of Bootstrap
for the state the form partials of EXT:academic_base
call invalid. |
show, showing, and one of ace-,
ace-, ace-, ace- | The ace- of the ace- that reports a result. With
the Bootstrap toast script on the page, the toast shows and hides
it. Without it, the editor sets show, so the site stylesheet
hides an ace- there that is not show. |
active | The button of the header that opens all fields, while they are
open, with
aria-. |
ace-, ce- | The value of a field after it was saved, as the template renders it. |
ace- | The ace- of a rich text field over its length limit. |
is-, is-, is-,
is-, is- | The dragged document row, its list, and the place it would drop to. |
is- | The editor while the image editor closes. |
col-, col-, col- | The columns of the image and the fields, which the image editor widens and narrows. |
academic-,
-enter-, -leave-, -leave-, and the same with
academic- | The ace- and an ace- while they
open and close. The script waits for the transition the stylesheet
declares on them, and goes on at once when there is none. |
The rich text editor
The rich text fields of the editor are CKEditor 5, imported from the import map of EXT:rte_ckeditor. The extension uses its scripts only, and ships no stylesheet for the toolbar, the buttons, the link balloon and the dialogs of the editor. Where those styles come from depends on the patch level of TYPO3:
| TYPO3 | CKEditor 5 | Interface styles |
|---|---|---|
| 13.4.35, 14.3.7 | 47.6.0 | Injected by the CKEditor scripts into the page they run on. Nothing to do for the site. |
| 13.4.36, 14.3.8 and later | 48.5.2 or later | In EXT:, which
only the backend form links. The site has to link it, or the
toolbar shows its icons at the size of their SVG files and the
editor has no layout. |
Link the file of the core rather than a copy of it. It belongs to the CKEditor
build the core ships, so it stays in step with the editor when a core update
brings a new CKEditor release. Linking it does no harm on the patch levels of
the first row, where the file only holds a few rules TYPO3 adds. The file is
served from the site's own origin, below _assets/ in a Composer
installation, so a Content Security Policy that allows style-
covers it. It is some 220 KB, so link it on the page of the editor only. The
development site of the extensions does it like this, in TypoScript the site
package can copy:
page.includeCSS.richTextEditor = EXT:rte_ckeditor/Resources/Public/Css/editor.css
page.includeCSS.richTextEditor.if.isTrue.numRows {
table = tt_content
select.where = {#CType} = 'academicpersonsedit_profileediting'
}
The condition counts the profile editing elements on the current page. An
element shown on another page, through an Insert records element
for example, is not on that page. Name the page that holds the element then,
with its uid in place of the default this, or link the file on every page:
page.includeCSS.richTextEditor.if.isTrue.numRows.select.pidInList = 42
The stylesheet uses the light colours of CKEditor. A site changes them through
the custom properties of CKEditor, such as -- or
--, in a rule of its own stylesheet that comes after the
link. The buttons of the toolbar are
<button>
elements below the plugin
root, so a focus rule of the site for the controls of the editor reaches them
as well.
An example
Rules in the stylesheet of the site package, scoped by the outermost element:
.academic-persons-profile-editing .ace-messages {
position: fixed;
right: 1rem;
bottom: 1rem;
}
.academic-persons-profile-editing .ace-messages .ace-message:not(.show) {
display: none;
}
.academic-persons-profile-editing .ace-message-danger {
border-left: 4px solid #dc3545;
}
.academic-persons-profile-editing .ace-item.is-dragging {
opacity: 0.5;
}
The development instances style the editor with the partial
_academic-persons-edit.scss
of the site package academics_, a complete example to copy from,
including the transitions above.
To change the markup itself, override the partials as described in
Templates. The editor script keeps working with other classes as long
as the data- attributes stay where the templates put them.