Academic Partners 

Extension key

academic_partners

Package name

fgtclb/academic-partners

Version

main

Language

en

Author

FGTCLB

License

This document is published under the Creative Commons BY 4.0 license.

Rendered

Fri, 21 Aug 2026 06:15:14 +0000


TYPO3 extension for presenting partner institutions and cooperations of universities with structured data and typified system categories, including filterable list and map views in the frontend.


Introduction 

What the extension does and the main concepts behind it.

Installation 

Install academic_partners via Composer, the Extension Manager or a TER upload.

Known problems 

Known issues and information about them.

Changelog 

Learn about what has changed and which actions are required to upgrade.

What does it do? 

...

Installation 

The extension has to be installed like any other TYPO3 CMS extension. You can download and install it using one of the following methods.

Install the stable release
composer require 'fgtclb/academic-partners':'^2'
Copied!
  1. Switch to the module Admin Tools > Extensions.
  2. Switch to Get Extensions.
  3. Search for the extension key academic_partners.
  4. Import the extension from the repository.
  1. Get the current version from TER by downloading the ZIP version. Alternatively, get the ZIP from the GitHub Releases page.
  2. Switch to the module Admin Tools > Extensions.
  3. Enable Upload Extension.
  4. Select or drag the extension ZIP archive and upload the file.

Known problems 

Please note that this extension is still in development. Changes to existing code may appear in upcoming versions.

If you run into a bug or a feature that would be helpful, please use the issue tracker.

ChangeLog v3 

Every change to the Academic Partners extension is documented here.

Also available 

3.0 Changes 

Table of contents

Breaking Changes 

Features 

Deprecation 

Important 

Breaking: The map assets are built and loaded as a module 

Description 

The stylesheet and the script of the partner map are now compiled from sources in the repository. Both moved into a frontend/ subdirectory, and the script became an ES module:

EXT:academic_partners/Resources/Public/Css/map.css
->  EXT:academic_partners/Resources/Public/Css/frontend/map.css

EXT:academic_partners/Resources/Public/JavaScript/map.js
->  EXT:academic_partners/Resources/Public/JavaScript/frontend/map.js
Copied!

The vendored Leaflet library, its marker cluster plugin and their stylesheets are unchanged. They are third party files without sources here, they keep their paths, and they are still loaded as classic scripts — the map module reads the LeafletObject global they define.

Impact 

An installation that uses the shipped Map.html template needs to do nothing.

An installation that references either path keeps pointing at a file that no longer exists.

Affected installations 

Installations that override Templates/Partner/Map.html or reference map.css or map.js from their own site package.

Migration 

In an overridden template, replace the two references:

<f:asset.css identifier="partnerC2" href="EXT:academic_partners/Resources/Public/Css/frontend/map.css" />
<f:asset.module identifier="@fgtclb/academic-partners/frontend/map.js" />
Copied!

The three Leaflet lines around them stay exactly as they are.

Breaking: Removed TYPO3 v12 support 

Description 

Support for TYPO3 v12 has been removed for the 3.x version line, based on the dual TYPO3 core version support per major version of the academic extensions support matrix.

This includes removing build, test and configuration parts only required for TYPO3 v12. Version specific code paths are dropped in a dedicated step.

Impact 

TYPO3 v12 or older instances can no longer install or update to the 3.x version of the academic extensions and are required to upgrade TYPO3 first.

The extension cannot be installed on TYPO3 v12 anymore but does not break otherwise.

Affected installations 

All installations using an academic extension on TYPO3 v12 that want to upgrade to the 3.x version line.

Migration 

Upgrade the TYPO3 installation to a supported version (TYPO3 v13) beforehand or within the same upgrade step.

Breaking: Removed the unused autocomplete library 

Description 

The file Resources/Public/JavaScript/autocomplete.min.js has been removed. It was a minified third party library that arrived with the initial import of the extension and was never referenced — no template, no TypoScript, no PHP and no other asset loaded it.

It was shipped in every release regardless, and a vendored, minified file without a source is a maintenance and security liability for as long as it exists.

Impact 

Nothing in the extension changes. No plugin, template or partial loaded the file, so no rendering, styling or behaviour is affected.

The file is no longer part of the package and a request for it returns 404.

Affected installations 

Only installations that referenced the file from their own site package or template overrides. That is possible, because the file was located below Resources/Public/, but it was never part of the extension's public API and no documentation ever mentioned it.

Migration 

If a project loads the file from its own template, ship the library in the project's own site package and reference it from there instead:

