8000 Should Twig require "router" and "router.request_context" services? · Issue #11466 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Should Twig require "router" and "router.request_context" services? #11466

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
Warbo opened this issue Jul 24, 2014 · 12 comments
Closed

Should Twig require "router" and "router.request_context" services? #11466

Warbo opened this issue Jul 24, 2014 · 12 comments

Comments

@Warbo
Copy link
Warbo commented Jul 24, 2014

Zawinski's Law has lead me to send emails from my Symfony-based CLI application. These emails use Twig templates, so naturally I used TwigBundle.

When I tried this I hit a bunch of errors, since Twig refused to load without a "router" and "router.request_context" service. As far as I'm aware, routing is only needed for directing URLs to Controllers, so is completely unnecessary in a CLI app.

I haven't just had to add useless Symfony\Component\Routing\Router and Symfony\Component\Routing\RequestContext definitions to my services.yml, I've also had to define a Loader for the Router to use. Since I have no routes, I've used Symfony\Component\Routing\Loader\ClosureLoader, since at least that won't access the disk.

I'd rather not have to define these extra services. They clutter the configuration, require comments telling future maintainers why there's HTTP request handling machinery in a CLI app, they add extra dependencies/coupling and make the bootstrap more brittle.

Could they be removed as dependencies and loaded as needed please?

@javiereguiluz
Copy link
Member

@Warbo in Symfony2 commands you can easily use any of the available services. As a matter of fact, rendering some Twig template and sending the contents via email is pretty straightforward:

use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class MailingCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        // ...
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $container = $this->getContainer();

        $content = $container->get('templating')->render(
            'AcmeDemoBundle:Default:email.html.twig',
            array('foo' => 'bar')
        );

        $mailer = $container->get('mailer');

        // ...
    }
}

And don't forget to check out this cookbook to learn some tips for sending emails from commands.

@Warbo
Copy link
Author
Warbo commented Jul 24, 2014

@javiereguiluz Yes, using available services in commands is easy. The hard part is making them available to being with ;)

I don't see why defining a twig service should require me to make up a fake router service in environments for which routing makes no sense (ie. a CLI).

@javiereguiluz
Copy link
Member

@Warbo I'm afraid that I don't understand your issue. If you want to render Twig templates as the content of emails sent via a Symfony-based CLI app, you can use the code that I pasted previously. There is no need to define any service or do anything else.

@wouterj
Copy link
Member
wouterj commented Jul 24, 2014

@javiereguiluz the problem @Warbo describes is that the twig services as extensions, which require some services like router (routing extension) and router.request_context (assets extension). Since @Warbo is creating a CLI application, he removed the configuration of framework.router (a router makes no sense in the CLI). That caused these services to no longer exists and thus causes the container to throw exceptions.

The only solution I see is to write a Compiler Pass and remove the twig.extension tags from those extensions that require non existing services

@Warbo
Copy link
Author
Warbo commented Jul 25, 2014

@wouterj You've described my problem exactly :)

Although it wasn't me that removed the configuration. I've inherited this application from a previous developer, so all I know about configuration changes is what git tells me.

The changes I made to enable Twig were:

  • Add TwigBundle to AppKernel::registerBundles
  • Add "framework: { templating: { engines: ['twig'] } }" to the config
  • Define a "router" service as Symfony\Component\Routing\Router
  • Define a "router.loader" service as Symfony\Component\Routing\Loader\ClosureLoader, to use as the first argument to "router"
  • Define a "router.request_context" as Symfony\Component\Routing\RequestContext

The first two are completely reasonable, were well documented and easy to figure out.

The last three are unintuitive, shouldn't really be necessary in a CLI application, and are effectively undocumented. I found lots of tutorials like that provided by @javiereguiluz but all of them assume that twig, router, etc. are already available.

I couldn't find anything about how to make them available, and had to dig through the PHP source to figure it out.

@wouterj
Copy link
Member
wouterj commented Jul 25, 2014

I couldn't find anything about how to make them available, and had to dig through the PHP source to figure it out.

The previous developer properbly had removed this line from your configuration: https://github.com/symfony/symfony-standard/blob/master/app/config/config.yml#L9-10 That causes the routing services to not load.

Imo, we should find a solution for this. Symfony allows people to work without the router, so all it's public services should allow that too. Atm, Twig isn't.

I would say that this is a DX issue, can someone please tag?

@jakzal jakzal added the DX label Jul 25, 2014
@Warbo
Copy link
Author
Warbo commented Jul 25, 2014

Ah. I was hesistant to define new, empty config files like "routing.yml", but it seems to work with "/dev/null". This at least lets me remove the manually-defined router services.

Still not ideal though! ;)

@Richtermeister
Copy link
Contributor

@Warbo I don't think it's unreasonable to have a router service in Cli contest. After all your emails might contain URLs to areas within your app.. so, links are not just for redirecting browsers, but also for informational value. I have found this to be a non-issue.

@wouterj
Copy link
Member
wouterj commented Aug 9, 2014

@Richtermeister if you create a pure CLI application, you don't have any routing. CLI doesn't have a host and such. Symfony allows you to disable the routing feature via the framework.router setting. It's strange that disabling the router means that you can't use twig templates anymore.

@Richtermeister
Copy link
Contributor

@wouterj Ah yes, agree. I was only thinking about the cli needs of a web-app. Sounds like disabling the router in the framework should also prevent url/path twig extensions from being registered..

@stof
Copy link
Member
stof commented Aug 12, 2014

Making Twig work without the router was already handled previously (the RoutingExtension is already disabled in this case). However, #10451 broke it by introducing the usage of the request context in a different extension without adding a check. This is a bug in 2.5 indeed /cc @romainneutron

@pgodel
Copy link
Contributor
pgodel commented Aug 23, 2014

I submitted a PR (#11749) to address the issue introduced in #10451.

I am not entirely satisfied though. If you try disabling the router in the SE, there are a bunch other dependencies that prevent you from using TwigBundle without the router. The TwigBundle requires the FrameworkBundle and this requires the router because the FrameworkBundle is loading templating_php.xml: #11748 among of other requirements.

So to fully fix this issue it appears there are other things that need to be done.

fabpot added a commit that referenced this issue Aug 27, 2014
…ssetsExtension (pgodel)

This PR was merged into the 2.5 branch.

Discussion
----------

[TwigBundle] Remove hard dependency of RequestContext in AssetsExtension

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #11466
| License       | MIT
| Doc PR        | -

#10451 introduced the requirement of RequestContext in AssetsExtension. This is only needed when generating absolute URLs for assets. When sending emails with Twig from the CLI, the router may not be present and most times is not required.

This PR attempts to remove the hard dependency and set RequestContext if the router is present according to issue #11466.

Commits
-------

5ad4d8a Remove hard dependency of RequestContext in AssetsExtension
@fabpot fabpot closed this as completed Aug 27, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants
0