Migrate to 12.1.x-dev (current main)

This commit is contained in:
Daniel Siepmann 2022-12-06 08:18:42 +01:00
parent 295f564672
commit 23b9672e51
16 changed files with 244 additions and 136 deletions

View file

@ -21,62 +21,59 @@ declare(strict_types=1);
* 02110-1301, USA.
*/
namespace DanielSiepmann\DsSite\Hooks\Backend;
namespace DanielSiepmann\DsSite\EventListener;
use TYPO3\CMS\Backend\Controller\PageLayoutController;
use TYPO3\CMS\Backend\Controller\Event\ModifyPageLayoutContentEvent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Frontend\Resource\FileCollector;
class PageLayoutHeader
{
/**
* @var array
*/
private $pageinfo = [];
public function render(
array $params,
PageLayoutController $pageLayoutController
): string {
if (is_array($pageLayoutController->pageinfo)) {
$this->pageinfo = $pageLayoutController->pageinfo;
}
public function __invoke(ModifyPageLayoutContentEvent $event): void
{
$request = $event->getRequest();
$pageinfo = BackendUtility::readPageAccess(
(int)($request->getParsedBody()['id'] ?? $request->getQueryParams()['id'] ?? 0),
''
);
// TODO: Check whether two levels up is uid 2, which holds all blog posts
// To prevent rendering on non blog posts
// Maybe we have rootline ?
$view = $this->getView();
$view->setRequest($request);
$view->assignMultiple([
'record' => $this->pageinfo,
'record' => $pageinfo,
'metaInfo' => [
[
'label' => 'meta-description',
'value' => $this->pageinfo['description'] ?? '',
'value' => $pageinfo['description'] ?? '',
'field' => 'description',
'type' => 'string',
],
[
'label' => 'introduction',
'value' => $this->pageinfo['abstract'] ?? '',
'value' => $pageinfo['abstract'] ?? '',
'field' => 'abstract',
'type' => 'string',
],
[
'label' => 'published',
'value' => $this->pageinfo['lastUpdated'] ?? '',
'value' => $pageinfo['lastUpdated'] ?? '',
'field' => 'lastUpdated',
'type' => 'date',
],
[
'label' => 'updated',
'value' => $this->pageinfo['SYS_LASTCHANGED'] ?? '',
'value' => $pageinfo['SYS_LASTCHANGED'] ?? '',
'type' => 'date',
],
[
'label' => 'media',
'value' => $this->resolvePageMedia(),
'value' => $this->resolvePageMedia((int) $pageinfo['uid']),
'field' => 'media',
'type' => 'files',
],
@ -84,7 +81,7 @@ class PageLayoutHeader
]);
$view->setTemplatePathAndFilename('EXT:ds_site/Resources/Private/Templates/Backend/Page/MetaInfo.html');
return $view->render();
$event->addHeaderContent($view->render());
}
private function getView(): StandaloneView
@ -92,11 +89,10 @@ class PageLayoutHeader
return GeneralUtility::makeInstance(StandaloneView::class);
}
private function resolvePageMedia(): array
private function resolvePageMedia(int $pageUid): array
{
$page = ['uid' => $this->pageinfo['uid'] ?? ''];
$files = new FileCollector();
$files->addFilesFromRelation('pages', 'media', $page);
$files->addFilesFromRelation('pages', 'media', ['uid' => $pageUid]);
return $files->getFiles();
}

View file

@ -83,14 +83,9 @@ class SitemapDataProvider extends RecordsXmlSitemapDataProvider
)
);
$result = $queryBuilder->execute()->fetchAll();
if ($result === false) {
return [];
}
return array_map(function (array $row) {
return (int) $row['uid'];
}, $result);
}, $queryBuilder->execute()->fetchAll());
}
private function createAdditionalWhereForPageUids(array $pageUids): string

View file

