Finally migrate RSS Feed
Misusing the sitemap implementation was a bad idea and broke for every major update. I now finally migrate to custom implementation which should remove the issues for future.
This commit is contained in:
parent
02493e9540
commit
8bcdec5d94
7 changed files with 197 additions and 386 deletions
148
Classes/Frontend/RssFeed/BlogPostsDataProvider.php
Normal file
148
Classes/Frontend/RssFeed/BlogPostsDataProvider.php
Normal file
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
namespace DanielSiepmann\DsSite\Frontend\RssFeed;
|
||||
|
||||
use Exception;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
|
||||
use TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor;
|
||||
|
||||
final class BlogPostsDataProvider implements DataProcessorInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly DatabaseQueryProcessor $databaseQueryProcessor,
|
||||
private readonly ConnectionPool $connectionPool
|
||||
) {
|
||||
}
|
||||
|
||||
public function process(
|
||||
ContentObjectRenderer $contentObjectRenderer,
|
||||
array $contentObjectConfiguration,
|
||||
array $processorConfiguration,
|
||||
array $processedData
|
||||
) {
|
||||
$processedData = $this->databaseQueryProcessor->process(
|
||||
$contentObjectRenderer,
|
||||
$contentObjectConfiguration,
|
||||
array_merge($processorConfiguration, [
|
||||
'where' => 'AND no_index = 0' . $this->getAdditionalWhere($contentObjectRenderer->getRequest()),
|
||||
]),
|
||||
$processedData
|
||||
);
|
||||
|
||||
foreach ($processedData['pages'] as &$page) {
|
||||
$page['description'] = $page['data']['abstract']
|
||||
. $this->getContent(
|
||||
$contentObjectRenderer,
|
||||
$page['data']['uid']
|
||||
);
|
||||
}
|
||||
|
||||
return $processedData;
|
||||
}
|
||||
|
||||
private function getAdditionalWhere(ServerRequestInterface $request): string
|
||||
{
|
||||
$categoryUid = intval($request->getQueryParams()['category_uid'] ?? 0);
|
||||
if ($categoryUid === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$pageUids = $this->getPageUidsWithRelationToCategory($categoryUid);
|
||||
$where = $this->createAdditionalWhereForPageUids($pageUids);
|
||||
|
||||
if ($where !== '') {
|
||||
return '';
|
||||
}
|
||||
return ' ' . $where;
|
||||
}
|
||||
|
||||
private function getPageUidsWithRelationToCategory(int $categoryUid): array
|
||||
{
|
||||
$queryBuilder = $this->connectionPool->getQueryBuilderForTable('pages');
|
||||
|
||||
$queryBuilder->select('uid');
|
||||
$queryBuilder->from('pages');
|
||||
$queryBuilder->leftJoin(
|
||||
'pages',
|
||||
'sys_category_record_mm',
|
||||
'mm',
|
||||
'pages.uid = mm.uid_foreign'
|
||||
);
|
||||
$queryBuilder->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'mm.tablenames',
|
||||
$queryBuilder->createNamedParameter('pages')
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
'mm.fieldname',
|
||||
$queryBuilder->createNamedParameter('categories')
|
||||
),
|
||||
$queryBuilder->expr()->in(
|
||||
'mm.uid_local',
|
||||
$queryBuilder->createNamedParameter($categoryUid)
|
||||
)
|
||||
);
|
||||
|
||||
return array_map(function (array $row) {
|
||||
if (is_numeric($row['uid'])) {
|
||||
return (int) $row['uid'];
|
||||
}
|
||||
throw new Exception('UID was not numeric: ' . var_export($row['uid'], true), 1707325559);
|
||||
}, $queryBuilder->executeQuery()->fetchAllAssociative());
|
||||
}
|
||||
|
||||
private function createAdditionalWhereForPageUids(array $pageUids): string
|
||||
{
|
||||
return ' AND uid IN(' . implode(',', $pageUids) . ')';
|
||||
}
|
||||
|
||||
private function getContent(
|
||||
ContentObjectRenderer $contentObjectRenderer,
|
||||
int $pageUid
|
||||
): string {
|
||||
$colPositions = [
|
||||
50,
|
||||
0,
|
||||
100,
|
||||
200,
|
||||
];
|
||||
|
||||
$content = '';
|
||||
foreach ($colPositions as $colPos) {
|
||||
$content .= $contentObjectRenderer->cObjGetSingle('CONTENT', [
|
||||
'table' => 'tt_content',
|
||||
'select.' => [
|
||||
'orderBy' => 'sorting',
|
||||
'where' => '{#colPos}=' . $colPos,
|
||||
'pidInList' => $pageUid,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 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.
|
||||
*/
|
||||
|
||||
namespace DanielSiepmann\DsSite\Frontend\RssFeed;
|
||||
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
class ContentRendering
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ContentObjectRenderer $contentObjectRenderer
|
||||
) {
|
||||
}
|
||||
|
||||
public function extend(array $row): array
|
||||
{
|
||||
$row['description'] = $row['data']['abstract'] . $this->getContent($row['data']['uid']);
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function getContent(int $pageUid): string
|
||||
{
|
||||
$colPositions = [
|
||||
50,
|
||||
0,
|
||||
100,
|
||||
200,
|
||||
];
|
||||
|
||||
$content = '';
|
||||
foreach ($colPositions as $colPos) {
|
||||
$content .= $this->contentObjectRenderer->cObjGetSingle('CONTENT', [
|
||||
'table' => 'tt_content',
|
||||
'select.' => [
|
||||
'orderBy' => 'sorting',
|
||||
'where' => '{#colPos}=' . $colPos,
|
||||
'pidInList' => $pageUid,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
namespace DanielSiepmann\DsSite\Frontend\RssFeed;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider;
|
||||
|
||||
/**
|
||||
* Provides dynamic for additionalWhere,
|
||||
* to only list pages for current requested category.
|
||||
*/
|
||||
class SitemapDataProvider extends RecordsXmlSitemapDataProvider
|
||||
{
|
||||
public function __construct(
|
||||
ServerRequestInterface $request,
|
||||
string $key,
|
||||
array $config = [],
|
||||
ContentObjectRenderer $cObj = null
|
||||
) {
|
||||
$categoryUid = intval($request->getQueryParams()['category_uid'] ?? 0);
|
||||
if ($categoryUid > 0) {
|
||||
$pageUids = $this->getPageUidsWithRelationToCategory($categoryUid);
|
||||
$config['additionalWhere'] = ($config['additionalWhere'] ?? '')
|
||||
. $this->createAdditionalWhereForPageUids($pageUids)
|
||||
;
|
||||
}
|
||||
|
||||
parent::__construct($request, $key, $config, $cObj);
|
||||
}
|
||||
|
||||
public function generateItems(): void
|
||||
{
|
||||
parent::generateItems();
|
||||
|
||||
$contentRendering = new ContentRendering($this->cObj);
|
||||
foreach ($this->items as $key => $item) {
|
||||
$this->items[$key] = $contentRendering->extend($item);
|
||||
}
|
||||
}
|
||||
|
||||
private function getPageUidsWithRelationToCategory(int $categoryUid): array
|
||||
{
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('pages');
|
||||
/* @var QueryBuilder $queryBuilder */
|
||||
|
||||
$queryBuilder->select('uid');
|
||||
$queryBuilder->from('pages');
|
||||
$queryBuilder->leftJoin(
|
||||
'pages',
|
||||
'sys_category_record_mm',
|
||||
'mm',
|
||||
'pages.uid = mm.uid_foreign'
|
||||
);
|
||||
$queryBuilder->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'mm.tablenames',
|
||||
$queryBuilder->createNamedParameter('pages')
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
'mm.fieldname',
|
||||
$queryBuilder->createNamedParameter('categories')
|
||||
),
|
||||
$queryBuilder->expr()->in(
|
||||
'mm.uid_local',
|
||||
$queryBuilder->createNamedParameter($categoryUid)
|
||||
)
|
||||
);
|
||||
|
||||
return array_map(function (array $row) {
|
||||
return (int) $row['uid'];
|
||||
}, $queryBuilder->executeQuery()->fetchAllAssociative());
|
||||
}
|
||||
|
||||
private function createAdditionalWhereForPageUids(array $pageUids): string
|
||||
{
|
||||
return ' AND uid IN(' . implode(',', $pageUids) . ')';
|
||||
}
|
||||
}
|
|
@ -1,167 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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.
|
||||
*/
|
||||
|
||||
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\Frontend\Controller\ErrorController;
|
||||
use TYPO3\CMS\Seo\XmlSitemap\Exception\InvalidConfigurationException;
|
||||
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemapDataProviderInterface;
|
||||
|
||||
class XmlSitemapRenderer
|
||||
{
|
||||
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;
|
||||
|
||||
$this->initialize($GLOBALS['TSFE']->tmpl->setup);
|
||||
$this->view->assign('type', $request->getAttribute('routing')?->getPageType() ?? 0);
|
||||
$sitemapType = $typoScriptConfiguration['sitemapType'] ?? 'xmlSitemap';
|
||||
if (!empty($sitemap = ($request->getQueryParams()['sitemap'] ?? null))) {
|
||||
return $this->renderSitemap($request, $sitemap, $sitemapType);
|
||||
}
|
||||
|
||||
return $this->renderIndex($request, $sitemapType);
|
||||
}
|
||||
|
||||
protected function renderIndex(ServerRequestInterface $request, string $sitemapType): string
|
||||
{
|
||||
$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
|
||||
{
|
||||
$settings = [];
|
||||
foreach (array_keys($this->typoScriptConfiguration['userFunc.']['variables.'] ?? []) as $variableName) {
|
||||
if (!is_string($variableName) || substr($variableName, -1) === '.') {
|
||||
continue;
|
||||
}
|
||||
$settings[$variableName] = $this->contentObjectRenderer->cObjGetSingle(
|
||||
$this->typoScriptConfiguration['userFunc.']['variables.'][$variableName] ?? '',
|
||||
$this->typoScriptConfiguration['userFunc.']['variables.'][$variableName . '.'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ services:
|
|||
arguments:
|
||||
- 'pages'
|
||||
|
||||
DanielSiepmann\DsSite\Frontend\RssFeed\XmlSitemapRenderer:
|
||||
DanielSiepmann\DsSite\Frontend\RssFeed\BlogPostsDataProvider:
|
||||
public: true
|
||||
|
||||
DanielSiepmann\DsSite\Backend\PreviewRenderer\Video:
|
||||
|
|
|
@ -1,30 +1,3 @@
|
|||
plugin.tx_seo {
|
||||
view {
|
||||
templateRootPaths {
|
||||
20 = EXT:ds_site/Resources/Private/Templates/Sitemaps/
|
||||
}
|
||||
}
|
||||
config {
|
||||
xmlSitemap {
|
||||
sitemaps {
|
||||
blog-posts {
|
||||
provider = DanielSiepmann\DsSite\Frontend\RssFeed\SitemapDataProvider
|
||||
config {
|
||||
table = pages
|
||||
sortField = lastUpdated
|
||||
sortOrder = DESC
|
||||
lastModifiedField = tstamp
|
||||
additionalWhere = AND no_index = 0
|
||||
pid = {$pageUids.blogPosts}
|
||||
recursive = 3
|
||||
template = RssFeed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page {
|
||||
headerData {
|
||||
10 = TEXT
|
||||
|
@ -32,7 +5,7 @@ page {
|
|||
wrap = <link rel="alternate" title="RSS Feed of all blog posts" type="application/rss+xml" href="|" />
|
||||
typolink {
|
||||
parameter = t3://page?uid=1
|
||||
additionalParams = &type=1533906435&sitemap=blog-posts
|
||||
additionalParams = &type=1707321482&feed=blog-posts
|
||||
returnLast = url
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +31,7 @@ page {
|
|||
additionalParams.stdWrap.cObject = COA
|
||||
additionalParams.stdWrap.cObject {
|
||||
10 = TEXT
|
||||
10.value = &type=1533906435&sitemap=blog-posts
|
||||
10.value = &type=1707321482&feed=blog-posts
|
||||
11 = TEXT
|
||||
11.value = &category_uid=
|
||||
12 = TEXT
|
||||
|
@ -71,11 +44,36 @@ page {
|
|||
}
|
||||
}
|
||||
}
|
||||
rssFeed = PAGE
|
||||
rssFeed {
|
||||
typeNum = 1707321482
|
||||
|
||||
seo_sitemap {
|
||||
config {
|
||||
admPanel = 0
|
||||
debug = 0
|
||||
disableAllHeaderCode = 1
|
||||
additionalHeaders {
|
||||
10 {
|
||||
userFunc = DanielSiepmann\DsSite\Frontend\RssFeed\XmlSitemapRenderer->render
|
||||
userFunc {
|
||||
header = Content-Type: application/xml;charset=utf-8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10 = FLUIDTEMPLATE
|
||||
10 {
|
||||
dataProcessing {
|
||||
10 = DanielSiepmann\DsSite\Frontend\RssFeed\BlogPostsDataProvider
|
||||
10 {
|
||||
as = pages
|
||||
table = pages
|
||||
orderBy = lastUpdated DESC
|
||||
selectFields = pages.uid, pages.abstract, pages.title, pages.lastUpdated
|
||||
where = AND no_index = 0
|
||||
pidInList = {$pageUids.blogPosts}
|
||||
recursive = 3
|
||||
}
|
||||
}
|
||||
|
||||
variables {
|
||||
categoryId = TEXT
|
||||
categoryId.data = GP:category_uid
|
||||
|
@ -83,6 +81,7 @@ seo_sitemap {
|
|||
categoryTitle = TEXT
|
||||
categoryTitle.data.dataWrap = DB : sys_category:{GP:category_uid}:title
|
||||
}
|
||||
}
|
||||
|
||||
file = EXT:ds_site/Resources/Private/Templates/RssFeed.xml
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<f:if condition="{settings.categoryId}">
|
||||
<f:if condition="{categoryId}">
|
||||
<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.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" />
|
||||
<title>Daniel Siepmann - Coding is Art - Blog Posts {categoryTitle}</title>
|
||||
<description>List of {categoryTitle} blog posts at daniel-siepmann.de</description>
|
||||
<link>{f:uri.typolink(parameter: 't3://page?uid=11', additionalParams: '&topic_uid={categoryId}', absolute: 1)}</link>
|
||||
<atom:link href="{f:uri.typolink(parameter: 't3://page?uid=1&type=1707321482', additionalParams: '&feed=blog-posts&category_uid={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.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" />
|
||||
<atom:link href="{f:uri.typolink(parameter: 't3://page?uid=1&type=1707321482', additionalParams: '&feed=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>
|
||||
<ttl>1800</ttl>
|
||||
|
||||
<f:for each="{items}" as="item">
|
||||
<f:if condition="{item.data.doktype} < 200">
|
||||
<f:for each="{pages}" as="post">
|
||||
<f:if condition="{post.data.doktype} < 200">
|
||||
{f:render(section: 'Item', arguments: {
|
||||
item: item.data,
|
||||
description: item.description
|
||||
item: post.data,
|
||||
description: post.description
|
||||
})}
|
||||
</f:if>
|
||||
</f:for>
|
Loading…
Reference in a new issue