Add feeds per category

This commit is contained in:
Daniel Siepmann 2021-02-12 11:42:35 +01:00
parent d8eb401e5b
commit 04753f82a2
6 changed files with 216 additions and 9 deletions

View file

@ -0,0 +1,99 @@
<?php
namespace DanielSiepmann\DsSite\Frontend\RssFeed;
/*
* 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.
*/
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'] ?? 0);
if ($categoryUid > 0) {
$pageUids = $this->getPageUidsWithRelationToCategory($categoryUid);
$config['additionalWhere'] = ($config['additionalWhere'] ?? '')
. $this->createAdditionalWhereForPageUids($pageUids)
;
}
parent::__construct($request, $key, $config, $cObj);
}
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)
)
);
$result = $queryBuilder->execute()->fetchAll();
if ($result === false) {
return [];
}
return array_map(function (array $row) {
return (int) $row['uid'];
}, $result);
}
private function createAdditionalWhereForPageUids(array $pageUids): string
{
return ' AND uid IN(' . implode(',', $pageUids) . ')';
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace DanielSiepmann\DsSite\Frontend\RssFeed;
/*
* 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.
*/
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Seo\XmlSitemap\XmlSitemapRenderer as Typo3XmlSitemapRenderer;
class XmlSitemapRenderer extends Typo3XmlSitemapRenderer
{
/**
* @var ContentObjectRenderer
*/
public $cObj;
public function render(string $_, array $typoScriptConfiguration): string
{
$settings = [];
foreach (array_keys($typoScriptConfiguration['userFunc.']['variables.'] ?? []) as $variableName) {
if (substr($variableName, -1) === '.') {
continue;
}
$settings[$variableName] = $this->cObj->cObjGetSingle(
$typoScriptConfiguration['userFunc.']['variables.'][$variableName] ?? '',
$typoScriptConfiguration['userFunc.']['variables.'][$variableName . '.'] ?? []
);
}
$this->view->assign('settings', $settings);
return parent::render($_, $typoScriptConfiguration);
}
}

View file

@ -30,7 +30,7 @@ services:
$view: '@dashboard.views.widget' $view: '@dashboard.views.widget'
$cache: '@cache.dashboard.rss' $cache: '@cache.dashboard.rss'
$options: $options:
feedUrl: 'https://daniel-siepmann.de/feed/rssFeedAllBlogPosts/sitemap.xml' feedUrl: 'https://daniel-siepmann.de/rss-feed/blog-posts.xml'
limit: 3 limit: 3
tags: tags:
- name: dashboard.widget - name: dashboard.widget

View file

@ -7,8 +7,8 @@ plugin.tx_seo {
config { config {
xmlSitemap { xmlSitemap {
sitemaps { sitemaps {
rssFeedAllBlogPosts { blog-posts {
provider = TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider provider = DanielSiepmann\DsSite\Frontend\RssFeed\SitemapDataProvider
config { config {
table = pages table = pages
sortField = lastUpdated sortField = lastUpdated
@ -31,9 +31,57 @@ page {
wrap = <link rel="alternate" title="RSS Feed of all blog posts" type="application/rss+xml" href="|" /> wrap = <link rel="alternate" title="RSS Feed of all blog posts" type="application/rss+xml" href="|" />
typolink { typolink {
parameter = t3://page?uid=1 parameter = t3://page?uid=1
additionalParams = &type=1533906435&sitemap=rssFeedAllBlogPosts additionalParams = &type=1533906435&sitemap=blog-posts
returnLast = url
}
}
11 = COA
11 {
if {
isTrue.stdWrap.data = GP:topic_id
}
1 = TEXT
1.char = 10
2 = TEXT
2 {
noTrimWrap = |<link rel="alternate" title="RSS Feed of blog posts for topic: |" type="application/rss+xml"|
data.dataWrap = DB : sys_category:{GP:topic_id}:title
}
3 = TEXT
3.char = 32
4 = TEXT
4 {
wrap = href="|" />
typolink {
parameter = t3://page?uid=1
additionalParams.stdWrap.cObject = COA
additionalParams.stdWrap.cObject {
10 = TEXT
10.value = &type=1533906435&sitemap=blog-posts
11 = TEXT
11.value = &category=
12 = TEXT
// uid is casted to int within PHP source
12.data.dataWrap = DB : sys_category:{GP:topic_id}:uid
}
returnLast = url returnLast = url
} }
} }
} }
} }
}
seo_sitemap {
10 {
userFunc = DanielSiepmann\DsSite\Frontend\RssFeed\XmlSitemapRenderer->render
userFunc {
variables {
categoryId = TEXT
categoryId.data = GP:category
categoryId.intval = 1
categoryTitle = TEXT
categoryTitle.data.dataWrap = DB : sys_category:{GP:category}:title
}
}
}
}

View file

@ -1,7 +1,7 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true"> data-namespace-typo3-fluid="true">
<nav> <nav>
<a rel="alternate" title="RSS Feed of all blog posts" type="application/rss+xml" href="{f:uri.page(pageUid: 1, pageType: 1533906435, additionalParams: {sitemap: 'rssFeedAllBlogPosts'})}">RSS Feed</a> <a rel="alternate" title="RSS Feed of all blog posts" type="application/rss+xml" href="{f:uri.page(pageUid: 1, pageType: 1533906435, additionalParams: {sitemap: 'blog-posts'})}">RSS Feed</a>
<a rel="me" href="https://fosstodon.org/@daniels">at Mastodon</a> <a rel="me" href="https://fosstodon.org/@daniels">at Mastodon</a>
<a href="https://gitea.daniel-siepmann.de/danielsiepmann">My Gitea</a> <a href="https://gitea.daniel-siepmann.de/danielsiepmann">My Gitea</a>
<f:for each="{pages}" as="page"> <f:for each="{pages}" as="page">

View file

@ -1,10 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel> <channel>
<title>Daniel Siepmann - Coding is Art</title> <f:if condition="{settings.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.page(pageUid: 11, additionalParams: {topic_id: settings.categoryId}, absolute: 1)}</link>
<atom:link href="{f:uri.page(pageUid: 1. pageType: 1533906435, additionalParams: {sitemap: 'blog-posts', category: 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> <description>List of blog posts at daniel-siepmann.de</description>
<link>{f:uri.page(pageUid: 1, absolute: 1)}</link> <link>{f:uri.page(pageUid: 1, absolute: 1)}</link>
<atom:link href="{f:uri.page(pageUid: 1. pageType: 1533906435, additionalParams: {sitemap: 'rssFeedAllBlogPosts'}, absolute: 1)}" rel="self" type="application/rss+xml" /> <atom:link href="{f:uri.page(pageUid: 1. pageType: 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> <lastBuildDate>{f:format.date(date: 'now', format: 'D, d M Y H:i:s O')}</lastBuildDate>
<ttl>1800</ttl> <ttl>1800</ttl>