From my research, there is such information in RouteResult instance in the public method getMatchedRouteName(). The problem is how to reach to this instance from the View.
We know that we can get RouteResult, but from the Request object which is in a Middleware's __invoke() method.
public function __invoke($request, $response, $next){
# instance of RouteResult
$routeResult = $request->getAttribute('Zend\Expressive\Router\RouteResult');
$routeName = $routeResult->getMatchedRouteName();
// ...
}
As @timdev recommended we will find inspiration in existing helper UrlHelper and make almost the same implementation in custom View Helper.
In short we will create 2 classes.
- CurrentUrlHelper with method setRouteResult() and
- CurrentUrlMiddleware with __invoke($req, $res, $next)
We will inject the CurrentUrlHelper in CurrentUrlMiddleware and
in __invoke() method call the CurrentUrlHelper::setRouteResult() with appropriate RouteResult instance.
Later we can use our CurrentUrlHelper with RouteResult instance in it. Both classes should have an Factory too.
class CurrentUrlMiddlewareFactory {
public function __invoke(ContainerInterface $container) {
return new CurrentUrlMiddleware(
$container->get(CurrentUrlHelper::class)
);
}
}
class CurrentUrlMiddleware {
private $currentUrlHelper;
public function __construct(CurrentUrlHelper $currentUrlHelper) {
$this->currentUrlHelper = $currentUrlHelper;
}
public function __invoke($request, $response, $next = null) {
$result = $request->getAttribute('Zend\Expressive\Router\RouteResult');
$this->currentUrlHelper->setRouteResult($result);
return $next($request, $response); # continue with execution
}
}
And our new helper:
class CurrentUrlHelper {
private $routeResult;
public function __invoke($name) {
return $this->routeResult->getMatchedRouteName() === $name;
}
public function setRouteResult(RouteResult $result) {
$this->routeResult = $result;
}
}
class CurrentUrlHelperFactory{
public function __invoke(ContainerInterface $container){
# pull out CurrentUrlHelper from container!
return $container->get(CurrentUrlHelper::class);
}
}
Now we only need to register our new View Helper and Middleware in the configs:
dependencies.global.php
'dependencies' => [
'invokables' => [
# dont have any constructor!
CurrentUrlHelper::class => CurrentUrlHelper::class,
],
]
middleware-pipeline.global.php
'factories' => [
CurrentUrlMiddleware::class => CurrentUrlMiddlewareFactory::class,
],
'middleware' => [
Zend\Expressive\Container\ApplicationFactory::ROUTING_MIDDLEWARE,
Zend\Expressive\Helper\UrlHelperMiddleware::class,
CurrentUrlMiddleware::class, # Our new Middleware
Zend\Expressive\Container\ApplicationFactory::DISPATCH_MIDDLEWARE,
],
And finaly we can register our View Helper in templates.global.php
'view_helpers' => [
'factories' => [
# use factory to grab an instance of CurrentUrlHelper
'currentRoute' => CurrentUrlHelperFactory::class
]
],
it's important to register our middleware after ROUTING_MIDDLEWARE and before DISPATCH_MIDDLEWARE!
Also, we have CurrentUrlHelperFactory only to assign it to the key 'currentRoute'.
Now you can use helper in any template file :)
<?php // in layout.phtml file
$index_css = $this->currentRoute('home-page') ? 'active' : 'none';
$about_css = $this->currentRoute('about') ? 'active' : 'none';
$contact_css = $this->currentRoute('contact') ? 'active' : 'none';
?>