Instantly share code, notes, and snippets.
Created
December 6, 2012 11:36
-
Star
(4)
4
You must be signed in to star a gist -
Fork
(3)
3
You must be signed in to fork a gist
-
Save bwaidelich/4223855 to your computer and use it in GitHub Desktop.
TYPO3 Flow menu with Fluid and DTOs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ul class="nav{f:if(condition: menuClass, then: ' {menuClass}')}"<f:for each="{menu.attributes}" as="attributeValue" key="attributeName"> {attributeName}="{attributeValue}"</f:for>> | |
<f:for each="{menu.menuItems}" as="menuItem" iteration="iteration"> | |
<f:if condition="{menuItem.header}"> | |
<f:then> | |
<li class="nav-header {menuItem.class}"<f:for each="{menuItem.attributes}" as="attributeValue" key="attributeName"> {attributeName}="{attributeValue}"</f:for>>{menuItem.label}</li> | |
</f:then> | |
<f:else> | |
<f:if condition="{menuItem.separator}"> | |
<f:then> | |
<li class="divider {menuItem.class}"<f:for each="{menuItem.attributes}" as="attributeValue" key="attributeName"> {attributeName}="{attributeValue}"</f:for>></li> | |
</f:then> | |
<f:else> | |
<li class="{menuItem.class}{f:if(condition: menuItem.active, then: ' active')}"<f:for each="{menuItem.attributes}" as="attributeValue" key="attributeName"> {attributeName}="{attributeValue}"</f:for>> | |
<a href="<f:uri.action action="{menuItem.targetActionName}" controller="{menuItem.targetControllerName}" arguments="{menuItem.targetActionArguments}"></f:uri.action>"> | |
{menuItem.label} | |
</a> | |
<f:if condition="{menuItem.subMenuItems}"> | |
<f:render section="subMenuItems" arguments="{subMenuItems: menuItem.subMenuItems, menu: menu}" /> | |
</f:if> | |
</li> | |
</f:else> | |
</f:if> | |
</f:else> | |
</f:if> | |
</f:for> | |
</ul> | |
<f:section name="subMenuItems"> | |
<ul class="nav nav-list nav-nested"> | |
<f:for each="{subMenuItems}" as="subMenuItem" iteration="iteration"> | |
<li class="{subMenuItem.class}{f:if(condition: subMenuItem.active, then: ' active')}"<f:for each="{subMenuItem.attributes}" as="attributeValue" key="attributeName"> {attributeName}="{attributeValue}"</f:for>> | |
<a href="<f:uri.action action="{subMenuItem.targetActionName}" controller="{subMenuItem.targetControllerName}" arguments="{subMenuItem.targetActionArguments}"></f:uri.action>"> | |
{subMenuItem.label} | |
</a> | |
</li> | |
</f:for> | |
</ul> | |
</f:section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace My\Package\Domain\Dto; | |
use TYPO3\Flow\Annotations as Flow; | |
/** | |
* Simple Menu that can be rendered with Fluid | |
*/ | |
class Menu { | |
/** | |
* @var array<\Yeebase\Guruhelp\Domain\Dto\MenuItem> | |
*/ | |
protected $menuItems; | |
/** | |
* @var array | |
*/ | |
protected $attributes = array(); | |
public function __construct(array $attributes = array()) { | |
$this->attributes = $attributes; | |
$this->menuItems = array(); | |
} | |
/** | |
* @param string $attributeName | |
* @param string $attributeValue | |
*/ | |
public function addAttribute($attributeName, $attributeValue) { | |
$this->attributes[$attributeName] = $attributeValue; | |
} | |
/** | |
* @return array | |
*/ | |
public function getAttributes() { | |
return $this->attributes; | |
} | |
/** | |
* @return array | |
*/ | |
public function getMenuItems() { | |
return $this->menuItems; | |
} | |
/** | |
* Adds a menu item to the end of this menu | |
* | |
* @param MenuItem $menuItem | |
* @return Menu the current instance to enable method chaining | |
*/ | |
public function addMenuItem(\Yeebase\Guruhelp\Domain\Dto\MenuItem $menuItem) { | |
$this->menuItems[] = $menuItem; | |
return $this; | |
} | |
/** | |
* @param string $label | |
* @param string $targetControllerName if omitted, the resulting menu item is a separator/menu header | |
* @param string $targetActionName | |
* @param array $targetActionArguments | |
* @return Menu the current instance to enable method chaining | |
*/ | |
public function createMenuItem($label, $targetControllerName = NULL, $targetActionName = NULL, array $targetActionArguments = array()) { | |
$this->menuItems[] = new MenuItem($label, $targetControllerName, $targetActionName, $targetActionArguments); | |
return $this; | |
} | |
/** | |
* @param \TYPO3\Flow\Mvc\ActionRequest $request | |
* @return void | |
*/ | |
public function setActiveMenuItem(\TYPO3\Flow\Mvc\ActionRequest $request) { | |
foreach ($this->menuItems as $menuItem) { | |
$menuItem->setActive($menuItem->matchesRequest($request)); | |
foreach ($menuItem->getSubMenuItems() as $subMenuItem) { | |
$subMenuItem->setActive($subMenuItem->matchesRequest($request)); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace My\Package\Domain\Dto; | |
use TYPO3\Flow\Annotations as Flow; | |
/** | |
* A Menu item | |
*/ | |
class MenuItem { | |
/** | |
* @Flow\Inject | |
* @var \TYPO3\Flow\Persistence\PersistenceManagerInterface | |
*/ | |
protected $persistenceManager; | |
/** | |
* @var string | |
*/ | |
protected $label = ''; | |
/** | |
* @var boolean | |
*/ | |
protected $active = FALSE; | |
/** | |
* @var string | |
*/ | |
protected $targetControllerName; | |
/** | |
* @var string | |
*/ | |
protected $targetActionName; | |
/** | |
* @var array | |
*/ | |
protected $targetActionArguments = array(); | |
/** | |
* @var array<MenuItem> | |
*/ | |
protected $subMenuItems = array(); | |
/** | |
* @var array | |
*/ | |
protected $attributes = array(); | |
/** | |
* @param string $label | |
* @param string $targetControllerName | |
* @param string $targetActionName | |
* @param array $targetActionArguments | |
* @param array $attributes | |
*/ | |
public function __construct($label, $targetControllerName = NULL, $targetActionName = NULL, array $targetActionArguments = array(), array $attributes = array()) { | |
$this->label = $label; | |
$this->targetControllerName = $targetControllerName; | |
$this->targetActionName = $targetActionName; | |
$this->targetActionArguments = $targetActionArguments; | |
$this->attributes = $attributes; | |
} | |
/** | |
* @param string $attributeName | |
* @param string $attributeValue | |
*/ | |
public function addAttribute($attributeName, $attributeValue) { | |
$this->attributes[$attributeName] = $attributeValue; | |
} | |
/** | |
* @return array | |
*/ | |
public function getAttributes() { | |
return $this->attributes; | |
} | |
/** | |
* returns TRUE if the given $request points to the controller/action specified in this menu item | |
* | |
* @param \TYPO3\Flow\Mvc\ActionRequest $request | |
* @return boolean TRUE if this menuItem is active for the given $request, otherwise FALSE | |
*/ | |
public function matchesRequest(\TYPO3\Flow\Mvc\ActionRequest $request) { | |
if ($this->isHeader()) { | |
return FALSE; | |
} | |
if ($this->getTargetControllerName() === $request->getControllerName()) { | |
if ($this->getTargetActionName() === NULL) { | |
return TRUE; | |
} | |
if ($this->targetActionName !== $request->getControllerActionName()) { | |
return FALSE; | |
} | |
$targetActionArguments = $this->getTargetActionArguments(); | |
$targetActionArguments = $this->persistenceManager->convertObjectsToIdentityArrays($targetActionArguments); | |
\TYPO3\Flow\Utility\Arrays::sortKeysRecursively($targetActionArguments); | |
$requestArguments = $request->getArguments(); | |
\TYPO3\Flow\Utility\Arrays::sortKeysRecursively($requestArguments); | |
return ($targetActionArguments === $requestArguments); | |
} | |
return FALSE; | |
} | |
/** | |
* @param boolean $active | |
*/ | |
public function setActive($active) { | |
$this->active = (boolean)$active; | |
} | |
/** | |
* @return boolean | |
*/ | |
public function isActive() { | |
return $this->active; | |
} | |
/** | |
* @param string $label | |
*/ | |
public function setLabel($label) { | |
$this->label = $label; | |
} | |
/** | |
* @return string | |
*/ | |
public function getLabel() { | |
return $this->label; | |
} | |
/** | |
* @param string $targetController | |
* @return void | |
*/ | |
public function setTargetControllerName($targetController) { | |
$this->targetControllerName = $targetController; | |
} | |
/** | |
* @return string | |
*/ | |
public function getTargetControllerName() { | |
return $this->targetControllerName; | |
} | |
/** | |
* @param string $targetActionName | |
* @return void | |
*/ | |
public function setTargetActionName($targetActionName) { | |
$this->targetActionName = $targetActionName; | |
} | |
/** | |
* @return string | |
*/ | |
public function getTargetActionName() { | |
return $this->targetActionName; | |
} | |
/** | |
* @param array $targetActionArguments | |
*/ | |
public function setTargetActionArguments(array $targetActionArguments) { | |
$this->targetActionArguments = $targetActionArguments; | |
} | |
/** | |
* @return array | |
*/ | |
public function getTargetActionArguments() { | |
return $this->targetActionArguments; | |
} | |
/** | |
* @return boolean TRUE if this menu item is just a header | |
*/ | |
public function isHeader() { | |
return $this->targetControllerName === NULL && $this->label !== ''; | |
} | |
/** | |
* @return boolean TRUE if this menu item is just a separator | |
*/ | |
public function isSeparator() { | |
return $this->label === ''; | |
} | |
/** | |
* @return string the normalized target controller & action name that can be used to render the css class of an menu item | |
*/ | |
public function getClass() { | |
$class = str_replace('\\', '-', $this->targetControllerName); | |
if ($this->targetActionName !== NULL) { | |
$class = sprintf('%s-%s', $class, $this->targetActionName); | |
} | |
return strtolower($class); | |
} | |
/** | |
* @param array<MenuItem> $subMenuItems | |
*/ | |
public function setSubMenuItems(array $subMenuItems) { | |
$this->subMenuItems = $subMenuItems; | |
} | |
/** | |
* @return array<MenuItem> | |
*/ | |
public function getSubMenuItems() { | |
return $this->subMenuItems; | |
} | |
/** | |
* @param MenuItem $subMenuItem | |
* @return MenuItem the current instance to enable method chaining | |
*/ | |
public function addSubMenuItem(MenuItem $subMenuItem) { | |
$this->subMenuItems[] = $subMenuItem; | |
return $this; | |
} | |
/** | |
* @return boolean | |
*/ | |
public function hasSubMenuItems() { | |
return $this->subMenuItems !== array(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment