Buy

Container, Twig: All Smooth

When you want to render a template, you'll usually extend Controller and it'll give you a bunch of shortcuts, including render(). That's a great idea. But I'll extend ContainerAware instead:

24 lines AppBundle/Controller/MightyMouseController.php
... lines 1 - 4
use Symfony\Component\DependencyInjection\ContainerAware;
... lines 6 - 8
class MightyMouseController extends ContainerAware
{
... lines 11 - 22
}

That gives access to the service container, but not the shortcut methods. So I can't say $this->render(), but I can say $html = $this->container->get('twig') and then call render() on it. Render mighty_mouse/rescue.html.twig and pass it a quote variable. But that's just HTML - so wrap it in a Response and return:

24 lines AppBundle/Controller/MightyMouseController.php
... lines 1 - 8
class MightyMouseController extends ContainerAware
{
... lines 11 - 13
public function rescueAction()
{
$html = $this->container->get('twig')->render(
'mighty_mouse/rescue.html.twig',
array('quote' => 'Here I come to save the day!')
);
return new Response($html);
}
}

Now, where do templates live? Usually, it's app/Resources/views. But we've moved everything up and out of app/. So our path is just Resources/views: add those directories and a mighty_mouse folder inside. Create rescue.html.twig and extend the base template. We don't have a base template yet, but we will soon. In {% block body %} print out the quote:

6 lines Resources/views/mighty_mouse/rescue.html.twig
{% extends 'base.html.twig' %}
{% block body %}
<h1>{{ quote }}</h1>
{% endblock %}

Now add base.html.twig in Resources/views. Let's steal again from the Standard Edition. Find app/Resources/views/base.html.twig, copy it, and paste it in ours:

13 lines Resources/views/base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>

Ok, give it a try. Unable to find template "mighty_mouse/rescue.html.twig". Hmm I bet I have a typo. Yep, my directory was called might_mouse. I went a bit too micro on the name there. Fix that and try again. It's alive!

Tip

After creating the views/ directory for the first time, you'll need to clear your Symfony cache, or the template won't be found. That's probably a small Symfony bug, that hopefully we can fix!

Now, let's add the web debug toolbar.

Leave a comment!

  • 2016-07-29 weaverryan

    Ah, you're right! That's an annoying little thing about the trait :) - you need to use the trait *and* implement the interface.

    Thanks for sharing this!

  • 2016-07-28 Han Solo

    The get() function was being called inside the rescueAction function from the tutorial, but since the ContainerAware was moved to a trait, you need to implement ContainerAwareInterface.

    use Symfony\Component\DependencyInjection\ContainerAwareInterface;

    class MightyMouseController implements ContainerAwareInterface

  • 2016-05-18 weaverryan

    Hi Alberto!

    Hmm, are you trying to call get() from inside of __construct(). That's the only thing I can think of. If so, don't do that :). In fact, don't have a __construct() - simply fetch the services later that you need when you need them.

    But if you're *not* getting this error in __construct(), let me know and paste a little more code. Because, yea, that should not happen :).

    Cheers!

  • 2016-05-15 Alberto Castro

    Ryan,

    When I try to use the trait ContainerAwareTrait as you explain below I cannot make the code run. I get the error:

    "Error: Call to a member function get() on a non-object"

    Is there something missing?

    Thanks.

  • 2016-03-08 Moises Cano

    NICE!!!!! Thanks a lot.

  • 2016-03-08 weaverryan

    Hey Moises!

    Ah, I'm glad you commented about that! You're right that ContainerAware is gone in Symfony3. That's ok - it was just moved to be a trait. So now:

    use Symfony\Component\DependencyInjection\ContainerAwareTrait;

    class MightyMouseController
    {
    use ContainerAwareTrait;
    }

    That'll do the same thing as before :). Also, in Symfony 2.8, I introduced a new MicroKernelTrait that helps to make creating a "micro Symfony app" like the one in this tutorial easier (in fact, this MicroKernelTrait was inspired by some of the "extra" work that felt unnecessary in this tutorial). I'm planning on adding an updated tutorial about this sometime, but I've written documentation already (http://symfony.com/doc/current... and a finished example application (https://github.com/weaverryan/... with multiple micro kernels.

    I hope that helps!

  • 2016-03-07 Moises Cano

    I'm stuck. I started this project but ContainerAware is deprecated in Symfony3. I don't know what to do, and am now wondering if I should try Silex, or if this is still a good solution.

  • 2015-08-20 weaverryan

    Awesome :) - I'm going to add a note about this!

  • 2015-08-18 Alexander Morozov

    Thank you Ryan!

    After i deploy this project on other machine it works great with "/views/" in routings. But when I delete "views/" from routings and clear the cache, it still works great!

  • 2015-08-18 weaverryan

    Hey Alexander!

    Try clearing your cache - with a "rm -rf cache/*".

    Let me know if that works. I think there might be a slight bug, where you need to clear the cache ONE time after creating your first template in the Resources directory (the Symfony standard edition doesn't have this problem since you start with a Resources directory).

    Cheers!

  • 2015-08-16 Alexander Morozov

    Can you help me, please?

    I can't run code from here. When I start it i got "Unable to find template "mighty_mouse/rescue.html.twig"" error.
    But when i add "views/" to $html = $this->container->get('twig')->render( 'views/mighty_mouse/rescue.html.twig', array('quote' => 'Here I come to save the day!') ); and in my controller and "{% extends 'views/base.html.twig' %}" in my rescue.html.twig all is good.