Remembered jobs
In the table layout, visitors can tick "Remember" for single jobs. The list and the search result keep their order. Remembered jobs are highlighted and their checkbox is checked.
Above the list, a link "Remembered jobs" with a badge shows the number of remembered jobs. It leads to the view of the remembered jobs, where visitors see all their remembered jobs and can remove them again.
How it works
The list is cached and identical for all visitors, see
Caching. The JavaScript file
EXT: adds
everything that belongs to the visitor in the browser:
- After the page is loaded, it sends a read request (see below). With
the answer, it checks the checkboxes of the remembered jobs, highlights
their rows (CSS class
highlight-) and fills the badge of the link to the remembered jobs.row - When a checkbox is changed, it sends the job and the new state to the server and updates checkboxes, highlight and badge with the answer.
All requests are POST requests with the HTTP header
jobboard-. They go to the URL of the current page,
which the table and the link to the remembered jobs provide in the
attribute
data-. If the attribute is missing,
the path of the current page in the browser is used. The PSR-15 middleware
\JWeiland\ (identifier
jweiland/) answers every frontend request with
this header. It runs before the page is resolved, so it does not render the
page.
Form fields of a request that changes a job:
job- UID of the job in the default language. This UID is valid in all languages of the site.
remember1remembers the job,0forgets it.
A request with an empty body only reads the remembered jobs. It never creates or changes a session.
The answer is always a JSON object with the UIDs of all remembered jobs. In
case of an error, it also contains an error code. All answers are sent with
Cache-.
curl -X POST -H 'jobboard-remember-job: 1' \
-d 'job=12&remember=1' https://example.org/jobs
curl -X POST -H 'jobboard-remember-job: 1' https://example.org/jobs
{"rememberedJobs": [7, 12]}
| HTTP status | Error code | Reason |
|---|---|---|
| 200 | The job was remembered or forgotten, or the remembered jobs were read. | |
| 400 | invalid | job is not a positive integer or remember is
neither 1 nor 0. |
| 404 | unknown | The job does not exist, is not visible or is not stored in the pages of the site setting jobboard.storagePid and their sub pages (3 levels, like the content element). |
| 405 | method | The request is not a POST request. The answer contains the error code only, no remembered jobs. |
| 409 | limit | The visitor has reached the maximum number of remembered jobs. |
If a request fails, remember- shows the remembered jobs of
the answer and a message in a toast. Without an answer (network error), it
resets the checkbox. A visually hidden status element announces the new
number of remembered jobs to screen readers.
View of the remembered jobs
The link "Remembered jobs" opens the action
remembered of the
content element, with the speaking URL /remembered (see
Speaking URLs (route enhancer)). It lists all remembered jobs of the visitor
that are still listed in the frontend, in the same order as the list,
without page browser. Their checkboxes are checked.
When the visitor unticks a job here, the job is removed from the
remembered jobs at once. Its row stays on the page, greyed out and struck
through (CSS class
jobboard-), until the page is loaded
again, so the visitor can tick it again. The button "Back to all jobs"
leads back to the list.
Storage in the session
The remembered jobs are stored in the session data of the TYPO3 frontend
user, also for visitors who are not logged in. The session data has the key
tx_ and contains a list of job UIDs only.
When the first job is remembered, TYPO3 creates a session and sets its
session cookie fe_. When the last job is forgotten and the
session contains no other data, TYPO3 removes the session and the cookie.
- For visitors who are not logged in, the cookie
fe_is a session cookie of the browser, so the remembered jobs are lost when the browser is closed. The garbage collection of TYPO3 removes the session from the database at the earliesttypo_ user $GLOBALSseconds (default: 1 day) after the last change.['TYPO3_ CONF_ VARS'] ['FE'] ['session Data Lifetime'] - For logged-in frontend users, the remembered jobs belong to their login session and are lost after logout.
fe_ is a technically necessary cookie of TYPO3. Mention
it in the privacy information of your site.
Caching
The list and the detail view are cached, see
Caching of the job list. They never contain data of the
current visitor: the remembered jobs are added by remember-
in the browser, from the answer of the read request. Therefore every
visitor gets the same cached page.
The view of the remembered jobs shows the jobs of the current visitor, so
the action
remembered is not cached.
Security
- Only UIDs of existing, visible jobs in the default language from the storage pages of the current site can be remembered. The storage pages are taken from the site setting jobboard.storagePid, never from the request. Other data is never written to the session.
- The number of remembered jobs is limited. Jobs that are not visible anymore are removed from the session when the next job is remembered.
- A request that changes nothing, for example a read request or an invalid or unknown job, does not create a session.
- The middleware only accepts POST requests with the custom header. A
form or link on another website cannot send this header. A script on
another website has to ask the browser for permission first (CORS
preflight request), which TYPO3 does not grant. Additionally, browsers
do not send the cookie
fe_with POST requests of other websites (typo_ user $GLOBALS, default['TYPO3_ CONF_ VARS'] ['FE'] ['cookie Same Site'] lax). There is no additional CSRF token: the worst result of a forged request is a changed list of remembered jobs.
Own templates
remember- relies on these parts of the shipped templates:
data-jobboard- uid=" {job. uid}" - On every row (
Partials/) or card (Types/ Table. html Partials/). The script highlights the elements of remembered jobs and checks the checkboxes inside.Types/ Card. html <input type="checkbox" name="remember_job" value=" {job. uid}"> - The "Remember" checkbox in
Partials/.Types/ Table. html data-jobboard- remember- url=" {f: uri. page ()}" - URL for the requests, on the table and on the link to the remembered jobs.
data-jobboard- remembered- count - The badge in
Partials/.Remembered Jobs/ Link. html data-jobboard- remembered- view - Marks the view of the remembered jobs in
Templates/. Inside, unticked rows are greyed out instead of highlighted.Jobboard/ Remembered Jobs. html Partials/Remembered Jobs/ Feedback. html - The status element for screen readers and the toast with the error messages.
Templates/ and
Templates/ render the table partial without
the variable
{remembered, because their output is the same for
all visitors. Never pass it there. Only
Templates/ passes it, to render the
checkboxes checked:
<f:render partial="RememberedJobs/Link"/>
<f:render partial="RememberedJobs/Feedback"/>
<f:render partial="Types/Table" arguments="{objects: jobs}"/>
<section data-jobboard-remembered-view>
<f:render partial="Types/Table"
arguments="{objects: jobs, rememberedJobs: rememberedJobs}"/>
</section>