I've seen Georg Ringer adding the categories trough the controller, I'm trying to get a ViewHelper to do this ...
<?php
namespace Vendor\Extension\ViewHelpers;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
/**
* will return system categories (sys_category) array of an element
*/
class CategoriesOutputViewHelper extends AbstractViewHelper
{
protected $escapeOutput = false;
public function initializeArguments()
{
$this->registerArgument('CEUid', 'integer', 'record UID, e.g. of a content element', true);
}
/**
* Get content element registered categories
*/
protected function getCategories(int $CEUid): ?array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
return $queryBuilder
->select('sys_category.uid', 'sys_category.title', 'sys_category.shortcut')
->from('sys_category')
->join(
'sys_category',
'sys_category_record_mm',
'mm',
$queryBuilder->expr()->eq(
'mm.uid_local',
'sys_category.uid'
)
)
->where(
$queryBuilder->expr()->eq(
'mm.uid_foreign',
$queryBuilder->createNamedParameter($CEUid, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'mm.tablenames',
$queryBuilder->quote('tt_content')
),
$queryBuilder->expr()->eq(
'mm.fieldname',
$queryBuilder->quote('categories')
)
)
->execute()
->fetchAll();
}
/**
* Do category translation overlay
*/
public function render()
{
$CEUid = $this->arguments['CEUid'];
$categories = $this->getCategories($CEUid);
foreach ($categories as $key => $category) {
$overlaidCategory = $category;
if ($overlaidCategory !== null){
$categories[$key] = $overlaidCategory;
}
}
return $categories;
}
}
obviously in my render function nothing happens, but this is how far I can get things to work, it returns a correct array of categories in the default language ...
In fluid I call it like this (rs being the extensions namespace):
<f:if condition="{data.categories}">
<span class="category-list">
<f:for each="{rs:CategoriesOutput(CEUid: data.uid)}" as="category" iteration="iteration">
<f:if condition="{category.shortcut}">
<f:then>
<f:link.typolink parameter="{category.shortcut}">
{category.title}
</f:link.typolink>
</f:then>
<f:else>
{category.title}
</f:else>
</f:if>
<f:if condition="!{iteration.isLast}">
::
</f:if>
</f:for>
</span>
</f:if>
I'm working with V11.5.13 but I think the solution would be the same from V9 and on, thanks for the attention
My Answer:
Your ViewHelper looks good and should work as expected. However, in order to get the categories in the selected language, you need to add a language overlay to your query. Here's how you can modify your `getCategories` method to include language overlay:
php
protected function getCategories(int $CEUid): ?array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$languageUid = $GLOBALS['TSFE']->sys_language_uid;
return $queryBuilder
->select('sys_category.uid', 'sys_category.title', 'sys_category.shortcut')
->from('sys_category')
->join(
'sys_category',
'sys_category_record_mm',
'mm',
$queryBuilder->expr()->eq(
'mm.uid_local',
'sys_category.uid'
)
)
->where(
$queryBuilder->expr()->eq(
'mm.uid_foreign',
$queryBuilder->createNamedParameter($CEUid, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'mm.tablenames',
$queryBuilder->quote('tt_content')
),
$queryBuilder->expr()->eq(
'mm.fieldname',
$queryBuilder->quote('categories')
),
$queryBuilder->expr()->eq(
'sys_category.sys_language_uid',
$queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)
)
)
->execute()
->fetchAll();
}
By adding the `sys_category.sys_language_uid` condition to your query, you will only get the categories in the selected language. This should solve your issue with getting the categories in the correct language.
Rate this post
3 of 5 based on 6521 votesComments