mirror of
https://github.com/SkillDisplay/TYPO3ContentElements.git
synced 2024-05-19 16:34:09 +02:00
Compare commits
15 commits
f0572b02af
...
9eb9d3c7ec
Author | SHA1 | Date | |
---|---|---|---|
9eb9d3c7ec | |||
f37a57e46e | |||
41beb0310a | |||
48142a8786 | |||
e2b7c980e5 | |||
15ddcb4158 | |||
0f0b7e3145 | |||
eb432ddf94 | |||
80dcd33175 | |||
9076aa0067 | |||
60931303c0 | |||
ffde64c04b | |||
901b7ab2be | |||
08a1830e75 | |||
573e1baedd |
55
Classes/FormDataProvider/ValuePickerItemDataProvider.php
Normal file
55
Classes/FormDataProvider/ValuePickerItemDataProvider.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of the TYPO3 CMS project.
|
||||
*
|
||||
* It is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License, either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*
|
||||
* The TYPO3 project - inspiring people to share!
|
||||
*/
|
||||
|
||||
namespace SkillDisplay\SkilldisplayContent\FormDataProvider;
|
||||
|
||||
use SkillDisplay\PHPToolKit\Api\SkillSet;
|
||||
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
|
||||
|
||||
/**
|
||||
* Inject available skill sets a valuepicker form
|
||||
*/
|
||||
class ValuePickerItemDataProvider implements FormDataProviderInterface
|
||||
{
|
||||
private SkillSet $skillSetApi;
|
||||
|
||||
public function __construct(SkillSet $skillSetApi)
|
||||
{
|
||||
$this->skillSetApi = $skillSetApi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sys_domains into $result data array
|
||||
*
|
||||
* @param array $result Initialized result array
|
||||
* @return array Result filled with more data
|
||||
*/
|
||||
public function addData(array $result): array
|
||||
{
|
||||
if ($result['tableName'] === 'tt_content' && isset($result['processedTca']['columns']['skilldisplay_skillset'])) {
|
||||
$skillSets = $this->skillSetApi->getAll();
|
||||
foreach ($skillSets as $skillSet) {
|
||||
$result['processedTca']['columns']['skilldisplay_skillset']['config']['valuePicker']['items'][] =
|
||||
[
|
||||
$skillSet->getName(),
|
||||
$skillSet->getId(),
|
||||
];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -25,6 +25,8 @@ namespace SkillDisplay\SkilldisplayContent\Frontend\DataProcessing;
|
|||
|
||||
use Exception;
|
||||
use SkillDisplay\PHPToolKit\Api\SkillSet;
|
||||
use TYPO3\CMS\Core\Cache\CacheManager;
|
||||
use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
|
@ -45,23 +47,43 @@ class SkillSets implements DataProcessorInterface
|
|||
array $processorConfiguration,
|
||||
array $processedData
|
||||
) {
|
||||
|
||||
$as = $cObj->stdWrapValue('as', $processorConfiguration, 'skillSets');
|
||||
$skillSetsIdsRaw = (string)$cObj->stdWrapValue('skillSets', $processorConfiguration);
|
||||
$skillSetIds = GeneralUtility::intExplode(
|
||||
',',
|
||||
(string)$cObj->stdWrapValue('skillSets', $processorConfiguration),
|
||||
$skillSetsIdsRaw,
|
||||
true
|
||||
);
|
||||
$skillSets = [];
|
||||
|
||||
$enableCache = $processorConfiguration['cache'] ?? false;
|
||||
if ($enableCache) {
|
||||
$cacheKey = md5($skillSetsIdsRaw) . $as;
|
||||
/** @var VariableFrontend $cache */
|
||||
$cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('sdcontent');
|
||||
if ($cache->has($cacheKey)) {
|
||||
$data = $cache->get($cacheKey);
|
||||
} else {
|
||||
$data = $this->generateData($skillSetIds);
|
||||
$cache->set($cacheKey, $data);
|
||||
}
|
||||
} else {
|
||||
$data = $this->generateData($skillSetIds);
|
||||
}
|
||||
$processedData[$as] = $data;
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
protected function generateData(array $skillSetIds): array
|
||||
{
|
||||
$skillSets = [];
|
||||
foreach ($skillSetIds as $skillSetId) {
|
||||
try {
|
||||
$skillSets[] = $this->skillSetApi->getById($skillSetId);
|
||||
$skillSets[] = $this->skillSetApi->getById($skillSetId, true);
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$processedData[$as] = $skillSets;
|
||||
return $processedData;
|
||||
return $skillSets;
|
||||
}
|
||||
}
|
||||
|
|
107
Classes/ViewHelpers/SkillGroupingViewHelper.php
Normal file
107
Classes/ViewHelpers/SkillGroupingViewHelper.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SkillDisplay\SkilldisplayContent\ViewHelpers;
|
||||
|
||||
/*
|
||||
* 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 Closure;
|
||||
use SkillDisplay\PHPToolKit\Entity\Skill;
|
||||
use SkillDisplay\PHPToolKit\Entity\SkillSet;
|
||||
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
*
|
||||
* <sd:skillGrouping skillSet="{skillSet}" as="domainGroup">
|
||||
* {domainGroup.title}<br />
|
||||
* <f:for each="{domainGroup.skills}" as="skill">
|
||||
* {skill.name}<br />
|
||||
* </f:for>
|
||||
* </sd:skillGrouping>
|
||||
*/
|
||||
class SkillGroupingViewHelper extends AbstractViewHelper
|
||||
{
|
||||
use CompileWithRenderStatic;
|
||||
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('skills', 'array', 'An array of skills to group', false, []);
|
||||
$this->registerArgument('skillSet', SkillSet::class, 'The skills of this skill set will be grouped');
|
||||
$this->registerArgument('as', 'string', 'The name of the iteration variable', true);
|
||||
}
|
||||
|
||||
public static function renderStatic(
|
||||
array $arguments,
|
||||
Closure $renderChildrenClosure,
|
||||
RenderingContextInterface $renderingContext
|
||||
) {
|
||||
/** @var Skill[] $skills */
|
||||
$skills = $arguments['skills'];
|
||||
/** @var SkillSet|null $skillSet */
|
||||
$skillSet = $arguments['skillSet'];
|
||||
$as = $arguments['as'];
|
||||
|
||||
if ($skillSet) {
|
||||
$groups = self::group($skillSet->getSkills());
|
||||
} else {
|
||||
$groups = self::group($skills);
|
||||
}
|
||||
|
||||
$templateVariableContainer = $renderingContext->getVariableProvider();
|
||||
$output = '';
|
||||
foreach ($groups as $group) {
|
||||
$templateVariableContainer->add($as, $group);
|
||||
$output .= $renderChildrenClosure();
|
||||
$templateVariableContainer->remove($as);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Skill[] $skills
|
||||
* @return array
|
||||
*/
|
||||
protected static function group(array $skills): array
|
||||
{
|
||||
$domainTags = [];
|
||||
foreach ($skills as $skill) {
|
||||
$domainTags[] = isset($skill->toArray()['domainTag']) ? $skill->toArray()['domainTag']['title'] : "none";
|
||||
}
|
||||
$domainTags = array_unique($domainTags);
|
||||
|
||||
$result = [];
|
||||
foreach ($domainTags as $domainTag) {
|
||||
$result[] = [
|
||||
'title' => $domainTag,
|
||||
'skills' => array_filter($skills, function (Skill $skill) use ($domainTag) {
|
||||
if (!isset($skill->toArray()['domainTag'])) {
|
||||
return $domainTag === "none";
|
||||
}
|
||||
return $skill->toArray()['domainTag']['title'] === $domainTag;
|
||||
})
|
||||
];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ abstract class VerificationViewHelper extends AbstractViewHelper
|
|||
|
||||
protected $escapeOutput = false;
|
||||
|
||||
public function initializeArguments()
|
||||
public function initializeArguments(): void
|
||||
{
|
||||
$this->registerArgument('skill', 'integer', 'ID of the Skill.');
|
||||
$this->registerArgument('skillSet', 'integer', 'ID of the SkillSet.');
|
||||
|
|
|
@ -21,10 +21,12 @@ services:
|
|||
alias: '@skilldisplay.settings'
|
||||
|
||||
SkillDisplay\PHPToolKit\Api\Skill:
|
||||
public: true
|
||||
arguments:
|
||||
$settings: '@skilldisplay.settings'
|
||||
|
||||
SkillDisplay\PHPToolKit\Api\SkillSet:
|
||||
public: true
|
||||
arguments:
|
||||
$settings: '@skilldisplay.settings'
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
'type' => 'input',
|
||||
'eval' => 'required',
|
||||
'size' => 10,
|
||||
'valuePicker' => [
|
||||
'mode' => 'append',
|
||||
// filled by ValuePickerItemDataProvider
|
||||
'items' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
'skilldisplay_campaign' => [
|
||||
|
|
1
Configuration/TypoScript/constants.typoscript
Normal file
1
Configuration/TypoScript/constants.typoscript
Normal file
|
@ -0,0 +1 @@
|
|||
SkilldisplayContent.skillSet.cache = 0
|
|
@ -17,6 +17,7 @@ tt_content.skilldisplay_skillset {
|
|||
dataProcessing {
|
||||
10 = SkillDisplay\SkilldisplayContent\Frontend\DataProcessing\SkillSets
|
||||
10 {
|
||||
cache = {$SkilldisplayContent.skillSet.cache}
|
||||
skillSets.field = skilldisplay_skillset
|
||||
}
|
||||
}
|
||||
|
|
30
README.rst
30
README.rst
|
@ -1,10 +1,21 @@
|
|||
=========================================
|
||||
TYPO3 Extension to integrate SkillDisplay
|
||||
=========================================
|
||||
=======================================================================
|
||||
Display Skills & SkillSets from SkillDisplay as TYPO3 Content Elements
|
||||
========================================================================
|
||||
|
||||
This TYPO3 extension integrates SkillDisplay into TYPO3 installations.
|
||||
This TYPO3 extension allows to show SkillDisplay Skills & SkillSets in TYPO3 installations.
|
||||
|
||||
Right now it provides the following features:
|
||||
Scenarios
|
||||
* Show job requirements based on official certification and expert definitions on your website
|
||||
|
||||
* Visualize the curriculum of a training your agency provides
|
||||
|
||||
* Display the requirements for official certification (on official pages or your intranet websites)
|
||||
|
||||
You can list the skills as content elements one by one, or use SkillSets for grouping purposes (see scenarios above).
|
||||
All public SkillSets available on the SkillDisplay platform (e.g.: Certification curriculums, etc.) are automatically available for use in this extension.
|
||||
To use custom SkillSets you either need a business account on the official SkillDisplay platform, or host the Open Source SkillDisplay Core Extension on your own TYPO3 instance.
|
||||
|
||||
Right now this extension provides the following features:
|
||||
|
||||
* Content element to render one or more skills.
|
||||
|
||||
|
@ -18,6 +29,8 @@ Right now it provides the following features:
|
|||
|
||||
* ViewHelper to generate verification URL.
|
||||
|
||||
* ViewHelper to group skills by domain tag
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
|
@ -46,6 +59,10 @@ Or copy the files from `/Resources/Private/Templates/ContentElements/` to your e
|
|||
Configuration
|
||||
=============
|
||||
|
||||
It is possible to cache the API results for Skill Sets with this TypoScript constant::
|
||||
|
||||
SkilldisplayContent.skillSet.cache = 1
|
||||
|
||||
You may include default CSS for the templates in your TypoScript::
|
||||
|
||||
page.includeCSS.skilldisplay = EXT:skilldisplay_content/Resources/Public/Css/Styles.css
|
||||
|
@ -59,5 +76,4 @@ Both can be adjusted via custom TypoScript and TSconfig.
|
|||
Usage
|
||||
=====
|
||||
|
||||
Add content elements to the pages and insert the ID of skills as comma separated
|
||||
list, or the ID of a single skill set.
|
||||
Add content elements to the pages and insert the ID of skills as comma separated list, or select one of the available skillsets. (The list includes all public SkillSets on the official SkillDisplay platform. Using custom SkillDisplay instances based on the Open Source extension is possible, check the skilldisplay/php-api package for more information)
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
|
||||
xmlns:sd="http://typo3.org/ns/SkillDisplay/SkilldisplayContent/ViewHelpers"
|
||||
data-namespace-typo3-fluid="true">
|
||||
<f:for each="{skillSets}" as="skillSet">
|
||||
{f:render(partial: 'VerificationBox', arguments: {
|
||||
title: skillSet.name,
|
||||
count: '{skillSet.skills -> f:count()}',
|
||||
detailUrl: 'https://my.skilldisplay.eu/skillset/{skillSet.id}',
|
||||
brandLogoUrl: skillSet.brand.logoPublicUrl,
|
||||
verificationUrl: '{sd:verification.url(skillSet: skillSet.id, campaign: data.skilldisplay_campaign)}',
|
||||
description: skillSet.description
|
||||
})}
|
||||
xmlns:sd="http://typo3.org/ns/SkillDisplay/SkilldisplayContent/ViewHelpers"
|
||||
data-namespace-typo3-fluid="true">
|
||||
<f:for each="{skillSets}" as="skillSet">
|
||||
<sd:skillGrouping skillSet="{skillSet}" as="domainGroup">
|
||||
<b>{domainGroup.title}</b><br/>
|
||||
<f:for each="{domainGroup.skills}" as="skill">
|
||||
{skill.title}<br/>
|
||||
</f:for>
|
||||
</sd:skillGrouping>
|
||||
</f:for>
|
||||
|
||||
<hr>
|
||||
|
||||
<f:for each="{skillSets}" as="skillSet">
|
||||
{f:render(partial: 'VerificationBox', arguments: {
|
||||
title: skillSet.name,
|
||||
count: '{skillSet.skills -> f:count()}',
|
||||
detailUrl: 'https://my.skilldisplay.eu/skillset/{skillSet.id}',
|
||||
brandLogoUrl: skillSet.brand.logoPublicUrl,
|
||||
verificationUrl: '{sd:verification.url(skillSet: skillSet.id, campaign: data.skilldisplay_campaign)}',
|
||||
description: skillSet.description
|
||||
})}
|
||||
</f:for>
|
||||
</html>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.1 || ^8.2",
|
||||
"skilldisplay/phptoolkit": "^2.0.1",
|
||||
"skilldisplay/phptoolkit": "^2.1",
|
||||
"typo3/cms-backend": "^11.5 || ^12.4",
|
||||
"typo3/cms-frontend": "^11.5 || ^12.4"
|
||||
},
|
||||
|
|
|
@ -25,4 +25,28 @@
|
|||
// todo v11?
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem'][$extKey] =
|
||||
\SkillDisplay\SkilldisplayContent\Backend\Preview::class;
|
||||
|
||||
// Inject skillsets into valuepicker form
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord']
|
||||
[\SkillDisplay\SkilldisplayContent\FormDataProvider\ValuePickerItemDataProvider::class] = [
|
||||
'depends' => [
|
||||
\TYPO3\CMS\Backend\Form\FormDataProvider\TcaInputPlaceholders::class,
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
$caches = [
|
||||
'sdcontent',
|
||||
];
|
||||
foreach ($caches as $cacheName) {
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheName] = [
|
||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class,
|
||||
'options' => [
|
||||
'defaultLifetime' => 2592000, // 30 days
|
||||
],
|
||||
'groups' => ['lowlevel']
|
||||
];
|
||||
}
|
||||
|
||||
})('skilldisplay_content');
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
CREATE TABLE tt_content
|
||||
(
|
||||
skilldisplay_skills TEXT,
|
||||
skilldisplay_skillset int(11) unsigned DEFAULT '0' NOT NULL,
|
||||
skilldisplay_campaign varchar(200) DEFAULT '' NOT NULL
|
||||
skilldisplay_skills varchar(200) DEFAULT '' NOT NULL,
|
||||
skilldisplay_skillset varchar(200) DEFAULT '' NOT NULL,
|
||||
skilldisplay_campaign varchar(200) DEFAULT '' NOT NULL
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue