Twig Post request when rendering a controller - symfony

I use the twig render function to render a controller :
{% render(controller("MyAppDemoBundle:Default:footer")) %}
It seems that the rendered controller didn't receive the request as the main controller.
So the request method is always set to "GET", even if the main request is POST.
Is it normal ?

You can forward the request like this:
{% render(controller("MyAppDemoBundle:Default:footer", {request: app.request})) %}
Remember that you need to pass the request as a variable of your controller action in order for this to work.

Yes, this is completely normal. The render function from twig initiates another request which is completely independent from the main request. So you will also not be able to access any post or get variables in this sub-request.

Related

Repeat code in Twig and pass parameter from controller all the time

I have this piece of code in several Twig templates:
{% if is_granted('IS_AUTHENTICATED_REMEMBERED') == false %}
{{ render(controller('FOSUserBundle:Security:login')) }}
{% include 'FOSMapyetBundle:Registration:register.html.twig' with {form:form} %}
{% endif %}
As you may see it receive the parameter form from controllers but here comes the problem in every site I like to use the code lets said in templates I need to pass the parameter form to the view. By now it's only on 15 templates but this make me think, what about if tomorrow should be 20 or 60 or even 100 templates? So what is the best solution to handle this? Twig Extensions? Symfony Services? Any advice or help on this one?
A kernel event listener may work for this. Render your mini template inside the listener and then "inject" it into the final response, similar to how the debug toolbar works:
https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/WebProfilerBundle/EventListener/WebDebugToolbarListener.php#L106
Note that this is the approach you may want if you want to modify all pages universally. You can apply checks inside the listener to ignore ajax requests, redirection, and the like. You could also probably implement a simple map that knows which routes should have the response modified.
If you want to explicitly render the template in specific pages, then I agree with Maerlyn.
When you need logic like this, your best option is to render a sub-controller, like you already do with your login form.
Create a RegistrationController in your bundle that creates the form and returns the rendered register.html.twig, then embed it like the line above the include.
You can use Response event, and inject your peace on code at the end of the template.
http://api.symfony.com/2.4/Symfony/Component/HttpKernel/KernelEvents.html

Passing current page url to control with Twig in Symfony

Hi I have a modal contact form on my site that is available on each page of my site. When I render the contact controller on each page I was trying to use this
{% render controller('CorporateSiteBundle:Forms:contactUs', { 'contactOpen': contactOpen is defined, route: app.request.requestUri}) %}
Then on my controller page from all my contact form I wanted to grab that 'route' value that I was sending over. This is what I used:
$request->query->get('route');
But the form just seems to fail when it submits. Can anyone help with where I'm going wrong? Thanks
you should try with
$request->get('contactOpen');

Call result controller/view in anoter view

I try to call controller/view in another view. I have a homepage Default:index using a block view of my controller Event and I want to put this block.html.twig in my folder of my controller. In my controller Event, I want an action block, in this way I keep the logic of events, in my controller Event.
How can I do for in Event:index.html.twig call my controller/view ?
I saw the helper render, but I think it makes many requests to include the result.
You seem to be on the right track. When calling sub-renders from a view, you have several options, as detailed here: http://symfony.com/doc/current/book/templating.html
The one I think you're looking for is:
{{ render(controller('YourBundle:Event:index')) }}
which will call the controller action and relevant view.
As an aside, if you want a sub-render, but require no controller logic, use
{{ include('YourBundle:Event:index.html.twig') }}
as this seems to be a lot more lightweight.
If you need to use any of these with parameters, normal format is used.

what is the difference between MASTER / SUB REQUEST in Symfony2?

so im reading the internals documentation for symfony2 http://symfony.com/doc/current/book/internals.html and i dont understand this section http://symfony.com/doc/current/book/internals.html#events.
so, i want to know the difference between MASTER / SUB REQUEST ?
The master request is the one that comes from the original user; the subrequest is the one that you do internally — either with the forward() method of HttpKernel — or by the forward() helper of the framework's Controller class — or {% render ... %} in Twig.
The master request is the one, that is triggered by the browser and the sub requests are requests from within the application. For example a template can render another action
<div id="sidebar">
{% render "AcmeArticleBundle:Article:recentArticles" with {'max': 3} %}
</div>
(Example taken from the manual)
This will lead to a sub request.

Symfony2 main request object in partial controller

I use twig render and in partial controller I want get main controller name, but
$this->get('request')->get('_template')->get('controller')
return partial.
How I can get main request object in partial controller?
Now I use:
{% render 'FooBundle::Controller:action' with {'controller': getControllerName() } %}
with custom Twig function.
Maybe there are more elegant ways to do this?
You will need to explicitly pass this value in the render tag.
{% render 'AcmeBundle:Demo:something' with { 'via': app.request.attributes.get('_controller') } %}
What you probably need is the include tag which includes another template.
{% include 'FooBundle::partial.html.twig' %}
Template inclusion is for simple cases, where you just need things like partials.
The render tag is for invoking controllers, doing more complex things, or if your template can't access the variables needed to display easily. Doing that the kernel creates a new request as if it came as a standalone request. In fact using ESI it could be a standalone request to that controller.See here for details. Because of that, you can't get the main request object, there is probably no main request object because you use ESI or because you create a route for that controller and invoke it via AJAX or whatever. Relying on the the information that your controller is invoked via a sub-request is not supported by the framework as I know, and I think it's intentional. You have to pass all information in query parameters.
Your example isn't correct, it would be like this:
{% render 'FooBundle:MyController:actionName' ... %}
You have to have a FooBundle\Controller\MyControllerController class like this for tihs to work.
namespace FooBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class MyControllerController extends Controller {
public function actionNameAction() {
...
}
}

Resources