<f:asset.script identifier="autocomplete" src="EXT:my_sitepackage/Resources/Public/JavaScript/autocomplete.min.js" />
Copied!

No migration is required otherwise.

Important: The category filter accepts a list of uids 

Description 

Factory\DemandFactory::createDemandObject() read the submitted category filter itself:

foreach ($demandFromForm['filterCollection'] as $uids) {
    $categoryUids = array_merge($categoryUids, GeneralUtility::intExplode(',', $uids));
}
Copied!

GeneralUtility::intExplode() takes a string, so a filter value that is a list ended in a TypeError:

TypeError: GeneralUtility::intExplode(): Argument #2 ($string) must be of
type string, array given
Copied!

That is exactly what a filter select with multiple submits — the argument the category filter select gained in the same release. A filterCollection that is not an array at all did not raise, but emitted a PHP warning foreach() argument must be of type array|object and silently dropped the filter.

Both shapes are reachable from a crafted request without any template being involved, because the controller action takes the demand as a plain ?array $demand = null and validates nothing.

The filter is read through FGTCLB\CategoryTypes\Filter\CategoryFilterNormalizer now, which accepts a single value, a list and a comma separated string, and treats anything it cannot read as no filter.

Impact 

  • A category filter select with multiple works.
  • A request with an unreadable filter renders the list unfiltered instead of failing.
  • An unselected filter no longer contributes uid 0 to the query. The prepended "all options" entry carries an empty value, and every unselected category type added one 0 to the uid list. The rendered result is unchanged — no category has uid 0 — but the list handed to CategoryRepository::findByGroupAndUidList() is empty now, which it accepts since the same release.
  • A uid submitted twice is used once.

Affected Installations 

None have to act. Own code calling createDemandObject() with a hand built demand array keeps working, and gains the list shape.

References 

  • CategoryFilterNormalizer in EXT:category_types — the class the filter is read with, and where its behaviour is documented.

Important: The page template name of the academic partner page type is set explicitly 

Description 

This extension registers a page type with a backend layout and ships the page template for it in Resources/Private/Pages/. Its TypoScript adds that directory to page.10.templateRootPaths , but it did not set page.10.templateName — the property that actually selects the file.

A site package deriving the name from the backend layout therefore did not find it. bk2k/bootstrap-package does exactly that:

templateName.cObject = TEXT
templateName.cObject {
  data = pagelayout
  case = uppercamelcase
  split {
    token = pagets__
    cObjNum = 1
    1.current = 1
  }
}
Copied!

case = uppercamelcase is GeneralUtility::underscoredToUpperCamelCase() , which lowercases the whole string before it camel cases it on underscores. The registered backend layout pagets__AcademicPartner therefore resolved to Academicpartner.html, and the frontend ended in an InvalidTemplateResourceException — in a production context a page whose body reads Oops, an error occurred!.

The extension now sets the name itself, inside the page type condition it already uses:

[page && traverse(page, "doktype") == 40]
  page.10 {
    templateName >
    templateName = AcademicPartner
  }
[END]
Copied!

The clear is not decoration. Bootstrap package assigns templateName.cObject , and a cObject overwrites the plain value in ContentObjectRenderer::stdWrapValue() , so assigning without clearing would change nothing.

Impact 

A page of this type renders its template on a site package that derives the name from the backend layout, where it previously did not render at all.

Nothing changes for a site package that sets the name itself, as long as it does so after this extension's TypoScript, and nothing changes for a PAGEVIEW page object — that content object ignores templateName and resolves the file from paths , which is why that integration worked before and is unaffected now.

Affected Installations 

All installations of this extension that use a FLUIDTEMPLATE page object. An installation that shipped Academicpartner.html in its own site package to work around this loses that override: the template of this extension is used instead. Clearing page.10.templateName after this extension's TypoScript restores it.

Important: The page TSconfig directory is now spelled TSconfig 

Description 

The extensions of this set spelled their page TSconfig directory in three different ways — TsConfig, TSconfig and TSConfig. They now all use TSconfig, which is how TYPO3 spells the term and what the core documentation uses.

In this extension the directory was Configuration/TsConfig.

Nothing was broken before, because every import matched the directory it pointed at. The reason to change it is that a filesystem is case sensitive on Linux and case insensitive on macOS and Windows, so a path copied between two of these extensions resolved on one machine and silently not on another — and a page TSconfig @import that does not resolve raises no error, the configuration is simply absent.

Impact 

Every file this extension ships moved with the directory. The imports inside the extension were updated in the same change, so an installation that only installs the extension has nothing to do.

