Add content element "skillsets"

Allow editors to add new content element "skills".
The element contains an input for a comma separated list of skill IDs.
A preview in backend is shown.
Frontend rendering is provided.
This commit is contained in:
Daniel Siepmann 2020-09-22 14:03:20 +02:00
parent 6e47f165e9
commit e967112277
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
17 changed files with 330 additions and 39 deletions

View file

@ -22,6 +22,7 @@ namespace SkillDisplay\Typo3Extension\Backend;
*/
use SkillDisplay\PHPToolKit\Api\Skill;
use SkillDisplay\PHPToolKit\Api\SkillSet;
use TYPO3\CMS\Backend\View\PageLayoutView;
use TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
@ -33,10 +34,17 @@ class Preview implements PageLayoutViewDrawItemHookInterface
*/
protected $skillApi;
/**
* @var SkillSet
*/
private $skillSetApi;
public function __construct(
Skill $skillApi
Skill $skillApi,
SkillSet $skillSetApi
) {
$this->skillApi = $skillApi;
$this->skillSetApi = $skillSetApi;
}
/**
@ -50,9 +58,36 @@ class Preview implements PageLayoutViewDrawItemHookInterface
array &$row
) {
$row['skills'] = [];
$row['skillSets'] = [];
if ($row['skilldisplay_skills'] != '') {
$row = $this->addSkills($row);
}
if ($row['skilldisplay_skillset'] > 0) {
$row = $this->addSkillSets($row);
}
}
private function addSkills(array $row): array
{
$skills = GeneralUtility::intExplode(',', $row['skilldisplay_skills'], true);
foreach ($skills as $skillId) {
$row['skills'][] = $this->skillApi->getById($skillId);
}
return $row;
}
private function addSkillSets(array $row): array
{
$skillSets = GeneralUtility::intExplode(',', $row['skilldisplay_skillset'], true);
foreach ($skillSets as $skillSetId) {
$row['skillSets'][] = $this->skillSetApi->getById($skillSetId);
}
return $row;
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace SkillDisplay\Typo3Extension\Frontend\DataProcessing;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use SkillDisplay\PHPToolKit\Api\SkillSet;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
class SkillSets implements DataProcessorInterface
{
/**
* @var SkillSet
*/
protected $skillSetApi;
public function __construct(
SkillSet $skillSetApi
) {
$this->skillSetApi = $skillSetApi;
}
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData
) {
$as = $cObj->stdWrapValue('as', $processorConfiguration, 'skillSets');
$skillSetIds = GeneralUtility::intExplode(
',',
$cObj->stdWrapValue('skillSets', $processorConfiguration, ''),
true
);
$skillSets = [];
foreach ($skillSetIds as $skillSetId) {
$skillSets[] = $this->skillSetApi->getById($skillSetId);
}
$processedData[$as] = $skillSets;
return $processedData;
}
}

View file

@ -22,33 +22,19 @@ namespace SkillDisplay\Typo3Extension\ViewHelpers\Verification;
*/
use SkillDisplay\PHPToolKit\Verification\Link;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use SkillDisplay\Typo3Extension\ViewHelpers\VerificationViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class ButtonViewHelper extends AbstractViewHelper
class ButtonViewHelper extends VerificationViewHelper
{
use CompileWithRenderStatic;
protected $escapeOutput = false;
public function initializeArguments()
protected static function verificationHtml(array $arguments): string
{
$this->registerArgument('skill', 'integer', 'ID of the skill.', true);
$this->registerArgument('type', 'string', 'Type of verification', false, 'self');
}
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
/** @var Link $link */
$link = GeneralUtility::makeInstance(Link::class);
return $link->getVerificationButton(
$arguments['type'],
$arguments['skill']
static::getId($arguments),
static::getType($arguments)
);
}
}

View file

@ -22,33 +22,19 @@ namespace SkillDisplay\Typo3Extension\ViewHelpers\Verification;
*/
use SkillDisplay\PHPToolKit\Verification\Link;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use SkillDisplay\Typo3Extension\ViewHelpers\VerificationViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class UrlViewHelper extends AbstractViewHelper
class UrlViewHelper extends VerificationViewHelper
{
use CompileWithRenderStatic;
protected $escapeOutput = false;
public function initializeArguments()
protected static function verificationHtml(array $arguments): string
{
$this->registerArgument('skill', 'integer', 'ID of the skill.', true);
$this->registerArgument('type', 'string', 'Type of verification', false, 'self');
}
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
/** @var Link $link */
$link = GeneralUtility::makeInstance(Link::class);
return $link->getVerificationLink(
$arguments['type'],
$arguments['skill']
static::getId($arguments),
static::getType($arguments)
);
}
}

View file

@ -0,0 +1,92 @@
<?php
namespace SkillDisplay\Typo3Extension\ViewHelpers;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use SkillDisplay\PHPToolKit\Verification\Link;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3\CMS\Core\Utility\GeneralUtility;
abstract class VerificationViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
protected $escapeOutput = false;
public function initializeArguments()
{
$this->registerArgument('skill', 'integer', 'ID of the Skill.');
$this->registerArgument('skillSet', 'integer', 'ID of the SkillSet.');
$this->registerArgument('type', 'string', 'Type of verification', false, 'self');
}
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
static::validateIds($arguments);
return static::verificationHtml($arguments);
}
abstract protected static function verificationHtml(array $arguments): string;
/**
* @return void
*/
protected static function validateIds(array $arguments)
{
if (
isset($arguments['skill']) && $arguments['skill'] !== ''
&& isset($arguments['skillSet']) && $arguments['skillSet'] !== ''
) {
throw new \Exception('Can only handle skill or skillSet not both.', 1600775604);
}
if (
(isset($arguments['skill']) === false || $arguments['skill'] === '')
&& (isset($arguments['skillSet']) === false || $arguments['skillSet'] === '')
) {
throw new \Exception('Either needs skill or skillSet, none given.', 1600775604);
}
}
protected static function getId(array $arguments): int
{
if (static::getType($arguments) === Link::SKILL) {
return $arguments['skill'];
}
return $arguments['skillSet'];
}
protected static function getType(array $arguments): string
{
if (isset($arguments['skill']) && $arguments['skill'] !== '') {
return Link::SKILL;
}
return Link::SKILL_SET;
}
}

