Skip to content

Commit 7ffaa1e

Browse files
authored
Merge pull request #286 from dotkernel/issue-282
Issue #282: Show current page as active/open in left menu
2 parents 9a4afd5 + 2fdd8ff commit 7ffaa1e

File tree

9 files changed

+129
-25
lines changed

9 files changed

+129
-25
lines changed

config/autoload/templates.global.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare(strict_types=1);
44

5+
use Admin\App\Twig\Extension\RouteExtension;
56
use Dot\Twig\Extension\DateExtension;
67
use Dot\Twig\Extension\TranslationExtension;
78
use Laminas\ServiceManager\Factory\InvokableFactory;
@@ -31,6 +32,7 @@
3132
'cache_dir' => 'data/cache/twig',
3233
'extensions' => [
3334
DateExtension::class,
35+
RouteExtension::class,
3436
TranslationExtension::class,
3537
],
3638
'globals' => [

public/css/app.css

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/js/app.js

Lines changed: 13 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
$(document).ready(function () {
22
$('[data-toggle="tooltip"]').tooltip();
3+
4+
$('.current-route').closest('.nav-group').addClass('open');
35
});

src/App/assets/js/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ import './components/_googleMaps';
1717
import './components/_util';
1818
import './components/_bsTable';
1919
import './components/_admin';
20+
import './components/_main';

src/App/src/ConfigProvider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Admin\App\Factory\FormsPluginFactory;
1111
use Admin\App\Plugin\FormsPlugin;
1212
use Admin\App\Resolver\EntityListenerResolver;
13+
use Admin\App\Twig\Extension\RouteExtension;
1314
use Doctrine\ORM\EntityManager;
1415
use Doctrine\ORM\EntityManagerInterface;
1516
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
@@ -44,6 +45,7 @@ public function getDependencies(): array
4445
PageController::class => AttributedServiceFactory::class,
4546
PluginManager::class => PluginManagerFactory::class,
4647
FormsPlugin::class => FormsPluginFactory::class,
48+
RouteExtension::class => AttributedServiceFactory::class,
4749
],
4850
'aliases' => [
4951
EntityManager::class => 'doctrine.entity_manager.orm_default',
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Admin\App\Twig\Extension;
6+
7+
use Dot\DependencyInjection\Attribute\Inject;
8+
use Mezzio\Helper\UrlHelper;
9+
use Twig\Extension\AbstractExtension;
10+
use Twig\TwigFunction;
11+
12+
class RouteExtension extends AbstractExtension
13+
{
14+
#[Inject(UrlHelper::class)]
15+
public function __construct(
16+
private readonly UrlHelper $urlHelper,
17+
) {
18+
}
19+
20+
public function getFunctions(): array
21+
{
22+
return [
23+
new TwigFunction('getCurrentRoute', [$this, 'getCurrentRoute']),
24+
];
25+
}
26+
27+
public function getCurrentRoute(): ?string
28+
{
29+
return $this->urlHelper->getRequest()?->getUri()?->getPath();
30+
}
31+
}

src/App/templates/partial/left-menu.html.twig

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{% set currentRoute = getCurrentRoute() %}
12
<div class="sidebar">
23
<div class="sidebar-inner">
34
<div class="sidebar-logo">
@@ -19,7 +20,7 @@
1920
</div>
2021
<div class="peer">
2122
<div class="mobile-toggle sidebar-toggle">
22-
<a href="" class="td-n">
23+
<a class="td-n cur-p">
2324
<i class="ti-arrow-circle-left"></i>
2425
</a>
2526
</div>
@@ -28,15 +29,15 @@
2829
</div>
2930
<ul class="sidebar-menu scrollable pos-r">
3031
<li class="nav-item mT-30">
31-
<a class="sidebar-link" href="{{ path('dashboard') }}">
32+
<a class="sidebar-link{{ currentRoute == path('dashboard') ? ' text-primary fw-medium current-route' }}" href="{{ path('dashboard') }}">
3233
<span class="icon-holder">
3334
<i class="c-blue-500 ti-home"></i>
3435
</span>
3536
<span class="title">Dashboard</span>
3637
</a>
3738
</li>
38-
<li class="nav-item dropdown">
39-
<a class="dropdown-toggle" href="javascript:void(0);">
39+
<li class="nav-item dropdown nav-group">
40+
<a class="dropdown-toggle cur-p">
4041
<span class="icon-holder">
4142
<i class="c-teal-500 ti-view-list-alt"></i>
4243
</span>
@@ -47,24 +48,24 @@
4748
</a>
4849
<ul class="dropdown-menu">
4950
<li class="nav-item dropdown">
50-
<a href="{{ path('admin', {action: 'manage'}) }}">
51+
<a href="{{ path('admin', {action: 'manage'}) }}" class="{{ currentRoute == path('admin', {action: 'manage'}) ? 'text-primary fw-medium current-route' }}">
5152
<span>List</span>
5253
</a>
5354
</li>
5455
<li class="nav-item dropdown">
55-
<a href="{{ path('admin', {action: 'logins'}) }}">
56+
<a href="{{ path('admin', {action: 'logins'}) }}" class="{{ currentRoute == path('admin', {action: 'logins'}) ? 'text-primary fw-medium current-route' }}">
5657
<span>View logins</span>
5758
</a>
5859
</li>
5960
<li class="nav-item dropdown">
60-
<a href="{{ path('admin', {action: 'simple-logins'}) }}">
61+
<a href="{{ path('admin', {action: 'simple-logins'}) }}" class="{{ currentRoute == path('admin', {action: 'simple-logins'}) ? 'text-primary fw-medium current-route' }}">
6162
<span>View logins v2</span>
6263
</a>
6364
</li>
6465
</ul>
6566
</li>
6667
<li class="nav-item dropdown">
67-
<a class="sidebar-link" href="{{ path('page', {action: 'components'}) }}">
68+
<a class="sidebar-link{{ currentRoute == path('page', {action: 'components'}) ? ' text-primary fw-medium current-route' }}" href="{{ path('page', {action: 'components'}) }}">
6869
<span class="icon-holder">
6970
<i class="c-pink-500 ti-palette"></i>
7071
</span>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AdminTest\Unit\App\Twig\Extension;
6+
7+
use Admin\App\Twig\Extension\RouteExtension;
8+
use AdminTest\Unit\UnitTest;
9+
use Laminas\Diactoros\ServerRequest;
10+
use Laminas\Diactoros\Uri;
11+
use Mezzio\Helper\UrlHelper;
12+
use Mezzio\Router\RouterInterface;
13+
use PHPUnit\Framework\MockObject\Exception;
14+
use Twig\TwigFunction;
15+
16+
use function method_exists;
17+
18+
class RouteExtensionTest extends UnitTest
19+
{
20+
/**
21+
* @throws Exception
22+
*/
23+
public function testWillInstantiate(): void
24+
{
25+
$urlHelper = $this->createMock(UrlHelper::class);
26+
$routeExtension = new RouteExtension($urlHelper);
27+
$this->assertInstanceOf(RouteExtension::class, $routeExtension);
28+
}
29+
30+
/**
31+
* @throws Exception
32+
*/
33+
public function testWillAddExistingFunctions(): void
34+
{
35+
$routeExtension = new RouteExtension(
36+
$this->createMock(UrlHelper::class)
37+
);
38+
39+
$functions = $routeExtension->getFunctions();
40+
$this->assertCount(1, $functions);
41+
42+
$twigFunction = $functions[0];
43+
$this->assertInstanceOf(TwigFunction::class, $twigFunction);
44+
45+
$callable = $twigFunction->getCallable();
46+
$this->assertIsArray($callable);
47+
$this->assertCount(2, $callable);
48+
$this->assertInstanceOf(RouteExtension::class, $callable[0]);
49+
$this->assertTrue(method_exists($routeExtension, $callable[1]));
50+
$this->assertSame($twigFunction->getName(), $callable[1]);
51+
}
52+
53+
/**
54+
* @throws Exception
55+
*/
56+
public function testWillGetCurrentRoute(): void
57+
{
58+
$router = $this->createMock(RouterInterface::class);
59+
$request = new ServerRequest(uri: new Uri('/test'));
60+
$urlHelper = new UrlHelper($router);
61+
$urlHelper->setRequest($request);
62+
$routeExtension = new RouteExtension($urlHelper);
63+
$this->assertSame('/test', $routeExtension->getCurrentRoute());
64+
}
65+
}

0 commit comments

Comments
 (0)