1

So I'm brand new to symfony (and MVC frameworks in general) so I'll need a complete beginners answer to my question please.

Basically, I've set up a controller to add a class to the navigation element of the current page. At least in theory I have, in practice I get the following exception error:

An exception has been thrown during the rendering of a template ("The controller must return a response (Text elements given).") in "myNewBundle:Page:text-elements.html.twig".

I think that the problem (or at least part of it) is that the controller has been decoupled from the template. So it has no idea if the page it is being called on, is current or not.

Here is the contents of my controller:

<?php

namespace my\NewBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

/**
* @Template("myNewBundle::definitions.html.twig")
*/

class NavController extends Controller
{
    public function renderNavAction($target='/usage', $text='Insert Link')
    {
        $output = '<a href="' . $this->generateUrl($target) . '" ';
        if ($this->getRequest()->get('_route') == $target) $output .= 'class="active"';
        $output .= '>' . $text . '</a>';
        return $output;
    }
}   

And this is the part of the twig template which should render it out:

<ul>
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_textElements', 'text' : 'Text elements' })) }}</li>                
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_buttons', 'text': 'Buttons' })) }}</li>                
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_forms',  'text': 'Forms' })) }}</li>                
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_lists', 'text': 'Lists' })) }}</li>                
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_tables', 'text': 'Tables' })) }}</li>                
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_searchBoxes', 'text': 'Search Boxes' })) }}</li>               
   <li>{{ render(controller('myNewBundle:Nav:renderNav', { 'target': 'my_new_pods', 'text': 'Reusable Pods' })) }}</li>
</ul>

Could somebody please let me know what it is that I'm doing wrong? Note: The template annotations part is something I added when trying to resolve the issue myself. If it's not necessary then I'm happy to remove/alter it.

tereško
  • 58,060
  • 25
  • 98
  • 150
Alex Foxleigh
  • 1,784
  • 2
  • 21
  • 47

1 Answers1

2

Read attentively Controller chapter in symfony book. Controller always must return a Response object.

public function renderNavAction($target='/usage', $text='Insert Link')
{
    $output = '<a href="' . $this->generateUrl($target) . '" ';
    if ($this->getRequest()->get('_route') == $target) $output .= 'class="active"';
    $output .= '>' . $text . '</a>';
    $response->setContent($output);
    $response->setStatusCode(200);
    $response->headers->set('Content-Type', 'text/html');
    return $response;
}

But in your situation better to make a macro or simply include another template with params.

Alexey B.
  • 11,965
  • 2
  • 49
  • 73
  • OK quick update. I've fixed part of the problem. And have now managed to get a response from the controller by adding: use Symfony\Component\HttpFoundation\Response; and changing the output line to: return new Response($output); However the initial issue of it being decoupled from the template still applies. I think the fault lies with this part: if ($this->getRequest()->get('_route') == $target) however I don't know what to do to make that realise it's on the same page. – Alex Foxleigh Aug 22 '13 at 08:55
  • You cant access Request in subqueries. Thats why its not working. Pass current route to controller as third parameter or compare it in template. To access current route use `app.request.attributes.get('_route')` in template – Alexey B. Aug 22 '13 at 08:58
  • That worked perfectly and makes total sense. I feel a bit daft not thinking of that in the first place :) Thank you. – Alex Foxleigh Aug 22 '13 at 09:05