I'm in the midst of converting a ZF2 site from using default templates into twig versions, and so far, for the main part, everything is going well, except I have some variables in Module.php defined from a bootstrap method that I'm now unable to get into the layout.twig template.
The original code that worked fine for the default templates is as:
public function bootstrapLayout(MvcEvent $e)
{
$config = $e->getApplication()->getServiceManager()->get('applicationconfig');
$authService = $e->getApplication()->getServiceManager()->get('AuthService');
$version = new \stdClass();
$version->major = $config['version']['major'];
$version->minor = $config['version']['minor'];
$dt = new \DateTime();
$thisYear = $dt->format('Y');
$dt->setTimestamp($config['version']['build_date']);
$version->buildDate = $dt->format('d/m/Y H:i');
$user = new \stdClass();
$user->hasIdentity = $authService->hasIdentity();
$user->username = $authService->getStorage()->read('username');
$e->getViewModel()->setVariables(array(
'version' => $version,
'thisYear' => $thisYear,
'user' => $user,
));
}
However, neither 'version', 'thisYear' nor 'user' make itself known to the twig layout template. I've searched on here and the closest resolution I came to finding was to obtain the ZfcTwigRenderer by:
$zfcTwigRenderer = $e->getApplication()->getServiceManager()->get('ZfcTwigRenderer');
but now I'm at a loss how I can utilise this and pass my defined vars through it to the layout.
Here's the content of the layout file:
{{ docType() }}
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<title>{% block title %}{% endblock title %} - Website</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% block meta %}{% endblock meta %}
<!-- Le styles -->
<link href="/css/bootstrap.min.css" media="screen" rel="stylesheet" type="text/css">
<link href="/css/bootstrap-hidden-inline.css" media="screen" rel="stylesheet" type="text/css">
<link href="/css/theme.min.css" media="screen" rel="stylesheet" type="text/css">
<link href="/css/bootstrap-datetimepicker.min.css" media="screen" rel="stylesheet" type="text/css">
<link href="/css/style.css" media="screen" rel="stylesheet" type="text/css">
<link href="/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon">
{% block style %}{% endblock style %}
<!-- Scripts -->
<script type="text/javascript" src="/js/jquery.min.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/tooltip.min.js"></script>
<script type="text/javascript" src="/js/bootstrap-datetimepicker.min.js"></script>
<!--[if lt IE 9]><script type="text/javascript" src="/js/html5.js"></script><![endif]-->
<script type="text/javascript" src="/js/modernizr.min.js"></script>
<script type="text/javascript" src="/js/overlays.min.js"></script>
<script type="text/javascript" src="/js/common.min.js"></script>
{% block script %}{% endblock script %}
</head>
<body>
<div class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
{% if user.hasIdentity %}
<button class="navbar-toggle" data-target=".navbar-collapse" data-toggle="collapse" type="button">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{% endif %}
<a class="navbar-brand" href="{{ url('home') }}">Website</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<!--<li><a class="icon-home" href="{{ url('home') }}"><span></span>Home</a></li>-->
{% if user.hasIdentity %}
<li class="hidden-sm hidden-xs"><a class="icon-import" href="{{ url('import') }}"><span></span>Import</a></li>
<li class="hidden-sm hidden-xs"><a class="icon-export" href="{{ url('export') }}"><span></span>Export</a></li>
<li><a class="icon-about" href="{{ url('about') }}"><span></span>About</a></li>
<!-- <li><a class="icon-reports" href="#"><span></span>Reports</a></li> -->
<li><a class="icon-logout" href="{{ url('logout') }}"><span></span>Logout</a></li>
{% endif %}
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.hasIdentity %}
<!--<li><a class="icon-report-bug" href="{{ url('report-bug') }}"><span></span>Report bug</a></li>-->
{% endif %}
</ul>
</div>
</div>
</div>
{% if user.hasIdentity %}
<div class="container hidden-sm hidden-xs">
<div class="welcome-message"><span></span>Welcome {{ user.username }}</div>
</div>
{% endif %}
<div class="container">
{% block content %}{{ content|raw }}{% endblock content %}
<hr>
<footer>
Copyright © {{ thisYear }} Company name<br>
Version {{ version.major }}.{{ version.minor }} —
Build {{ version.buildDate }}
</footer>
</div> <!-- /container -->
{% block inline %}{% endblock inline %}
</body>
</html>
Any help on this would be greatly appreciated as I've really come up against a dead end, despite trying all sorts of things for the past couple of hours.
Ahah! After a bit more digging around on the net for ZF2 concepts in general, I've managed to come up with a solution. Maybe, maybe not, the best, but it's working (at least for now)... the solution was a custom view helper.
In Module.php, I added a
getViewHelperConfig()
method that I plan to call viaglobalVars()
:Then I created the view helper in Application\src\Application\View\Helper\GlobalVars.php:
In layout.twig, I now call this via
{{ globalVars().version.major }}
for example, and to check whether the user is logged in or not,{% if globalVars().user.hasIdentity %}
.If someone has a better / more elegant method, then I'd most certainly be interested in seeing it, but if not, or if this is the "best" approach, then hopefully it'll be useful for others too.
For true global variables that are available inside all layouts you need to do the following inside a onBootstrap function in Module.php so you example would be
This would then allow you to use your above template like you have set out.
Hope this helps
You could use
instead of