An integrator who references these paths from their own configuration has to update them, because the old path no longer exists:

Page TSconfig of your own site package
# before
@import 'EXT:academic_partners/Configuration/TsConfig/BackendLayouts/*.tsconfig'
# after
@import 'EXT:academic_partners/Configuration/TSconfig/BackendLayouts/*.tsconfig'

# before
@import 'EXT:academic_partners/Configuration/TsConfig/Wizards/*.tsconfig'
# after
@import 'EXT:academic_partners/Configuration/TSconfig/Wizards/*.tsconfig'
Copied!

Affected Installations 

Every installation that imports a page TSconfig file of this extension by path, or that copied such a path into its own site package. An installation that relies only on the auto-included Configuration/page.tsconfig of the extension, or on its site set, is unaffected.

Important: The sorting select shares the option rendering 

Description 

ViewHelpers\Form\SortingSelectViewHelper::renderOptionTags() was removed. It was identical to the method it inherits from FGTCLB\CategoryTypes\ViewHelpers\Form\AbstractSelectViewHelper, down to the last character - the class only ever needed its own getOptions().

That base class writes every option through a single method now, which escapes the option value. It used to concatenate the value unchanged while escaping the label.

Impact 

The rendered markup is unchanged. The options of this select carry the values of Enumeration\SortingOptions - title, asc, desc and their siblings - and none of them needs escaping.

An own subclass overriding renderOptionTags() keeps working, and one calling parent::renderOptionTags() reaches the inherited implementation.

References 

  • AbstractSelectViewHelper in EXT:category_types - the class writing the option markup, and where the change is documented.

Important: The static template and the backend layout are registered correctly 

Description 

Two registrations of this extension did not reach an installation.

The static template was registered under the wrong extension key. Configuration/TCA/Overrides/sys_template.php passed 'academic_programs' to ExtensionManagementUtility::addStaticFile() , so the entry offered in a template record as Academic Partners Page Setup pointed at EXT:academic_programs/Configuration/TypoScript/ — the TypoScript of a different extension. The TypoScript of this extension was registered nowhere and could only be reached through the site set fgtclb/academic-partners .

What that costs an installation without site sets: the page template directory of this extension never enters page.10.templateRootPaths , and the PartnershipProcessor data processor is never registered, so partnerships are not resolved on any page. An installation that has this extension without fgtclb/academic-programs included nothing at all, silently — SysTemplateTreeBuilder skips an include whose extension is not loaded.

