On 10/27/10 12:23 AM, Lukas Kahwe Smith wrote:
Hi,
I think the _format routing magic needs a bit of tweaking to be really useful.
Summary:
2) Make it possible to define some format specific view logic (json_encode(),
generate pdf/image etc)
You might have noticed that I always say that a controller should return
a Response (I never say "must"). That's because you can implement a View
if you want/need to. Let me show you a simple example for JSON.
First, instead of returning a Response, the controller can return
anything you want, like a View instance for example:
public function someAction()
{
return new JsonView(array('foo' => 'bar'));
}
Then, define the JsonView class (you can do whatever you want in the
toResponse() method):
use Symfony\Component\HttpFoundation\Response;
class JsonView
{
protected $parameters;
public function __construct(array $parameters)
{
$this->parameters = $parameters;
}
public function toResponse()
{
return new Response(
json_encode($this->parameters),
200,
array('content-type' => 'application/json')
);
}
}
If the controller does not return a Response, you need to implement a
core.view listener to convert it to a proper Response instance:
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class JsonViewListener
{
public function register(EventDispatcher $dispatcher)
{
$dispatcher->connect('core.view', array($this, 'toResponse'));
}
public function toResponse(Event $event, $retval)
{
if (!$retval instanceof JsonView) {
return $retval;
}
return $retval->toResponse();
}
}
Eventually, register your listener:
<service id="view.json" class="...\View\JsonViewListener">
<tag name="kernel.listener" />
</service>
This example show you how you can implement a generic view. The same
technique can also be used if you want to define a View for all your
controllers. A View can deal with HTTP headers, template choice logic,
caching, ... That way, your controller responsibility is just about
getting data from the Model and passing them to the View. One of the
goal of the FrameworkExtraBundle
(http://bundles.symfony-reloaded.org/frameworkextrabundle/) is to avoid
View implementation for simple/common use cases. By providing
annotations for common Response tweaking, it allows you to have a clean
controller without the need for implementing a View (see the tip on the
doc page).
Of course, you can argue that it would be a good idea to "standardize"
the way generic View classes are defined. For instance, we might have an
interface like this one in the Symfony2 core:
interface ViewInterface
{
public function toResponse();
}
For Views implementing this interface, we can then have a generic
listener that will work for all implementation:
class GenericViewListener
{
public function register(EventDispatcher $dispatcher)
{
$dispatcher->connect('core.view', array($this, 'toResponse'));
}
public function toResponse(Event $event, $retval)
{
if (!$retval instanceof ViewInterface) {
return $retval;
}
return $retval->toResponse();
}
}
With that code in the core, we can also probably provide some generic
View class implementations in the core (like the JSON one).
That's a possibility... and something I wanted to talk about and play
with for quite some time now... but I just hadn't the time to do so...
So, your question is good way to get the discussion started on that
topic :) Comments welcomed...
Fabien
--
If you want to report a vulnerability issue on symfony, please send it to
security at symfony-project.com
You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en