-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Document how to embed a controller as a service #8039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document how to embed a controller as a service #8039
Conversation
I think the backslashes need escaping, like |
@marcverney my bad, I'll change that. |
@marcverney actually, I have a doubt: are you sure this is needed when using single quotes? |
05e4f3d
to
071b119
Compare
@greg0ire Based on my tests they are needed (it fails to find AppBundleControllerHelloController). I can't guarantee that there isn't a problem with my setup, though. You should definitely test it yourself. |
{# ... #} | ||
<div id="sidebar"> | ||
{{ render(controller( | ||
'AppBundle\\Controller\\HelloController:indexAction', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can anyone tell why these double backslashes are required?
I have no up to date enough project to do that, sadly :/ Thanks for checking. |
@@ -98,4 +98,36 @@ string syntax for controllers (i.e. **bundle**:**controller**:**action**): | |||
) ?> | |||
</div> | |||
|
|||
If your controller should be used :doc:`as a service </controller/service>`, | |||
you can reference it like this instead: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is interesting :). Starting in Symfony 3.3, the AppBundle:Article:recentArticles
syntax should also work when your controller is a service... as long as your service id matches your class name (like it does in your example). In other words, unless you've registered your service with a non-class id (e.g. my_controller
), you should be able to just use one syntax, and Symfony will automatically use your controller as a service if it is registered as one (or instantiate it like normal if it is not).
Given that, what made you create this PR? Were you seeing different behavior or were you confused by something?
Cheers!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried helping @marcverney set it up on via Slack, but it did not work for him. @marcverney , can you comment on your setup and on the error message you were getting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here it goes. I was trying to embed a controller action in a twig template, this way:
{{ render(controller('AppBundle:Default:completeSignup')) }}
Here is my controller action:
public function completeSignupAction(CategoryRepository $categoryRepository)
{
// ...
}
And the CategoryRepository service definition
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Domain\Model\CategoryRepository:
factory: ['@doctrine.orm.entity_manager', 'getRepository']
arguments: ['Domain\Model\Category']
When I tried to access the page, I got the following error:
An exception has been thrown during the rendering of a template ("Controller "Infrastructure\UI\Symfony\AppBundle\Controller\DefaultController::completeSignupAction()" requires that you provide a value for the "$categoryRepository" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.").
I then thought that maybe injecting a service in a controller action was not supported for subrequests (as I think that's what render(controller())
does). I searched the docs but couldn't find anything about this, so I asked on the support Slack channel. This is where @greg0ire and others told me to try using the FQCN notation:
{{ render(controller('Infrastructure\\UI\\Symfony\\AppBundle\\Controller\\DefaultController:completeSignupAction')) }}
This worked and my $categoryRepository
was correctly injected, so @greg0ire created this PR.
I think this sums it all up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, and as for my setup, two things:
- I'm trying to follow a ddd-loosely-inspired folder structure, so my AppBundle dir is not a direct child of src, plus not everything is inside AppBundle.
- I'm not very comfortable with the autowiring magic yet, so an error in my service definitions would not come as a surprise.
@marcverney I tried to reproduce your issue (see https://github.com/GuilhemN/symfony-standard/tree/issue) but it worked fine for me... Could you try to update my repository (or the standard edition) to give us something to debug please? Can you share with us all your service definitions to make sure everything is configured correctly? |
Todo: