Skip to content

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

Closed

Conversation

greg0ire
Copy link
Contributor

@greg0ire greg0ire commented Jun 13, 2017

Todo:

  • add links between docs

@marcverney
Copy link
Contributor

I think the backslashes need escaping, like 'AppBundle\\Controller\\HelloController:indexAction'

@greg0ire
Copy link
Contributor Author

@marcverney my bad, I'll change that.

@greg0ire
Copy link
Contributor Author

@marcverney actually, I have a doubt: are you sure this is needed when using single quotes?

@greg0ire greg0ire force-pushed the document_caas_embed_controller_syntax branch from 05e4f3d to 071b119 Compare June 14, 2017 18:02
@marcverney
Copy link
Contributor

@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',
Copy link
Contributor Author

@greg0ire greg0ire Jun 14, 2017

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?

@greg0ire
Copy link
Contributor Author

You should definitely test it yourself.

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:
Copy link
Member

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!

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

@GuilhemN
Copy link
Contributor

GuilhemN commented Jun 16, 2017

@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?

@marcverney
Copy link
Contributor

While I was preparing a sample minimal repo, as @GuilhemN suggested, I discovered that upgrading symfony/symfony from 3.3.0 to 3.3.1 fixed the issue. Looking at the changelog I think that #23013 matches perfectly. This PR can probably be closed.

@greg0ire greg0ire closed this Jun 16, 2017
@greg0ire greg0ire deleted the document_caas_embed_controller_syntax branch June 16, 2017 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants