Templates and frontend assets 

The output of the job board is rendered with Fluid. Copy the files you want to change into your site package and register its paths.

Override templates 

Set the site settings jobboard.templateRootPath, jobboard.partialRootPath and jobboard.layoutRootPath to the folders of your site package. Files that you do not copy are taken from the extension.

config/sites/<site-identifier>/settings.yaml
jobboard:
  templateRootPath: 'EXT:my_sitepackage/Resources/Private/Extensions/Jobboard/Templates/'
  partialRootPath: 'EXT:my_sitepackage/Resources/Private/Extensions/Jobboard/Partials/'
  layoutRootPath: 'EXT:my_sitepackage/Resources/Private/Extensions/Jobboard/Layouts/'
Copied!

Alternatively, add paths in TypoScript, see View paths.

Template files 

All files are in EXT:jobboard/Resources/Private/.

File Purpose
Layouts/Default.html Wrapper <div class="tx-jobboard">
Templates/Jobboard/List.html List: assets, search form, map and list of jobs
Templates/Jobboard/Search.html Search result, same structure as the list
Templates/Jobboard/RememberedJobs.html View of the remembered jobs of the visitor, see View of the remembered jobs
Templates/Jobboard/Detail.html Detail view. One <f:section> per group of fields, for example renderSalary or renderBenefits.
Partials/JobListAssets.html CSS and JavaScript of list, search and the view of the remembered jobs, see JavaScript and CSS
Partials/RememberedJobs/Link.html Link to the view of the remembered jobs with the count badge
Partials/RememberedJobs/Feedback.html Status for screen readers and toast with error messages of remember-jobs.js
Partials/SearchForm.html Search form and map
Templates/Map/InfoWindow.html Info window of a job location on the map (EXT:maps2 only), see Info window of a job location
Partials/Job/Search.html The search form itself. Provides the URL for the location suggestions, see Own search form templates.
Partials/Types/Table.html Default list rendering as table
Partials/Pagination.html Page browser below the list, see Page browser
Partials/Types/Card.html Alternative list rendering as cards, see Card layout
Partials/Job/TitleLink.html Table cell with the link to the job
Partials/Job/JobAreas.html Occupational fields of a job, see Partial "Job/JobAreas"
Partials/Job/JsonLd.html Structured data of the detail view, see Structured data (JSON-LD)
Templates/PluginPreview/Jobboard.html Preview in the backend page module
Pdf/Jobboard/Detail.html PDF version of a job, see PDF export

If a job has an external link (filled by an import only), the list links to this URL in a new window instead of the detail view.

Card layout 

The partial Partials/Types/Card.html renders each job as a card with occupational fields, position, application deadline, title, a shortened description, a "Read more" button and, if jobboard.pidOfApplicationForm is set, an "Apply online" button. It has no "Remember" checkbox. remember-jobs.js highlights the cards of jobs remembered in the table layout.

To use it, override Templates/Jobboard/List.html and Templates/Jobboard/Search.html and replace the table partial:

EXT:my_sitepackage/Resources/Private/Extensions/Jobboard/Templates/Jobboard/List.html
<f:render partial="Types/Card" arguments="{objects: jobs}"/>
Copied!

Partial "Job/JobAreas" 

Renders all occupational fields of a job, each in a <span class="job-area"> .

job
The job ( \JWeiland\Jobboard\Domain\Model\Job ). Required.
separator
Text between the occupational fields. Optional, default ', ' . Use '' if the spacing is done with CSS.
Render the occupational fields separated by a pipe
<f:render partial="Job/JobAreas" arguments="{job: job, separator: ' | '}"/>
Copied!

Page browser 

List and search result show jobboard.pageBrowser.itemsPerPage jobs per page. The partial Partials/Pagination.html renders the links to the first, previous, next and last page and the range of the shown jobs. The links of a search result keep the search criteria.

The page browser is added by the PSR-14 event listener \JWeiland\Jobboard\EventListener\AddPaginatorEventListener , see Extending the job board. It provides these variables:

{jobs}
The jobs of the current page only. The map above the list shows the locations of all jobs of the list or search result, see Markers of the map.
{paginator}
\TYPO3\CMS\Extbase\Pagination\QueryResultPaginator , for example {paginator.currentPageNumber} . It loads only the jobs of the current page from the database.
{pagination}
\JWeiland\Jobboard\Pagination\GetPostPagination , for example {pagination.lastPageNumber} or {pagination.nextPageArguments} .
{numberOfJobs}
Number of all jobs of the list or search result.

If the page browser is disabled (see jobboard.pageBrowser.enable and Show page browser) or the content element limits the list with Max entries to show (0 for all), the event listener adds nothing: {jobs} contains all jobs of the list or search result (a query result of \JWeiland\Jobboard\Domain\Model\Job objects), and the variables {paginator} , {pagination} , {numberOfJobs} and {actionName} are not assigned. The shipped partial Partials/Pagination.html then renders nothing. Check these variables with <f:if> before you use them in own templates.

The options of the search form are built from all jobs of the list or search result, not only from the jobs of the current page.

View of the remembered jobs 

Templates/Jobboard/RememberedJobs.html renders the action rememberedJobs , see View of the remembered jobs. This action is not cached and has no page browser. It provides these variables:

{jobs}
The remembered jobs of the current visitor that are still listed in the frontend, in the order of the list. Empty if the visitor has not remembered any job.
{rememberedJobs}
The UIDs of the remembered jobs as keys. Passed to Partials/Types/Table.html to render the checkboxes checked.

Never pass {rememberedJobs} in Templates/Jobboard/List.html or Templates/Jobboard/Search.html: their output must be the same for all visitors, see Own templates.

Structured data (JSON-LD) 

The detail view adds a schema.org/JobPosting as <script type="application/ld+json"> with these properties: title, description, identifier (employer and reference number), start date, validThrough (application deadline), hiring organization with logo (company and first image of the employer address; without company, the company of the workplace), job location, base salary (monthly, in the currency of jobboard.salary.currency) and directApply (true if the job has an email address).

Override Partials/Job/JsonLd.html to change the properties. Follow the rules in the comment of this partial to keep the output valid JSON: render every dynamic value with the tag syntax <f:format.json value="{...}"/> .

JavaScript and CSS 

The partial Partials/JobListAssets.html adds these files with the asset collector of TYPO3:

  • Css/style.css
  • JavaScript/remember-jobs.js (remembered jobs)
  • JavaScript/address-suggestions.js (suggestions of the location field)

Both JavaScript files are plain JavaScript. remember-jobs.js reads the remembered jobs of the visitor after the page is loaded, highlights them in the cached list and fills the count badge of the link to the remembered jobs. It sends a ticked or unticked "Remember" checkbox to the server and updates the highlight, see Remembered jobs. Neither file needs a library. address-suggestions.js shows the suggestions of the location field as a native <datalist> , see Suggestions for the location field.

To use other libraries or files, override the partial Partials/JobListAssets.html.

Labels 

Frontend labels are in EXT:jobboard/Resources/Private/Language/locallang.xlf (English) and de.locallang.xlf (German). Override single labels in your site package, see Custom translations.

Some useful label keys:

dateFormat
Date format of the list, the cards, the detail view and the PDF version, for example Y-m-d (English) or d.m.Y (German).
job.applyOnline
Text of the "Apply online" link.
job.downloadPdf, job.downloadPdf.addition
Text of the link to the PDF version. The addition is hidden on small screens.
search.no_jobs_found
Text if no job matches.
map.noGeoPosition.header, map.noGeoPosition
Message instead of the map, if no listed job has an address with a map location (EXT:maps2 only).
map.infoWindow.numberOfJobs.singular, map.infoWindow.numberOfJobs.plural
Number of jobs in the info window of a job location. The plural label contains %d for the number.
rememberedJobs.link, rememberedJobs.header
Text of the link to the remembered jobs and heading of their view.
rememberedJobs.error.limitReached and further error labels
Messages of remember-jobs.js if a job cannot be remembered or forgotten (rememberedJobs.error.unknownJob, rememberedJobs.error.failed).

ViewHelper for salary amounts 

The detail view formats every salary amount (salary range and salary steps) with the ViewHelper \JWeiland\Jobboard\ViewHelpers\Format\SalaryViewHelper . It uses \NumberFormatter with the locale of the site language and the currency of jobboard.salary.currency, for example 1.234,56 € in German or € 1.234,56 in Dutch.

Format a salary amount in an own template
<html xmlns:jobboard="http://typo3.org/ns/JWeiland/Jobboard/ViewHelpers"
      data-namespace-typo3-fluid="true">

<jobboard:format.salary>{job.salaryRangeMin}</jobboard:format.salary>
{job.salaryRangeMax -> jobboard:format.salary()}
Copied!

If you have overridden Templates/Jobboard/Detail.html, replace <f:format.currency> of the salary amounts with this ViewHelper and remove the currency sign after it. Otherwise, your template keeps the German format. The structured data (Structured data (JSON-LD)) keeps the plain numbers and gets the currency code from the ViewHelper \JWeiland\Jobboard\ViewHelpers\SalaryCurrencyViewHelper :

Currency of the structured data in an own Partials/Job/JsonLd.html
"currency": <f:format.json value="{jobboard:salaryCurrency()}"/>,
Copied!

Another format, for example a fixed one for all languages, needs no setting: override the template and use f:format.number with separators from your own language file. f:format.number uses number_format() , so the separators of each language are translations:

Own format with the separators of an own language file
<f:format.number decimals="2"
    decimalSeparator="{f:translate(key: 'LLL:EXT:my_sitepackage/Resources/Private/Language/locallang.xlf:salary.decimalSeparator')}"
    thousandsSeparator="{f:translate(key: 'LLL:EXT:my_sitepackage/Resources/Private/Language/locallang.xlf:salary.thousandsSeparator')}"
>{job.salaryRangeMin}</f:format.number> €
Copied!

Markers of the map 

List and search result assign the variable {poiCollections} : the map locations (EXT:maps2) of all jobs of the list or search result, one marker per location, even if several jobs or addresses share the same location. The page browser does not reduce it, only the search form and the settings of the content element do. Hidden addresses and addresses without a map location are skipped. Without EXT:maps2, it is empty and no map is rendered.

The markers are built before the template is rendered, by the service \JWeiland\Jobboard\Service\MapPoiCollectionServiceInterface . No job is loaded for the map. Partials/SearchForm.html passes {poiCollections} to the map partial of EXT:maps2.

The map locations of EXT:maps2 are passed unchanged. The title of a marker is the title of the map location, which EXT:maps2 takes from the address, see Map location. The info window is loaded when a visitor clicks the marker, see Info window of a job location.

Info window of a job location 

When a visitor clicks a marker, EXT:maps2 loads the content of the info window with an AJAX request. For markers of job locations, the job board renders Templates/Map/InfoWindow.html. It shows:

  • The company of the address, otherwise first and last name
  • ZIP code and city
  • The number of jobs, for example "3 jobs at this location"
  • A link to each open job at this location

The jobs are selected with the same rules as the job list: open jobs (see Why is my job not shown?) in the storage folder of jobboard.storagePid and its subpages, in the language of the page. They are sorted alphabetically by the title shown to the visitor: in a translated language by the translated title, according to the rules of the locale of the site language and without regard to upper and lower case. Jobs with the same title keep the order of their creation. The links lead to the detail view on the page jobboard.pidOfDetailPage or, if it is not set, on the current page. Jobs with an external link (filled by an import only) link to this URL in a new tab, like in the list.

Override the template like the other templates, see Override templates. The template is searched in the template root paths of plugin.tx_jobboard.view . If the TypoScript setup is not available in the AJAX request (cached page), the site settings jobboard.templateRootPath, jobboard.partialRootPath and jobboard.layoutRootPath are used. Place the file in Map/InfoWindow.html of your template folder.

The template is rendered without an Extbase request. Use the attribute extensionName: 'jobboard' in f:translate and the prepared URIs of the job links instead of f:link.action .

The template gets one variable:

{jobLocation}

\JWeiland\Jobboard\Domain\Model\JobLocation with these properties:

{jobLocation.name}
Company of the address, otherwise first and last name. May be empty.
{jobLocation.street}
Street and house number of the address (field address of tt_address ). May be empty.
{jobLocation.zip} , {jobLocation.city}
ZIP code and city of the address.
{jobLocation.numberOfJobs}
Number of open jobs at this location. Always at least 1.
{jobLocation.jobLinks}
List of \JWeiland\Jobboard\Domain\Model\JobLink objects with {jobLink.uid} , {jobLink.title} , {jobLink.uri} and {jobLink.isExternal} . The URI is empty if no link could be built.
EXT:my_sitepackage/Resources/Private/Extensions/Jobboard/Templates/Map/InfoWindow.html
<strong>{jobLocation.name}</strong>
<ul>
    <f:for each="{jobLocation.jobLinks}" as="jobLink">
        <li><a href="{jobLink.uri}">{jobLink.title}</a></li>
    </f:for>
</ul>
Copied!

The labels map.infoWindow.numberOfJobs.singular and map.infoWindow.numberOfJobs.plural contain the text of the number of jobs, see Labels.

To render the info window with PHP instead, see Info window of job locations.