If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
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:
... 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:
... 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:
{% 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:
<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.
Hey Maksym,
Could you provide a bit more information? What do you think we should update here? Thanks!
Cheers!
For example, ContainerAware is deprecated.
Also I would like to know more about the MicroKernelTrait.
You're absolutely right :). Fortunately, that's an easy change - there's now a ContainerAwareTrait you can use instead (no other code needs to be changed).
And actually, this tutorial is part of what inspired me to "invent" the MicroKernelTrait in Symfony :). I wrote the docs about it also for Symfony.com - http://symfony.com/doc/curr....
We will likely do a tutorial on it, but not in 2016 (we have other tutorials planned). I have noted this request though, that helps push things up in priority :). But if you have any questions or are wondering something, let me know - I love to chat about the MicroKernelTrait! :)
Cheers!
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.
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/cookbook/configuration/micro-kernel-trait.html) and a finished example application (https://github.com/weaverryan/docs-micro_kernel/tree/finished) with multiple micro kernels.
I hope that helps!
Hey Nina,
"$ bin/console cache" will show you available commands which contain "cache" in its name. I'll find a few commands, but for clearing the cache use: "$ bin/console cache:clear". But this command clears only environment specific cache, by default it's dev. If you want to clear the cache for prod environment, use: "$ bin/console cache:clear --env=prod", etc. Or, you can clear all the cache manually with "rm -rf var/cache/*".
Cheers!
Thanks for reply
But in the micro framework we don't have bin/ directory
if I use:
php console cache
I have error
> php console cache
Fatal error: Uncaught Error: Class 'Dotenv\Dotenv' not found in C:\OpenServer\domains\symfony.microframework\console on line 16
Error: Class 'Dotenv\Dotenv' not found in C:\OpenServer\domains\symfony.microframework\console on line 16
Call Stack:
0.0002 365816 1. {main}() C:\OpenServer\domains\symfony.microframework\console:0
Dump $_SERVER
$_SERVER['REMOTE_ADDR'] is undefined
$_SERVER['REQUEST_METHOD'] is undefined
Dump $_SESSION
$_SESSION['*'] is undefined
Dump $_REQUEST
Yo Nina!
You're right! The actual command would be php console cache:clear --env=prod
, as it does not live in a command directory.
About the error, it looks like you're missing the Dotenv library, which we installed here: https://knpuniversity.com/screencast/micro-symfony/dotenv. Make sure you've installed the vlucas/phpdotenv
library, and run composer install
so that everything is downloaded into your vendor directory :).
Cheers!
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.
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!
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!
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.
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!
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
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!
// composer.json
{
"require": {
"symfony/symfony": "^2.7", // v2.7.2
"sensio/framework-extra-bundle": "^3.0", // v3.0.9
"vlucas/phpdotenv": "^2.0", // v2.0.1
"symfony/monolog-bundle": "^2.7" // v2.7.1
}
}
This tutorial needs updating, I believe.