Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This course is archived!

Console Styling

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 $6.00

We all love ice cream and Symfony's console. We love the ability to add colors, beer shaped progress bars, tables and a bunch of other cool stuff.

A little feature snuck into Symfony 2.7 and was improved greatly in Symfony 2.8. It's called the SymfonyStyle. It's more than just a cool way to dress, it's the Twitter Bootstrap for styling console commands. Ok ok, it's not a huge deal, but let's face it, that blog post with the beer icon in the console? It's pretty much our most popular blog post... so clearly you guys love this stuff.

Create a new Command directory. Inside, I'll take the lazy road and have PhpStorm make me a new command called StylesPlayCommand. Give it a name! styles:play:

... lines 1 - 2
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class StylesPlayCommand extends ContainerAwareCommand
protected function configure()
protected function execute(InputInterface $input, OutputInterface $output)

Start like we always do, with lame, worn-out $output->writeln('boring'). Zip over to the terminal and try that out:

./bin/console styles:play

And there it is! In all its white text on a black background glory.

Introducing SymfonyStyle

Enough of that! That still works, it will always work. But now, create a new $style variable set to new SymfonyStyle(). Pass it the $input and $output:

... lines 1 - 17
protected function execute(InputInterface $input, OutputInterface $output)
$style = new SymfonyStyle($input, $output);
... lines 21 - 26
... lines 28 - 29

This class comes from a few friends of mine, Kevin Bond & Javier Eguiluz. This dynamic Canadian-Spaniard team sat down and designed a good-looking style guide that can be used for all commands in the Symfony ecosystem. As Javier put it, this is basically the stylesheet for your commands. We use simple methods, and Javier makes sure it looks good. Thanks Javier!

Ok, let's take this for a test drive. First, we need a big title: $style->title('Welcome to SymfonyStyle!') and then a sub-header with $style->section('Wow, look at this text section');. To print out normal text, use $style->text(). I'll quote all demo pages on the Internet by saying "Lorem ipsum Dolor"... a bunch of times:

... lines 1 - 19
$style = new SymfonyStyle($input, $output);
$style->title('Welcome to SymfonyStyle');
$style->section('Wow, look at this text section');
$style->text('Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, Lorem ipsum dolor, ');
... lines 24 - 29

Because we're worried about all these "Lorem ipsums", use $style->note('') to remind people to "write some real text eventually":

... lines 1 - 23
$style->note('Make sure you write some *real* text eventually');
... lines 25 - 29

Let's try it! Run:

./bin/console styles:play

OooOOooooOOO. Without doing anything, Javier gives us the console equivalent of h1 and h2 tags, with colors and separation. Below, it's subtle, but all the text lines are indented with one space to make them stand out. The note starts with an exclamation point and uses a hip color.

Get the idea?

Back on the command, add one more text line: $style->comment('Lorem ipsum is just latin garbage');. Follow that with $style->comment('So don\'t overuse it'). Make sure the method name is correct:

... lines 1 - 24
$style->comment('Lorem ipsum is just Latin garbage');
$style->comment('So don\'t overuse it');
... lines 27 - 29

Run it again!

./bin/console styles:play

More indented text, this time with a little bit different styling.

Success and Error Messages

Time to take the fancy up a notch! Add another section for some BIG messages. SymfonyStyle has built-in methods to emphasize that "things are great!", "things are terrible! or "OMG things are really terrible". Start with $style->success('I <3 Lorem ipsum');:

... lines 1 - 27
$style->section('How about some BIG messages?');
$style->success('I <3 lorem ipsum');
... lines 30 - 35

Try it!

./bin/console styles:play

A big ol' nice green message that just screams celebration.

Ok, maybe we don't love "Lorem ipsum". Send a warning with $style->warning('You should *maybe* not use Lorem ipsum');:

... lines 1 - 29
$style->warning('You should *maybe* not use Lorem ipsum');
... lines 31 - 35

Try that!

./bin/console styles:play

Now we have a menacing red message: you've been warned...

Next, try $style->error('You should stop using Lorem ipsum');. And throw in one last word of caution, $style->caution('STOP USING IT SRSLY!');:

... lines 1 - 30
$style->error('You should stop using lorem ipsum');
$style->caution('STOP USING IT SRSLY!');
... lines 33 - 35

When we run this, we've got four blocks: all styled for their meaning with nice spacing, coloration and margin. Thanks Javier!

Tables and Lists

The SymfonyStyle has helpers for a few other things, like progress bars and tables. Create a new section: $style->section('Some tables and lists?');:

... lines 1 - 33
$style->section('Some tables and lists?');
... lines 35 - 51

Creating tables isn't new, but $style has a shortcut where Javier styles them for us. Thanks Javier!

Use $style->table(). The first argument holds the headers: ['User', 'Birthday'], and the second argument holds the rows. Plug in an important birthday to remember: ['weaverryan','June 5th'] and an even more important one to remember, ['leannapelham','All of February']. That's right, the celebration for Leanna never ends:

... lines 1 - 34
['User', 'Birthday'],
['weaverryan', 'June 5th'],
['leannapelham', 'All February']
... lines 42 - 51

So let's see how this renders!

./bin/console styles:play

Wow, look at that table: nice spacing, nice styled headers. Of course you could do this all yourself, but why?

Ok, time for just one more: a list of my favorite things: $style->text('Ryan\'s my favorite things') with a nicely-styled list. Use $style->listing([]). Pass this an array, which you can think of as an unordered list. Let's see, I like ['Running', 'Pizza', 'Watching Leanna tease Jordi Boggiano',]:

... lines 1 - 42
$style->text('Ryan\'s favorite things:');
'Watching Leanna tease Jordi Boggiano'
... lines 49 - 51

Ok last run in the terminal!

./bin/console styles:play

There you have it, the SymfonyStyle. Thanks Javier! Seriously, Javier is a cool dude.

Leave a comment!

Login or Register to join the conversation
Default user avatar
Default user avatar Dimitry K | posted 5 years ago

Thank you for great videos! Btw, is there a way to display things in a table when I don't know number of items beforehand... or in other words where rows are added to the table "live"...


Thanks Dimitry K!

Hmm, I don't think what you're asking is possible. Basically, the table needs to be built first entirely, and *then* rendered, otherwise Symfony won't be able to know how wide to make the columns (which it calculates based on the number of columns and the width of the content inside the columns). But, it still might be possible: as long as you are able to build the table and *then* render it, there shouldn't be a problem. What I mean is, even if you have a variable number of columns, as long as you're able to determine how many columns you have when building the table, and then you build the table with the data, Symfony will have no problem rendering that :).

Let me know if that helps! And cheers!

Cat in space

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

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.0.*", // v3.0.0
        "doctrine/orm": "~2.5@dev", // 2.7.x-dev
        "doctrine/doctrine-bundle": "~1.6@dev", // 1.10.x-dev
        "doctrine/doctrine-cache-bundle": "~1.2@dev", // 1.3.2
        "symfony/security-acl": "~3.0@dev", // dev-master
        "symfony/swiftmailer-bundle": "~2.3", // v2.3.8
        "symfony/monolog-bundle": "~2.7@dev", // dev-master
        "sensio/distribution-bundle": "~5.0@dev", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.11
        "incenteev/composer-parameter-handler": "~2.0", // v2.1.2
        "doctrine/doctrine-fixtures-bundle": "^2.3", // v2.4.1
        "composer/package-versions-deprecated": "^1.11" // 1.11.99
    "require-dev": {
        "sensio/generator-bundle": "~3.0", // v3.0.0
        "symfony/phpunit-bridge": "~2.7" // v2.7.6