Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jokumer/35adfba22905a0b3d0255f39a0704d2e to your computer and use it in GitHub Desktop.
Save jokumer/35adfba22905a0b3d0255f39a0704d2e to your computer and use it in GitHub Desktop.
TYPO3 9.5 SEO Sitemap for TxNews

Example XML sitemap rendering for news with TYPO3 9.5

To render Google compliant news sitemap with TYPO3 version 9.5 with its included SEO extension and thirdparty news extension from Georg Ringer, this example is a quick start you can embed in your own project.

It follows the recommended XML scheme from Google Google News Sitemaps

Requirements

You need to use a project or sitepackage extension in your TYPO3 installation (see also Sitepackage builder).

How to

Given, you already have installed TYPO3 9 system extension seo and included static TypoScript for it...

You need to embed following two files in your project or sitepackage extension:

  • TxNewsGoogleXmlSitemapDataProvider.php - PHP class as data provider for news XML sitemap /Classes/XmlSitemap/TxNewsGoogleXmlSitemapDataProvider.php
  • GoogleNews.xml - FLUID template for news sitemap /Resources/Private/Templates/XmlSitemap/GoogleNews.xml

Include TypoScript setup.typoscript in your setup to use provider class and FLUID template for rendering.

Adjustments

  • Adjust PHP namespace definitions for vendor and sitepackage in TxNewsGoogleXmlSitemapDataProvider.php compared to your project or sitepackage extension (Vendor\Sitepackage)
  • Adjust TypoScript and specify at least provider class, pid and pageId in TypoScript compared to your page ID's in your installation:
    • plugin.tx_seo.config.xmlSitemap.sitemaps.TxNewsGoogle.provider = Vendor\Sitepackage\XmlSitemap\TxNewsGoogleXmlSitemapDataProvider
    • plugin.tx_seo.config.xmlSitemap.sitemaps.TxNewsGoogle.config.pid ... storage page for News
    • plugin.tx_seo.config.xmlSitemap.sitemaps.TxNewsGoogle.config.url.pageId ... detail view page for News
    • See also API/XML Sitemap

Improvements

You are free to use and adopt this solution. Hints are appreciated. Improvements will help other projects. Leave a comment or link - maybe our contribution will be embed in news extension in future.

<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="{xslFile}"?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
<f:for each="{items}" as="item"><f:if condition="{item.loc}">
<url>
<loc>{item.loc}</loc>
<lastmod>{item.lastMod -> f:format.date(format: 'c')}</lastmod>
<news:news>
<news:publication>
<news:name>{item.name}</news:name>
<news:language>{item.language}</news:language>
</news:publication>
<f:if condition="{item.access}"><news:access>{item.access}</news:access></f:if>
<f:if condition="{item.genres}"><news:genres>{item.genres -> f:format.htmlspecialchars()}</news:genres></f:if>
<news:publication_date>{item.publication_date -> f:format.date(format: 'c')}</news:publication_date>
<news:title>{item.title -> f:format.htmlspecialchars()}</news:title>
<f:if condition="{item.data.keywords}"><news:keywords>{item.data.keywords -> f:format.htmlspecialchars()}</news:keywords></f:if>
<f:if condition="{item.stock_tickers}"><news:stock_tickers>{item.stock_tickers}</news:stock_tickers></f:if>
</news:news>
</url>
</f:if></f:for>
</urlset>
plugin.tx_seo {
view {
templateRootPaths.100 = EXT:sitepackage/Resources/Private/Templates/XmlSitemap/
partialRootPaths.100 = EXT:sitepackage/Resources/Private/Templates/XmlSitemap/
layoutRootPaths.100 = EXT:sitepackage/Resources/Private/Templates/XmlSitemap/
}
config.xmlSitemap.sitemaps {
TxNewsGoogle {
provider = Vendor\Sitepackage\XmlSitemap\TxNewsGoogleXmlSitemapDataProvider
config {
table = tx_news_domain_model_news
sortField = sorting
lastModifiedField = tstamp
pid = <page id('s) containing news records>
recursive = 1
url {
pageId = <your detail page id>
fieldToParameterMap {
uid = tx_news_pi1[news]
}
additionalGetParameters {
tx_news_pi1.controller = News
tx_news_pi1.action = detail
}
useCacheHash = 1
}
template = GoogleNews
itemOverrides {
// Publication/Name of the news publication
name =
// Publication/Language of the publication. It should be an ISO 639 Language Code
language =
// Accessibility of the article. Required if access is not open
access =
// Comma-separated list of properties characterizing the content of the article
genres =
// Comma-separated list of up to 5 stock tickers
stock_tickers =
}
}
}
}
}
<?php
namespace Vendor\Sitepackage\XmlSitemap;
/*
* 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.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider;
use TYPO3\CMS\Seo\XmlSitemap\Exception\MissingConfigurationException;
/**
* Class TxNewsGoogleXmlSitemapDataProvider
*
* @package TYPO3
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 2 or later
*/
class TxNewsGoogleXmlSitemapDataProvider extends RecordsXmlSitemapDataProvider
{
/**
* Generate Items
*
* @throws MissingConfigurationException
*/
public function generateItems(): void
{
parent::generateItems();
$this->resolveRequiredValues();
$this->overrideValuesByConfiguration();
}
/**
* Resolve item values for minimum requirements
*/
protected function resolveRequiredValues(): void
{
if (!empty($this->items)) {
foreach ($this->items as &$item) {
// publication -> name
if (!isset($item['name']) || empty($item['name']))
$item['name'] = $GLOBALS['TSFE']->tmpl->sitetitle ? : $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
// publication -> language
if (!isset($item['language']) || empty($item['language']))
$item['language'] = $GLOBALS['TSFE']->lang; // @todo get iso code by $item['data']['sys_language_uid'];
// publication_date
if (!isset($item['publication_date']) || empty($item['publication_date']))
$item['publication_date'] = date('c', $item['data']['datetime']);
// title
if (!isset($item['title']) || empty($item['title']))
$item['title'] = htmlspecialchars($item['data']['title']);
}
}
}
/**
* Override Item values with typoscript configuration
*/
protected function overrideValuesByConfiguration(): void
{
if (!empty($this->items)) {
if (isset($this->config['itemOverrides']) && !empty($this->config['itemOverrides'])) {
foreach ($this->items as &$item) {
foreach ($this->config['itemOverrides'] as $key => $value) {
if (!empty($value)) {
if (is_array($value)) {
foreach ($value as $subKey => $subValue) {
if (!empty($subValue)) {
$item[$key][$subKey] = $subValue;
}
}
} else {
$item[$key] = $value;
}
}
}
}
}
}
}
}
@Treedent
Copy link

Hi,
what is then, the url to access to the news sitemap?
I have done all the process of your tuto, but can't see any additionnal site map in the TYPO3 XML Sitemap index.

Thanks.

@christianbaer
Copy link

@jokumer
Copy link
Author

jokumer commented Jun 17, 2019

Or with routing for human readable urls http://local.domain.org/newssitemap.xml

routes:
- route: newssitemap.xml
  type: uri
  source: 't3://page?type=1533906435'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment