Business
Technology
- Administration
- Android
- Apache Solr
- API
- Development Principles
- Django
- Eclipse
- Hibernate
- Javascript/jQuery
- Microsoft .NET
- Microsoft Office
- Patterns
- PHP
- Social Media
- Spring 3.0
- Spring Roo
- Symfony
- Symfony: Doctrine
- Symfony: View
- Symfony: Web Services
The fact that I have entered into IT-related business is proof that businesses have to evolve and keep with time. One has to re-invent continuously.
Kerry Packer
Symfony: Execution Filters: Controlling output
Looking for a Symfony Developer?
If you or your company are looking for a Symfony Developer contact us or read about our Symfony Development Service
This is the last in a three part article on Symfony Request filters. Here we look at using a filter change the output after the main logic is run. This article is split up into 3 parts.
- Symfony: Execution Filters - Here I show you what is needed to set up the filter and an overview as to whats going on,
- Symfony: Execution Filters: Add objects to global environment - Here we look at using a filter to add objects into the global environment before the main logic is run.
- Symfony: Execution Filters: Controlling output - This; Here we look at using a filter to modify the output of an action before sending the request off to the view.
Overview
In the Time Tracker application companies are permitted brand there instances with different layouts, css, javascript, images and so on. The obvious way to do achieve this is to call the setLayout() method in each action. However with over close to 100 actions this would really bulk up the code and distract from the application and business logic. Instead the sfExecutionFilter was overridden and the default layout was swapped with the companies requested layout. Read on to see how it is done.
Creating the post execution filter
This filter takes advantage of the CompanyContextFilter presented in the previous article to select the companies desired layout.
We will be creating a filter that overrides the sfExecutionFilter's executeView method. This is done by:
- Create a filter that extends sfExecutionFilter,
- Reading the company object out of sfContext,
- Setting the layout to the companies requested layout if present, and finally
- Register the filter
Extending sfFilter
In the application's lib directory "$site/apps/frontend/lib" create a file called CompanyLayoutFilter.class.php.
Open this new file and add the following code
<?php
// $site/apps/frontend/lib/CompanyContextFilter.class.php
class CompanyLayoutFilter extends sfExecutionFilter
{
protected function executeView($moduleName, $actionName, $viewName, $viewAttributes)
{
$request = $this->context->getRequest();
$controller = $this->context->getController();
// get the view instance
$view = $controller->getView($moduleName, $actionName, $viewName);
if($this->context->has('Company')){
$layout = $this->context->get('Company')->getLayout();
if(file_exists($layout) && !$request->isXmlHttpRequest()){
$view->setDecoratorTemplate($layout);
}
}
// execute the view
$view->execute();
}
}
This code is taken from the Time Tracker application's api "application", modified for readability. Here is a break down:
- Line 9-14: Sets up required objects
- Line 16: Ensure that we do in-fact have a company object in context
- Line 17: Gets the layout file for the company
- Line 18: Ensures the file exists
- Line 18: Sets the layout for the view to use
- Line 24: Executes the view
Now the actions can continue to focus on their key task and the view remains seperate.
Register the filter with Symfony
The next step is to register the filter with Symfony. This is simply a matter of opening the application's filters.yml file and telling symfony to use a different execution filter
# $site/apps/api/config/filters.yml rendering: ~ security: ~ cache: ~ execution: class: CompanyLayoutFilter
Read back: Symfony: Execution Filters:Add objects to global environment
If you found this article useful, please be sure to check out the related articles below.
Add a comment

Jonathan commented:
A great article on an under documented feature of Symfony, thanks!
gopi commented:
tried it. doesnt seem to be working.
Adam Pullen commented:
Hello gopi,
Thanks for your comment.
What doesn't seem to be working?
Is the filter even being executed?
Can you add a die("hello from filter") to the filter?
gopi commented:
yes, filter is being executed.
what I see is by enabling this filter, no layout is getting set. I even commented out the $view->setDecorator() to check that it should show default layout.
but it is always showing without any layout. not sure what I am missing.
Adam Pullen commented:
I trust that
* your calling $view->execute().
* you havn't set layout(false) anywhere in your action,
* your layout file is accessable (needs to be the full path to the file)
gopi commented:
adam, thx for your response.
I copied ur code as and commented out the setlayout part (given below).
I expected this to be a pass through filter with the default view and layout handle to happen.
but all I am seeing is symfony's debug log and nothing else.
---------------
class ViewFilter extends sfExecutionFilter
{
protected function executeView($moduleName, $actionName, $viewName, $viewAttributes)
{
$request = $this->context->getRequest();
$controller = $this->context->getController();
// get the view instance
$view = $controller->getView($moduleName, $actionName, $viewName);
/*
if($this->context->has('Company')){
$layout = $this->context->get('Company')->getLayout();
if(file_exists($layout) && !$request->isXmlHttpRequest()){
$view->setDecoratorTemplate($layout);
}
} */
// execute the view
$view->execute();
}
}
Adam Pullen commented:
Ok, Silly question,
1) did you set the layout file in the config?
2) Is there anything in the layout file to render?
gopi commented:
1. yes, I did set the layout in the view config, which is the default.. looks like
has_layout: true
layout: layout
2. yes, if I just remove the filter setting line from filter.yml, I get the normal ui output
Tristan commented:
Hi Gopi,
This is what I added to executeView() to make it work in Symfony 1.4.X (taken directly from sfExecutionFilter.class.php):
// Code setting the decorator, etc goes here
// execute the view
$view->execute()
$view->getAttributeHolder()->add($viewAttributes);
// render the view
switch ($controller->getRenderMode())
{
case sfView::RENDER_NONE:
break;
case sfView::RENDER_CLIENT:
$viewData = $view->render();
$this->context->getResponse()->setContent($viewData);
break;
case sfView::RENDER_VAR:
$viewData = $view->render();
$controller->getActionStack()->getLastEntry()->setPresentation($viewData);
break;
}
gopi commented:
thx Tristan, I will try it later in the day and post back
gopi commented:
tristan,
I tried it a month back and it WORKS!
forgot to update before, apologies..
many thanks for ur help
--gopi