Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

Configuring a Bundle

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Let's dump this markdown object: I want to know exactly what this object actually is: dump($markdown);die;:

... lines 1 - 13
class ArticleController extends AbstractController
{
... lines 16 - 26
public function show($slug, MarkdownInterface $markdown, AdapterInterface $cache)
{
... lines 29 - 60
dump($markdown);die;
... lines 62 - 68
}
... lines 70 - 81
}

Refresh the article page! Ok, it's an instance of some Max object - probably from the bundle or some library it's using. And it looks like it has a features array where you can turn some features on and off.

So here's the burning question: because the bundle gives us this service automatically, how can we configure it? I mean, what if I want to turn some of these features on or off, or I want to swap the class from Max to a different class from the bundle?

The answer is... science! I mean... configuration! Imagine you're the bundle author: you can probably think of the types of things a user might want to change. So, you setup a simple configuration array that can be used to control those things.

And yea... that's basically how it works, except the config is in YAML.

Dumping Bundle Configuration

And there's an awesome way to find out all of the configuration options for a bundle without reading the documentation... because I know, we all like to skip reading the docs!

The name of this bundle is KnpMarkdownBundle. At your terminal, use that to dump its config:

./bin/console config:dump KnpMarkdownBundle

Boom! Say hello to a big YAML example of all of the config options for this bundle. Sometimes, the keys are self-explanatory. But other times - you'll want to cross-reference this with the bundle's docs to find out more.

In this case, down below on the docs, it tells us that the bundle ships with a number of different parsers: it looks like it defaults to this "max" parser: fully-featured, but a bit slow.

Configuring the Parser

To prove we can do it, let's try to change to the "light" parser. According to the docs, we can do that by using the knp_markdown, parser, service config and setting its value to markdown.parser.light.

Ok! But... where should this config live? Move over to your project and look in the config/ directory and then packages/. Create a new file called knp_markdown.yaml. Then, copy the configuration, paste it here and change the service to the one from the docs: markdown.parser.light:

knp_markdown:
parser:
service: markdown.parser.light

Before we see what that did, find your terminal and run:

./bin/console cache:clear

This... is a bummer. Normally, Symfony is smart-enough to rebuild its cache whenever we change a config file. But... there's currently a bug in Symfony where it does not notice new config files. So, for now, we need to do this on the rare occasion when we add a new file to config. It should be fixed soon.

So... what did this config change... actually... do? Well, because the purpose of a bundle is to give us services, the purpose of configuring a bundle is to change how those services behave. That might mean that a service will suddenly use a different class, or that different arguments are passed to a service object. As a user, it doesn't really matter to us: the bundle takes care of the ugly details.

Ok, refresh!

Ah, in this case the change is obvious! Our markdown parser is now an instance of a Light class. Cool!

More about Bundle Configuration

Now: why did I put this in a file named knp_markdown.yaml? Is that important? Actually, no! As we'll learn soon, Symfony automatically loads all files in packages/, and their names are meaningless, technically!

The super important part is the root - meaning, non-indented - key: knp_markdown. Each file in packages/ configures a different bundle. Any configuration under knp_markdown is passed to the KnpMarkdownBundle. Any config under framework configures FrameworkBundle, which is Symfony's one, "core" bundle:

framework:
secret: '%env(APP_SECRET)%'
#default_locale: en
#csrf_protection: ~
#http_method_override: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: ~
#esi: ~
#fragments: ~
php_errors:
log: true
cache:
# Put the unique name of your app here: the prefix seed
# is used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name
# The app cache caches to the filesystem by default.
# Other options include:
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu

And yea, twig configures TwigBundle:

twig:
paths: ['%kernel.project_dir%/templates']
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'

Every bundle has its own set of valid config. Heck, let's go check out Twig's config:

./bin/console config:dump TwigBundle

or we can just the config key instead:

./bin/console config:dump twig

Say hello to all of the valid options for TwigBundle. Of course, these keys are explained more on the TwigBundle docs... but isn't this awesome?

Next: the service container has been hiding something huge from us... like "dark matter" huge. Let's find out what it is.

Leave a comment!

1
Login or Register to join the conversation
Richard Avatar
Richard Avatar Richard | posted 3 years ago

./bin/console config:dump KnpMarkdownBundle shows the default. Should it not also take into account the customisation you describe in this tutorial?

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
        "nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
        "php-http/guzzle6-adapter": "^1.1", // v1.1.1
        "sensio/framework-extra-bundle": "^5.1", // v5.1.4
        "symfony/asset": "^4.0", // v4.0.4
        "symfony/console": "^4.0", // v4.0.14
        "symfony/flex": "^1.0", // v1.17.6
        "symfony/framework-bundle": "^4.0", // v4.0.14
        "symfony/lts": "^4@dev", // dev-master
        "symfony/twig-bundle": "^4.0", // v4.0.4
        "symfony/web-server-bundle": "^4.0", // v4.0.4
        "symfony/yaml": "^4.0" // v4.0.14
    },
    "require-dev": {
        "easycorp/easy-log-handler": "^1.0.2", // v1.0.4
        "symfony/debug-bundle": "^3.3|^4.0", // v4.0.4
        "symfony/dotenv": "^4.0", // v4.0.14
        "symfony/maker-bundle": "^1.0", // v1.0.2
        "symfony/monolog-bundle": "^3.0", // v3.1.2
        "symfony/phpunit-bridge": "^3.3|^4.0", // v4.0.4
        "symfony/profiler-pack": "^1.0", // v1.0.3
        "symfony/var-dumper": "^3.3|^4.0" // v4.0.4
    }
}
userVoice