gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Ok! The first half of Symfony: route-controller-response is in the books!
The second half is all about useful objects. Obviously, returning a string response like this is not going to take us very far. Our aquanauts demand more! In real life, we might need to render a template, query a database, or even turn objects into JSON for an API!
Symfony comes with many, optional, useful objects to help out with stuff like this. For example, want to send an email? Symfony has an object for that. How about log something? There's an object for that.
These objects are commonly called services, and that's important: when you hear the word service
, just think "useful object".
To keep track of all of these services, Symfony puts them into one big associative array called the container. Each object has a key - like mailer
or logger
. And to be more honest with you - sorry, I do like to lie temporarily - the container is actually an object. But think of it like an array: each useful object has an associated key. If I give you the container, you can ask for the logger
service and it'll give you that object.
The second half of Symfony is all about finding out what objects are available and how to use them. Heck, we'll even add our own service objects to the container before too long. That's when things get really cool.
The first useful object is the templating
service: it renders Twig templates. To get access to the service container, you need to extend Symfony's base controller.
Go Deeper!
Why does extending Controller
give you access to the container? Find out:
Injecting the Container: ContainerAwareInterface (advanced).
In GenusController
, add extends Controller
from FrameworkBundle
. Hit tab to autocomplete and get the use
statement:
... lines 1 - 5 | |
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
... lines 7 - 8 | |
class GenusController extends Controller | |
{ | |
... lines 11 - 22 | |
} |
To get the templating
service, add $templating = $this->container->get('templating')
:
... lines 1 - 8 | |
class GenusController extends Controller | |
{ | |
... lines 11 - 13 | |
public function showAction($genusName) | |
{ | |
$templating = $this->container->get('templating'); | |
... lines 17 - 21 | |
} | |
} |
The container pretty much only has one method: get
. Give it the nickname to the service and it will return that object. It's super simple.
Quickly, open the var
directory, right click on the cache
directory and click "mark this directory as excluded". Symfony caches things... that's not important yet, but excluding this is important: this directory confuses autocompletion.
Now type $this->container->get('templating')
. Well hey autocompletion!
With the templating object we can... well... render a template! Add $html = $templating->render('')
followed by the name of the template. This could be anything, but let's be logical: genus/show.html.twig
. I'll show you where this lives in a second:
... lines 1 - 8 | |
class GenusController extends Controller | |
{ | |
... lines 11 - 13 | |
public function showAction($genusName) | |
{ | |
$templating = $this->container->get('templating'); | |
$html = $templating->render('genus/show.html.twig', array( | |
'name' => $genusName | |
)); | |
... lines 20 - 21 | |
} | |
} |
We'll also want to pass some variables into the template. Pass a name
variable into Twig that's set to $genusName
.
Finally, what do we always do in Symfony controllers? We always return a Symfony's Response
object. Stick, that $html
into the response object and return it:
... lines 1 - 8 | |
class GenusController extends Controller | |
{ | |
... lines 11 - 13 | |
public function showAction($genusName) | |
{ | |
... lines 16 - 20 | |
return new Response($html); | |
} | |
} |
Go Deeper!
You can actually return anything from a controller via the kernel.view
event:
The kernel.view Event (advanced)
Ok, where do templates live? Ah, it's so simple: templates live in app/Resources/views
. The one we're looking for will be in app/Resources/views/genus/show.html.twig
. The existing index.html.twig
template was for the original homepage. Check it out if you want to, then delete it!
Create a new genus
directory and then a new file: show.html.twig
. Welcome to Twig! You'll love it. Add an <h1>
tag with The Genus
and then {{ name }}
to print the name
variable. More on Twig in a second:
<h1>The Genus {{ name }}</h1> |
But that's it! Refresh the browser. Check out that sweet h1
tag.
Now back up: we just did something really cool: used our first service. We now know that rendering a template isn't done by some deep, dark part of Symfony: it's done by the templating object. In fact, Symfony doesn't really do anything: everything is done by one of these services.
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"composer/package-versions-deprecated": "^1.11" // 1.11.99
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.7
"symfony/phpunit-bridge": "^3.0" // v3.1.3
}
}