Skip to content

Instantly share code, notes, and snippets.

@Sebobo
Last active February 21, 2018 11:16
Show Gist options
  • Save Sebobo/7b12f8e46778321f7b1b02d4b9aaad85 to your computer and use it in GitHub Desktop.
Save Sebobo/7b12f8e46778321f7b1b02d4b9aaad85 to your computer and use it in GitHub Desktop.
Modified node route part handler for Neos 2.* for hiding url path segments of specific pages in the frontend url generation
<?php
namespace Vendor\Package\Routing;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Neos\Domain\Service\SiteService;
use TYPO3\TYPO3CR\Domain\Model\NodeInterface;
use TYPO3\Neos\Routing\Exception as Exception;
/**
* A route part handler for finding nodes specifically in the website's frontend.
*/
class FrontendNodeRoutePartHandler extends \TYPO3\Neos\Routing\FrontendNodeRoutePartHandler
{
/**
* @param string $requestPath
* @return string
*/
protected function getWorkspaceName($requestPath)
{
$contextPathParts = array();
if ($requestPath !== '' && strpos($requestPath, '@') !== false) {
preg_match(NodeInterface::MATCH_PATTERN_CONTEXTPATH, $requestPath, $contextPathParts);
}
return isset($contextPathParts['WorkspaceName']) && $contextPathParts['WorkspaceName'] !== '' ? $contextPathParts['WorkspaceName'] : 'live';
}
/**
* @inheritdoc
*/
protected function getRelativeNodePathByUriPathSegmentProperties(NodeInterface $siteNode, $relativeRequestPath)
{
/** @var NodeInterface $node */
$node = $siteNode;
$relativeNodePathSegments = array();
$workspaceName = $this->getWorkspaceName($relativeRequestPath);
foreach (explode('/', $relativeRequestPath) as $pathSegment) {
$node = $this->findNextNodeWithPathSegmentRecursively($node, $pathSegment, $relativeNodePathSegments,
$workspaceName);
if ($node === null) {
return false;
}
}
return implode('/', $relativeNodePathSegments);
}
/**
* @param NodeInterface $startingNode
* @param string $pathSegment
* @param array $relativeNodePathSegments
* @param string $workspaceName
* @return NodeInterface
*/
protected function findNextNodeWithPathSegmentRecursively(
NodeInterface $startingNode,
$pathSegment,
&$relativeNodePathSegments,
$workspaceName
) {
/** @var NodeInterface $node */
foreach ($startingNode->getChildNodes('TYPO3.Neos:Document') as $node) {
if ($workspaceName == 'live' && $node->hasProperty('hideSegmentInUriPath') && $node->getProperty('hideSegmentInUriPath') == true) {
$foundNode = $this->findNextNodeWithPathSegmentRecursively($node, $pathSegment,
$relativeNodePathSegments, $workspaceName);
if ($foundNode !== null) {
array_unshift($relativeNodePathSegments, $node->getName());
return $foundNode;
}
}
if ($node->getProperty('uriPathSegment') === $pathSegment) {
$relativeNodePathSegments[] = $node->getName();
return $node;
}
}
return null;
}
/**
* @inheritdoc
*/
protected function getRequestPathByNode(NodeInterface $node)
{
if ($node->getParentPath() === SiteService::SITES_ROOT_PATH) {
return '';
}
$startingNode = $node;
$workspaceName = $node->getContext()->getWorkspaceName();
if ($workspaceName !== 'live') {
return parent::getRequestPathByNode($node);
}
$requestPathSegments = array();
while ($node->getParentPath() !== SiteService::SITES_ROOT_PATH && $node instanceof NodeInterface) {
if (!$node->hasProperty('uriPathSegment')) {
throw new Exception\MissingNodePropertyException(sprintf('Missing "uriPathSegment" property for node "%s". Nodes can be migrated with the "flow node:repair" command.',
$node->getPath()), 1415020326);
}
if ($startingNode === $node || !$node->hasProperty('hideSegmentInUriPath') || !$node->getProperty('hideSegmentInUriPath') == true) {
$pathSegment = $node->getProperty('uriPathSegment');
$requestPathSegments[] = $pathSegment;
}
$node = $node->getParent();
if ($node === null || !$node->isVisible()) {
return '';
}
}
return implode('/', array_reverse($requestPathSegments));
}
}
'Vendor.Package:HideSegmentMixin':
abstract: true
properties:
hideSegmentInUriPath:
type: boolean
ui:
label: 'Hide page url segment in URLs'
inspector:
group: 'redirect'
TYPO3\Neos\Routing\FrontendNodeRoutePartHandlerInterface:
className: Vendor\Package\Routing\FrontendNodeRoutePartHandler
@breadlesscode
Copy link

breadlesscode commented Feb 21, 2018

Thanks for this nice gist!

I made a package of this feature: https://github.com/breadlesscode/neos-nodetypes-folder

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