The backend layout was imported by the site set only. Configuration/page.tsconfig is auto-included for the whole installation since TYPO3 v12.0 (Feature: #96614); a site set is opt-in per site. The backend layout of the page type this extension registers, and the descriptions of its content elements, were imported only by Configuration/Sets/AcademicPartners/page.tsconfig. On a site that does not enable that set the layout pagets__AcademicPartner resolved nowhere: the page properties showed [ MISSING LABEL ] for it and it could not be selected for a new page at all.

Both imports moved to Configuration/page.tsconfig, where fgtclb/academic-programs already had them, and the copy in the site set was removed rather than left to be applied twice. The empty Configuration/TsConfig/page.tsconfig, which nothing imports any more, was removed with it.

The missing label of the layout's content column was added to Resources/Private/Language/locallang_be.xlf in the same change.

Impact 

The static template Academic Partners Page Setup now includes the TypoScript of this extension. The backend layout and the content element descriptions are available on every installation, whether or not it uses site sets.

Affected Installations 

All installations of this extension.

The static template fix is not self-healing. A template record that selected the entry before stores EXT:academic_programs/Configuration/TypoScript/ , which is still a valid registration of the other extension, so the record keeps working and keeps including the wrong tree. The now correct entry has to be added to the record by hand. No upgrade wizard ships for it: the stored value is genuinely ambiguous — it cannot be told apart from an intentional selection of Academic Programs Page Setup — and rewriting it would break an installation that meant the latter.

Nothing has to be done for the backend layout. Pages already carrying pagets__AcademicPartner resolve it from now on.

3.x Changes by type 

This lists all changes to the Academic Partners extension of minor versions grouped by their type.

Table of contents

Breaking Changes 

Features 

Deprecations 

Important notes 

ChangeLog v2 

Every change to the Academic Partners extension is documented here.

Also available 

Feature: "Show hidden records" plugin option for the partner lists 

Description 

A new boolean plugin option Show hidden records ( settings.showHiddenRecords , checkbox/toggle, default off) was added to the following plugins:

  • List ( academicpartners_list )
  • Map ( academicpartners_map )

Both plugins share the single ListSettings.xml flexform data structure, which gains the new toggle.

When the option is enabled, the frontend partner listing includes hidden (disabled) records, independent of the Context API visibility settings. Only the hidden enable column (disabled) is ignored; the deleted, starttime/endtime and fe_group restrictions stay in effect.

The option is core-version-aware and available in both the TYPO3 v12 and v13 flexform data structures of the plugins.

Impact 

Editors can now opt in per plugin instance to display hidden partners in the frontend, for example to preview intentionally hidden records without changing the global preview settings. The option is off by default, so existing plugin instances keep their current behaviour.

Affected Installations 

All installations using the EXT:academic_partners extension starting with version 2.4. No action is required for existing installations.

Important: Extended PartnerDemand and demand handling 

Description 

To support the new "Show hidden records" plugin option, the partner demand pipeline gained a new transport flag:

  • \FGTCLB\AcademicPartners\Domain\Model\Dto\PartnerDemand has a new bool $showHiddenRecords property with setShowHiddenRecords(bool): void and getShowHiddenRecords(): bool accessors (default false ).
  • \FGTCLB\AcademicPartners\Factory\DemandFactory::createDemandObject() now reads $settings['showHiddenRecords'] and sets the flag on the demand object.
  • \FGTCLB\AcademicPartners\Domain\Repository\PartnerRepository::findByDemand() honours the flag: when it is true , the query ignores only the disabled (hidden) enable field via the Extbase query settings.

The public method signatures of DemandFactory::createDemandObject() and PartnerRepository::findByDemand() are unchanged.

Impact 

The change is non-breaking: the new flag defaults to false and no existing method signature changed. Projects that build a PartnerDemand themselves can opt in by calling setShowHiddenRecords(true) .

Affected Installations 

Only installations that extend or replace the PartnerDemand DTO, the DemandFactory or the PartnerRepository need to take the added flag into account. All other installations are unaffected.

Breaking: Changed identifier of backend layout 

Description 

The identifier of the backend layout was changed to unify the naming within all of the academic extensions.

Impact 

The backend layout identifier was changed from AcademicPartners to AcademicPartner.

Affected Installations 

Installations using the backend layout with the old identifier.

Migration 

Adapt to new naming of the backend layouts.

Breaking: Move translations to their belonging locallang files 

Description 

As some labels used for the backend were maintained in the locallang files for frontend usage, these labels were organized accordingly.

Impact 

Some labels in the backend might not be translated anymore, if a custom translation was only added to the frontend locallang file.

Affected Installations 

Installations with custom translations only added to the frontend locallang files.

Migration 

Add the custom translations to the correct locallang files.

Breaking: Removed partials 

Description 

Some partials got removed as the templating structure has changed.

Impact 

Those partials include:

  • Resources/Private/Layouts/Default.html
  • Resources/Private/Pages/AcademicPartners.html
  • Resources/Private/Partials/Categories.html
  • Resources/Private/Partials/Partner/Items.html
  • Resources/Private/Partials/Partner/SingleItem.html
  • Resources/Private/Partials/Partnerships/ListItem.html
  • Resources/Private/Partials/Partnerships/TeaserItem.html

Affected Installations 

TYPO3 instances with extensions overriding those partials of EXT:academic_partners.

Migration 

Adapt overrides accordingly to the new templating structure.

Important: Basic bootstrap styling 

Description 

The default templating now supports basic bootstrap styling and is semantically optimized to also not lack any major accessibility.

Important: Switch to EXT:category_types v2 

Description 

Category type based handling has been streamlined and centralized within the EXT:category_types extension and the known implementation based on deprecated TYPO3 Enumeration has been replaced with a modern PHP API provided by the EXT:category_type extension.

Extension specific category types are now grouped and are now defined by newly introduced yaml file format, following a concrete convention to look and auto-register these files.

EXT:academic_partners now ships a default set of partner related category types, which can be found in ./Configuration/CategoryTypes.yaml

EXT:academic_partners related category types can be extended by any other TYPO3 extension providing a Configuration/CategoryTypes.yaml file containing category-types using the group-identifier partners.

Configuration/CategoryTypes.yaml format uses following syntax:

Configuration/CategoryTypes.yaml
types:
    - identifier: <unique_identifier>
      title: '<type-translation-lable-using-full-LLL-syntax'
      group: partners
      icon: '<icon-file-using-EXT-syntax-needs-to-be-an-as-svg>'
Copied!

Sitemap