@ -24,29 +24,129 @@ declare(strict_types=1);
namespace DanielSiepmann\DsSite\Frontend\RssFeed;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3Fluid\Fluid\View\TemplateView;
use TYPO3\CMS\Core\Http\PropagateResponseException;
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemapRenderer as Typo3XmlSitemapRenderer;
use TYPO3\CMS\Frontend\Controller\ErrorController;
use TYPO3\CMS\Seo\XmlSitemap\Exception\InvalidConfigurationException;
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemapDataProviderInterface;
class XmlSitemapRenderer extends Typo3XmlSitemapRenderer
class XmlSitemapRenderer
{
/**
* @var ContentObjectRenderer
*/
public $cObj;
private array $typoScriptConfiguration = [];
protected array $configuration;
private ContentObjectRenderer $contentObjectRenderer;
protected TemplateView $view;
public function __construct(
protected TypoScriptService $typoScriptService,
protected RenderingContextFactory $renderingContextFactory,
) {
}
public function setContentObjectRenderer(ContentObjectRenderer $contentObjectRenderer): void
{
$this->contentObjectRenderer = $contentObjectRenderer;
}
protected function initialize(array $fullConfiguration): void
{
$this->configuration = $this->typoScriptService->convertTypoScriptArrayToPlainArray($fullConfiguration['plugin.']['tx_seo.'] ?? []);
$renderingContext = $this->renderingContextFactory->create();
$templatePaths = $renderingContext->getTemplatePaths();
$templatePaths->setTemplateRootPaths($this->configuration['view']['templateRootPaths']);
$templatePaths->setLayoutRootPaths($this->configuration['view']['layoutRootPaths']);
$templatePaths->setPartialRootPaths($this->configuration['view']['partialRootPaths']);
$templatePaths->setFormat('xml');
$this->view = GeneralUtility::makeInstance(TemplateView::class, $renderingContext);
$this->view->assign('settings', $this->getSettings());
}
public function render(string $_, array $typoScriptConfiguration, ServerRequestInterface $request): string
{
$this->typoScriptConfiguration = $typoScriptConfiguration;
return parent::render($_, $typoScriptConfiguration, $request);
$this->initialize($GLOBALS['TSFE']->tmpl->setup);
$this->view->assign('type', $GLOBALS['TSFE']->type);
$sitemapType = $typoScriptConfiguration['sitemapType'] ?? 'xmlSitemap';
if (!empty($sitemap = ($request->getQueryParams()['sitemap'] ?? null))) {
return $this->renderSitemap($request, $sitemap, $sitemapType);
}
return $this->renderIndex($request, $sitemapType);
}
protected function initialize(array $fullConfiguration): void
protected function renderIndex(ServerRequestInterface $request, string $sitemapType): string
{
parent::initialize($fullConfiguration);
$this->view->assign('settings', $this->getSettings());
$sitemaps = [];
foreach ($this->configuration['config'][$sitemapType]['sitemaps'] ?? [] as $sitemap => $config) {
if (!empty($config['provider']) && is_string($config['provider'])
&& class_exists($config['provider'])
&& is_subclass_of($config['provider'], XmlSitemapDataProviderInterface::class)
) {
/** @var XmlSitemapDataProviderInterface $provider */
$provider = GeneralUtility::makeInstance(
$config['provider'],
$request,
$sitemap,
(array)($config['config'] ?? [])
);
$pages = $provider->getNumberOfPages();
for ($page = 0; $page < $pages; $page++) {
$sitemaps[] = [
'key' => $sitemap,
'page' => $page,
'lastMod' => $provider->getLastModified(),
];
}
}
}
$this->view->assign('sitemapType', $sitemapType);
$this->view->assign('sitemaps', $sitemaps);
return $this->view->render('Index');
}
protected function renderSitemap(ServerRequestInterface $request, string $sitemap, string $sitemapType): string
{
if (!empty($sitemapConfig = $this->configuration['config'][$sitemapType]['sitemaps'][$sitemap] ?? null)) {
if (class_exists($sitemapConfig['provider']) &&
is_subclass_of($sitemapConfig['provider'], XmlSitemapDataProviderInterface::class)) {
/** @var XmlSitemapDataProviderInterface $provider */
$provider = GeneralUtility::makeInstance(
$sitemapConfig['provider'],
$request,
$sitemap,
(array)($sitemapConfig['config'] ?? [])
);
$items = $provider->getItems();
$this->view->assign('items', $items);
$this->view->assign('sitemapType', $sitemapType);
$template = ($sitemapConfig['config']['template'] ?? false) ?: 'Sitemap';
return $this->view->render($template);
}
throw new InvalidConfigurationException('No valid provider set for ' . $sitemap, 1535578522);
}
throw new PropagateResponseException(
GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
$request,
'No valid configuration found for sitemap ' . $sitemap
),
1535578569
);
}
private function getSettings(): array
@ -56,7 +156,7 @@ class XmlSitemapRenderer extends Typo3XmlSitemapRenderer
if (!is_string($variableName) || substr($variableName, -1) === '.') {
continue;
}
$settings[$variableName] = $this->cObj->cObjGetSingle(
$settings[$variableName] = $this->contentObjectRenderer->cObjGetSingle(
$this->typoScriptConfiguration['userFunc.']['variables.'][$variableName] ?? '',
$this->typoScriptConfiguration['userFunc.']['variables.'][$variableName . '.'] ?? []
);

View file

@ -35,13 +35,18 @@ class CodeHighlighting
/**
* @var ContentObjectRenderer
*/
public $cObj;
private $contentObjectRenderer;
public function setContentObjectRenderer(ContentObjectRenderer $contentObjectRenderer): void
{
$this->contentObjectRenderer = $contentObjectRenderer;
}
public function preTag(string $content, array $config): string
{
$highlighter = new Highlighter();
$highlighter->setClassPrefix('');
$code = $this->cObj->data[$this->cObj->currentValKey];
$code = $this->contentObjectRenderer->data[$this->contentObjectRenderer->currentValKey];
$code = htmlspecialchars_decode(trim($code));
try {

View file

@ -1,76 +1,69 @@
# Load default processing options
imports:
- {resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml"}
- {resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml"}
- {resource: "EXT:rte_ckeditor/Configuration/RTE/Processing.yaml"}
- {resource: "EXT:rte_ckeditor/Configuration/RTE/Editor/Base.yaml"}
editor:
config:
contentsCss: "EXT:ds_site/Resources/Public/Css/index.css"
height: 500
format_tags: "p;pre"
config:
# Ensure that special characters are not converted to HTML entities
entities_latin: false
entities: false
stylesSet:
- {name: "Inline code", element: "code"}
# Ensure that special characters are not converted to HTML entities
style:
definitions:
- {name: "Inline Code", element: "code", classes: ['']}
toolbarGroups:
# - {name: insert}
- {name: basicstyles, groups: [basicstyles, align, cleanup]}
- {name: paragraph, groups: [list, indent, blocks, align, bidi]}
- {name: links}
- {name: editing, groups: [find, selection, spellchecker]}
- {name: specialcharacters, groups: [insertcharacters]}
- "/"
- {name: styles}
- "/"
- {name: tools}
- {name: document, groups: [mode, document, doctools]}
heading:
options:
- {model: 'paragraph', title: 'Paragraph'}
- {model: 'formatted', view: 'pre', title: 'Code Block'}
# - {name: 'document', items: ['Source']}
# - {name: 'clipboard', items: ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', 'Undo', 'Redo']}
# - '/'
# - {name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', 'CopyFormatting', 'RemoveFormat']}
# - {name: 'paragraph', items: ['NumberedList', 'BulletedList', 'Outdent', 'Indent', 'Blockquote']}
# - {name: 'links', items: ['Link', 'Unlink', 'Anchor']}
# - {name: 'insert', items: ['HorizontalRule', 'SpecialChar']}
# - '/'
# - {name: 'styles', items: ['Styles', 'Format']}
# - {name: 'tools', items: ['Maximize', 'ShowBlocks']}
# - {name: 'about', items: ['About']}
toolbar:
items:
- bold
- italic
- underline
- strikethrough
- subscript
- superscript
- '|'
- removeFormat
- '|'
- bulletedList
- numberedList
- '|'
- indent
- outdent
- '|'
- blockQuote
- '|'
- link
- '-'
- style
- heading
- '-'
- sourceEditing
externalPlugins:
typo3link: { resource: "EXT:rte_ckeditor/Resources/Public/JavaScript/Plugins/typo3link.js", route: "rteckeditor_wizard_browse_links" }
showbrokenlinks: { resource: "EXT:rte_ckeditor/Resources/Public/JavaScript/Plugins/showbrokenlinks/plugin.js"}
# This is a plugin, found here: https://github.com/ufdada/quicktable
# quicktable: { resource: "EXT:rte_ckeditor/Resources/Public/JavaScript/Plugins/quicktable/plugin.js" }
autolinking: { resource: "EXT:rte_ckeditor/Resources/Public/JavaScript/Plugins/autolinking.js" }
# softhyphen plugin for adding ctrl+dash support to insert a conditional word break
# softhyphen:
# resource: "EXT:rte_ckeditor/Resources/Public/JavaScript/Plugins/softhyphen/"
# enableShortcut: true
importModules:
- '@typo3/rte-ckeditor/plugin/typo3-link.js'
externalPlugins:
typo3link: {route: "rteckeditor_wizard_browse_links"}
processing:
allowAttributes: []
HTMLparser_db:
tags:
ol:
allowedAttribs: []
ul:
allowedAttribs: []
code:
allowedAttribs: []
pre:
allowedAttribs: []
allowTagsOutside:
- pre
- blockquote
- ul
- ol
- li
- br
# blockElementList:
# - P
# - PRE
# - BLOCKQUOTE
allowAttributes: []
HTMLparser_db:
tags:
ol:
allowedAttribs: []
ul:
allowedAttribs: []
code:
allowedAttribs: []
pre:
allowedAttribs: []
allowTagsOutside:
- pre
- blockquote
- ul
- ol
- li
- br

View file

@ -72,3 +72,8 @@ services:
identifier: 'AddFurtherMetadataToFile'
event: TYPO3\CMS\Core\Resource\Event\EnrichFileMetaDataEvent
after: 'languageAndWorkspaceOverlay'
DanielSiepmann\DsSite\EventListener\PageLayoutHeader:
tags:
- name: event.listener
event: TYPO3\CMS\Backend\Controller\Event\ModifyPageLayoutContentEvent

View file

@ -19,8 +19,7 @@
],
'url' => [
'config' => [
'renderType' => 'inputLink',
'softref' => 'typolink',
'type' => 'link',
],
],
'lastUpdated' => [

View file

@ -15,13 +15,11 @@
],
'poster' => [
'label' => $languagePath . 'poster',
'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
'poster',
[
'maxitems' => 1,
],
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
),
'config' => [
'type' => 'file',
'maxitems' => 1,
'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
],
],
],
]);