View file

@ -0,0 +1,15 @@
mod {
wizards.newContentElement.wizardItems.skilldisplay {
elements {
skilldisplay_skillset {
iconIdentifier = skilldisplay-skillset
title = LLL:EXT:skilldisplay/Resources/Private/Language/locallang_tca.xlf:tt_content.skilldisplay_skillset
description = LLL:EXT:skilldisplay/Resources/Private/Language/locallang_be.xlf:newContentElement.skilldisplay.skillset.description
tt_content_defValues {
CType = skilldisplay_skillset
}
}
}
}
web_layout.tt_content.preview.skilldisplay_skillset = EXT:skilldisplay/Resources/Private/Templates/Backend/ContentElements/Skillset.html
}

View file

@ -24,6 +24,10 @@ services:
arguments:
$settings: '@skilldisplay.settings'
SkillDisplay\PHPToolKit\Api\SkillSet:
arguments:
$settings: '@skilldisplay.settings'
SkillDisplay\PHPToolKit\Verification\Link:
public: true
arguments:

View file

@ -22,6 +22,16 @@
'size' => 10,
],
],
'skilldisplay_skillset' => [
'exclude' => 1,
'label' => $languagePath . 'skilldisplay_skillset',
'description' => $languagePath . 'skilldisplay_skillset.description',
'config' => [
'type' => 'input',
'eval' => 'int,required',
'size' => 10,
],
],
],
]);
})('skilldisplay', 'tt_content');

View file

@ -0,0 +1,46 @@
<?php
(function (string $extensionKey, string $tableName, string $contentType) {
$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang_tca.xlf:' . $tableName . '.';
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA'][$tableName], [
'ctrl' => [
'typeicon_classes' => [
$contentType => 'skilldisplay-skillset',
],
],
'types' => [
$contentType => [
'showitem' => implode(',', [
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general',
'--palette--;;general',
'skilldisplay_skillset',
'--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance',
'--palette--;;frames',
'--palette--;;appearanceLinks',
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language',
'--palette--;;language',
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access',
'--palette--;;hidden',
'--palette--;;access',
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories',
'categories',
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes',
'rowDescription',
'--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended',
]),
],
],
]);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTcaSelectItem(
$tableName,
'CType',
[
$languagePath . $contentType,
$contentType,
'skilldisplay-skillset',
'skilldisplay'
]
);
})('skilldisplay', 'tt_content', 'skilldisplay_skillset');

View file

@ -9,3 +9,15 @@ tt_content.skilldisplay_skills {
}
}
}
tt_content.skilldisplay_skillset = < lib.contentElement
tt_content.skilldisplay_skillset {
templateName = SkillDisplaySkillSet
dataProcessing {
10 = SkillDisplay\Typo3Extension\Frontend\DataProcessing\SkillSets
10 {
skillSets.field = skilldisplay_skillset
}
}
}

View file

@ -9,6 +9,9 @@
<trans-unit id="newContentElement.skilldisplay.skills.description">
<source>Renders one or multiple skills.</source>
</trans-unit>
<trans-unit id="newContentElement.skilldisplay.skillset.description">
<source>Renders one skillset.</source>
</trans-unit>
<trans-unit id="site.div.skilldisplay">
<source>SkillDisplay</source>

View file

@ -9,6 +9,12 @@
<trans-unit id="tt_content.skilldisplay_skills.description">
<source>Comma separated list of UIDs.</source>
</trans-unit>
<trans-unit id="tt_content.skilldisplay_skillset">
<source>SkillDisplay: SkillSet</source>
</trans-unit>
<trans-unit id="tt_content.skilldisplay_skillset.description">
<source>UID of SkillSet</source>
</trans-unit>
<trans-unit id="tt_content.CType.itemGroups.skilldisplay">
<source>SkillDisplay</source>
</trans-unit>

View file

@ -0,0 +1,18 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
xmlns:sd="http://typo3.org/ns/SkillDisplay/Typo3Extension/ViewHelpers"
data-namespace-typo3-fluid="true">
<a href="{be:uri.editRecord(
uid: uid,
table: 'tt_content'
)}">
<ol>
<f:for each="{skillSets}" as="skillSet">
<li>
<strong>{skillSet.name}</strong><br>
</li>
</f:for>
</ol>
</a>
</html>

View file

@ -0,0 +1,13 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:sd="http://typo3.org/ns/SkillDisplay/Typo3Extension/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:for each="{skillSets}" as="skillSet">
<div class="card">
<div class="card-body">
<h5 class="card-title">{skillSet.name}</h5>
<p class="card-text">{skillSet.description -> f:format.html()}</p>
<sd:verification.button skillSet="{skillSet.id}"/>
</div>
</div>
</f:for>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -7,6 +7,7 @@
$icons = [
'skill',
'skillset',
];
$iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\TYPO3\CMS\Core\Imaging\IconRegistry::class

View file

@ -1,3 +1,4 @@
CREATE TABLE tt_content (
skilldisplay_skills TEXT,
skilldisplay_skillset int(11) unsigned DEFAULT '0' NOT NULL,
);