I’ve got the following situation. As in your typical ZF2-Application there is existing a layout.phtml
-view-script for the layout and a view-script specific to the called action. In my case it’s team/frontend/index.phtml
.
My problem is concerned with the headtitle. The headtitle-parts are currently set directly within the view-script-files, like the following:
layout.phtml
<?php
echo $this->headtitle('My Application')->setAutoEscape(false)->setSeparator(' | ');
team/frontend/index.phtml
<?php
$this->headtitle('Our team');
This is – as intended – resulting in My Application | Our team
. So far so good.
Now I am writing a new module, which – beside some other features – also should provide the possibility for some SEO-stuff. One of the SEO-tasks is to overwrite the title of a the inner view script: team/frontend/index.phtml
but not for layout.phtml
. The new title is coming from the database, however this is not relevant for this problem.
So for this action I want to be able to produce an outcome like this: My Application | The faces behind the team
. As you can see I only want to overwrite the everything the action-view-script sets, but not the title part of the layout.phtml
.
Since it’s a completly different module, which would add this functionality and both modules should work independendly I hope this is solvable through events/the EventManager.
Sidenote: the new module is called: Node
I tried 2 things, both resulting in the same thing:
I attached to the MvcEvent::EVENT_RENDER
EventManager within the onBootstrap
-method of my NodeModule.php
and (in another attempt) I fetched EventManager of ZendViewView
and attached to the ViewEvent::EVENT_RENDERER_POST
.
In the callback-function I fetched the title from the database and set it by fetching the HeadTitle-View-Helper.
Both attempts resulted in a final headtitle of My Application | Our team | The faces behind the team
meaning the parts were just appended although I used the SET
-Parameter within the callback function.
This is a simplified version of the callback-function:
$viewHelperManager = $serviceLocator->get('viewhelpermanager');
// Get new title-part from database
$titlePart = '...' // In this case "The faces behind the team"
// Set HeadTitle
$headtitle = $viewHelperManager->get('headtitle');
$headtitle($node->getNodeName(), 'SET');
As you can see here I am using SET
as the second parameter. I do understand, why it’s not working: it’s too late the event seems to be triggered when the action-view-script and the layout-view-script are finished processing. However I need a possibility to hook in before the layout-view-script is processed, so that I can overwrite the action-view-scripts’ headtitle.
I hope you understand what I mean.
Any thoughts ideas on this? Is there an event which is triggered for every view-script in the queue?
UPDATE 2015-10-14 – 13:10
I’ve further investigated the code and the event triggering within the code of ZF2. Because of the structure in which it is written, my request is just not possible in the way I wanted it to be.
Like Wilt‘s and akond‘s anwers the headtitle should be generally dealt with in the action or in particular other places, however not within the view-script itself.
Wilt posted the link to the ZF2-docs concerning headtitle. There they provide an example of how to set the headtitle within an action.
I knew how to do that, however in the Album-Module Tutorial (http://framework.zend.com/manual/current/en/user-guide/database-and-models.html#listing-albums) they set the headtitle within the view, so I went this way…
Of course, it’s no problem for me to fix my other modules (like my Team-Module), however I will run into problems with vendor-modules. If authors of other module keep setting their headtitles within their view-scripts, my Node-Module won’t stand a chance. The only thing I could do in that case is to overwrite their view-scripts and remove the setting of the headtitle…
2
Answers
In my opinion you are experiencing this problem because of contamination of the view with data. In other words, you should not have put neither ‘My Application’ or ‘Our team’ into the view.
What you should be having instead is a model/helper, that provides view with an appropriate head title. Something along the lines of:
in the controller action and
in the view.
View should only render data that is provided by model. In our case, the view is a model in its own right. That’s bogus.
You should set your head title in your controller not in your view.
Check the ZF2 documentation on head title to see how to properly use this view helper:
In the view only:
Outputs the following html:
In your other module, in the other controller you can set new variables for the headscript.
Another possibility (don’t think it is better) would be to pass your titles as variables to your view in a parameter. For example like this:
Now in the views you can do:
and
This last solution is more dirty, because you are not supposed to set your head title like that in the view if you ask me. But it will work and it suits your current solution more (less refactoring).
UPDATE
If you are afraid of others overruling the title you set in their views then you can also extend the the
HeadTitle
view helper and overwrite the ‘_invoke’ method so it does not allow the overwriting the$title
if it is already set.And then re-register (overwrite) it in the view helper manager: