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() {
...
}
}
Related
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
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.
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.
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.
I am now working on my first symfony2 project. I have created a service, and I need to call it for every controllers to generate a html which is necessary throughout the all pages in my website.
So I created a BaseController class which extends Symfony\Bundle\FrameworkBundle\Controller\Controller class and tried to place the code in this BaseController class. Now whenever I call from the constructor:
$my_service = $this->get('my_service');
or
$my_service = $this->container->get('my_service');
I got error:
Call to a member function get() on a non-object.
The container object has not been initialized. What is the solution to this problem? How DRY method is followed in symfony2, if I want to place left panel or header in all pages which contains dynamic data?
Thanks in advance.
You shouldn't use the constructor in your controller class, especially when you inherit from Symfony Controller: that way you get the container after the object instantiation (the DIC will call the setContainer method inherited from Symfony's Controller).
In general, for your first experiments, use the services in the action methods; if there is some cross-cutting logic that you need to execute in every request you could consider registering some event listeners (see the "Internals" docs in the Symfony website).
When you get more confidence with the framework you can start thinking about not inheriting Symfony's Controller, registering your controller classes in the DIC and injecting the services that you need manually (eventually implementing some logic in the constructor).
I know this is not the answer you desire, but if you need some html on all pages, I think using a service the way you do is the wrong way.
I guess you know about twig and the possibility to use a layout to place common code. But you can also embed a controller:
{% render "AcmeArticleBundle:Article:recentArticles" %}
Within the recentArticlesAction, you can place your specific code and return a template. By this, you can get custom html into each of your templates! See the symfony docs for more: http://symfony.com/doc/current/book/templating.html#embedding-controllers
Business logic is all the custom code you write for your app that's not specific to the framework (e.g. routing and controllers). Domain classes, Doctrine entities and regular PHP classes that are used as services are good examples of business logic. Ref