View file

@ -28,7 +28,8 @@
'columns' => [
'header' => [
'config' => [
'eval' => 'required, trim',
'eval' => 'trim',
'required' => true,
],
],
'CType' => [

View file

@ -1,3 +1,5 @@
@import "../Frontend/variables";
.typo3-login {
.panel,
.panel-footer {
@ -31,3 +33,23 @@
max-width: 100%;
}
}
.ck-content {
padding: {
top: $spacer * 2;
bottom: $spacer * 2;
}
pre {
background: $black-dark;
color: $white-dark;
padding: 0.5em;
}
}
.ck.ck-content code {
background: $black-dark;
color: $white-dark;
}
.ck-editor__editable_inline {
height: 500px;
}

View file

@ -1,3 +1,5 @@
$spacer: 1rem !default;
$black: #5D5D5D;
$black-dark: #000000;
$red: #E09690;

View file

@ -1,4 +1,4 @@
body.cke_editable {
.ck-content {
padding: {
top: $spacer * 2;
bottom: $spacer * 2;

View file

@ -13,6 +13,5 @@
@import "components/codeHighlighting";
@import "components/adminpanel";
@import "components/ckeditor";
@import "components/admonition";
@import "components/video";

View file

@ -5,14 +5,14 @@
<f:then>
<title>Daniel Siepmann - Coding is Art - Blog Posts {settings.categoryTitle}</title>
<description>List of {settings.categoryTitle} blog posts at daniel-siepmann.de</description>
<link>{f:uri.page(pageUid: 11, additionalParams: {topic_uid: settings.categoryId}, absolute: 1)}</link>
<atom:link href="{f:uri.page(pageUid: 1. pageType: 1533906435, additionalParams: {sitemap: 'blog-posts', category_uid: settings.categoryId}, absolute: 1)}" rel="self" type="application/rss+xml" />
<link>{f:uri.typolink(parameter: 't3://page?uid=11', additionalParams: '&topic_uid={settings.categoryId}', absolute: 1)}</link>
<atom:link href="{f:uri.typolink(parameter: 't3://page?uid=1&type=1533906435', additionalParams: '&sitemap=blog-posts&category_uid={settings.categoryId}', absolute: 1)}" rel="self" type="application/rss+xml" />
</f:then>
<f:else>
<title>Daniel Siepmann - Coding is Art - All Blog Posts</title>
<description>List of blog posts at daniel-siepmann.de</description>
<link>{f:uri.page(pageUid: 1, absolute: 1)}</link>
<atom:link href="{f:uri.page(pageUid: 1. pageType: 1533906435, additionalParams: {sitemap: 'blog-posts'}, absolute: 1)}" rel="self" type="application/rss+xml" />
<link>{f:uri.typolink(parameter: 't3://page?uid=1', absolute: 1)}</link>
<atom:link href="{f:uri.typolink(parameter: 't3://page?uid=1&type=1533906435', additionalParams: '&sitemap=blog-posts', absolute: 1)}" rel="self" type="application/rss+xml" />
</f:else>
</f:if>
<lastBuildDate>{f:format.date(date: 'now', format: 'D, d M Y H:i:s O')}</lastBuildDate>
@ -32,8 +32,8 @@
<item>
<title>{item.title}</title>
<description>{item.abstract}</description>
<link>{f:uri.page(pageUid: item.uid, absolute: 1)}</link>
<link>{f:uri.typolink(parameter: 't3://page?uid={item.uid}', absolute: 1)}</link>
<pubDate>{f:format.date(date: item.lastUpdated, format: 'D, d M Y H:i:s O')}</pubDate>
<guid isPermaLink="true">{f:uri.page(pageUid: item.uid, absolute: 1)}</guid>
<guid isPermaLink="true">{f:uri.typolink(parameter: 't3://page?uid={item.uid}', absolute: 1)}</guid>
</item>
</f:section>

View file

@ -1 +1 @@
.typo3-login .panel,.typo3-login .panel-footer{background-color:rgba(0,0,0,.2)}.typo3-login .card-login,.typo3-login input{background-color:#2e3436}.typo3-login input{color:#9cd9f0;border-color:#9cd9f0}.typo3-login .form-control:focus,.typo3-login .form-control:hover{color:#9cd9f0;border-color:#9cd9f0;background-color:#2e3436}.typo3-login h2{color:#fff}.typo3-login a{color:#218693}.exampleContent video{width:40rem;max-width:100%}
.typo3-login .panel,.typo3-login .panel-footer{background-color:rgba(0,0,0,.2)}.typo3-login .card-login,.typo3-login input{background-color:#2e3436}.typo3-login input{color:#9cd9f0;border-color:#9cd9f0}.typo3-login .form-control:focus,.typo3-login .form-control:hover{color:#9cd9f0;border-color:#9cd9f0;background-color:#2e3436}.typo3-login h2{color:#fff}.typo3-login a{color:#218693}.exampleContent video{width:40rem;max-width:100%}.ck-content{padding-top:2rem;padding-bottom:2rem}.ck-content pre{padding:.5em}.ck-content pre,.ck.ck-content code{background:#000;color:#b0b0b0}.ck-editor__editable_inline{height:500px}

View file

@ -7,13 +7,6 @@
'default' => 'EXT:ds_site/Configuration/RTE/Default.yaml',
],
],
'SC_OPTIONS' => [
'cms/layout/db_layout.php' => [
'drawHeaderHook' => [
$extKey => \DanielSiepmann\DsSite\Hooks\Backend\PageLayoutHeader::class . '->render',
],
],
],
'SYS' => [
'fluid' => [
'namespaces' => [