Skip to content

Commit

Permalink
[FEATURE] Configuration option for automatic embedding of a breadcrum…
Browse files Browse the repository at this point in the history
…b in pages

Resolves: #20
  • Loading branch information
brotkrueml committed Sep 13, 2019
1 parent f13648f commit 40ea659
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. This projec
## [Unreleased]

### Added
- Configuration option for automatic embedding of a breadcrumb in pages (#20)
- Choice where to place markup: head or body section (#21)
- API for retrieving lists of types (#19)

Expand Down
108 changes: 108 additions & 0 deletions Classes/Middleware/BreadcrumbList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php
declare(strict_types = 1);

namespace Brotkrueml\Schema\Middleware;

/*
* This file is part of the "schema" extension for TYPO3 CMS.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/

use Brotkrueml\Schema\Core\Model\AbstractType;
use Brotkrueml\Schema\Manager\SchemaManager;
use Brotkrueml\Schema\Model\Type;
use Brotkrueml\Schema\Utility\Utility;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

final class BreadcrumbList implements MiddlewareInterface
{
/** @var TypoScriptFrontendController */
private $controller;

/** @var SchemaManager */
private $schemaManager;

/** @var ExtensionConfiguration */
private $configuration;

/** @var object|ContentObjectRenderer */
private $contentObjectRenderer;

public function __construct(
TypoScriptFrontendController $controller = null,
SchemaManager $schemaManager = null,
ExtensionConfiguration $configuration = null,
ContentObjectRenderer $contentObjectRenderer = null
) {
$this->controller = $controller ?: $GLOBALS['TSFE'];
$this->schemaManager = $schemaManager ?: GeneralUtility::makeInstance(SchemaManager::class);
$this->configuration = $configuration ?: GeneralUtility::makeInstance(ExtensionConfiguration::class);
$this->contentObjectRenderer = $contentObjectRenderer ?: GeneralUtility::makeInstance(ContentObjectRenderer::class);
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
/** @noinspection PhpUnhandledExceptionInspection */
$shouldEmbedBreadcrumbMarkup = (bool)$this->configuration->get('schema', 'automaticBreadcrumbSchemaGeneration');

if ($shouldEmbedBreadcrumbMarkup) {
$rootLine = [];
foreach ($this->controller->rootLine as $page) {
if ($page['is_siteroot']) {
break;
}

if ($page['nav_hide']) {
continue;
}

$rootLine[] = $page;
}

if (!empty($rootLine)) {
\sort($rootLine);
$this->buildBreadCrumbList($rootLine);
}
}

return $handler->handle($request);
}

private function buildBreadCrumbList(array $rootLine): void
{
$breadcrumbList = (new Type\BreadcrumbList());
foreach ($rootLine as $index => $page) {
$givenItemTypeClass = Utility::getNamespacedClassNameForType($page['tx_schema_webpagetype']);
$webPageTypeClass = $givenItemTypeClass ?: Type\WebPage::class;

/** @var AbstractType $itemType */
$itemType = new $webPageTypeClass();

$link = $this->contentObjectRenderer->typoLink_URL([
'parameter' => $page['uid'],
'forceAbsoluteUrl' => true,
]);

$itemType->setId($link);

$item = (new Type\ListItem())->setProperties([
'position' => $index + 1,
'name' => $page['nav_title'] ?: $page['title'],
'item' => $itemType,
]);

$breadcrumbList->addProperty('itemListElement', $item);
}

$this->schemaManager->addType($breadcrumbList);
}
}
7 changes: 6 additions & 1 deletion Configuration/RequestMiddlewares.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?php
/** @noinspection PhpFullyQualifiedNameUsageInspection */
return [
'frontend' => [
'brotkrueml/schema/webpage-type' => [
Expand All @@ -8,5 +7,11 @@
'typo3/cms-frontend/content-length-headers',
],
],
'brotkrueml/schema/breadcrumblist' => [
'target' => \Brotkrueml\Schema\Middleware\BreadcrumbList::class,
'before' => [
'typo3/cms-frontend/content-length-headers',
],
],
],
];
17 changes: 17 additions & 0 deletions Documentation/Configuration/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@ and defaults to :ref:`WebPage <web-page-type>`.
enabled


.. _configuration-automaticBreadcrumbSchemaGeneration:

basic.automaticBreadcrumbSchemaGeneration
-----------------------------------------

If this option is enabled, the breadcrumb is automatically generated from the rootline of the current page.

:aspect:`Default value`

disabled

.. NOTE::

Since multiple breadcrumbs are allowed for a page, this option adds a breadcrumb to the possibly already existing ones
(e.g. defined via the :ref:`API <breadcrumb-api>` or the :ref:`view helpers <breadcrumb-viewhelpers>`).


.. _configuration-embedMarkupInBodySection:

basic.embedMarkupInBodySection
Expand Down
4 changes: 4 additions & 0 deletions Documentation/Developer/Breadcrumb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ There can also be more than one breadcrumb on a page, Google gives an example in
`breadcrumb <https://developers.google.com/search/docs/data-types/breadcrumb>`__.


.. _breadcrumb-api:

Using the API
=============

Expand Down Expand Up @@ -94,6 +96,8 @@ This results in the following schema markup:
As you can see, the breadcrumb is embedded in a ``WebPage`` automatically.


.. _breadcrumb-viewhelpers:

Using the view helpers
======================

Expand Down
Binary file modified Documentation/Images/Configuration/ExtensionConfiguration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Resources/Private/Language/locallang.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<xliff version="1.0">
<file source-language="en" datatype="plaintext" original="messages" date="2019-09-12T18:32:21Z">
<body>
<trans-unit id="config.automaticBreadcrumbSchemaGeneration">
<source><![CDATA[Automatic embedding of the breadcrumb markup into the page]]></source>
</trans-unit>
<trans-unit id="config.automaticWebPageSchemaGeneration">
<source><![CDATA[Automatic embedding of the WebPage schema into the page]]></source>
</trans-unit>
Expand Down
Loading

0 comments on commit 40ea659

Please sign in to comment.