Skip to content

Commit d2f58e0

Browse files
committed
feature #6017 Documented the Symfony Console Styles (javiereguiluz)
This PR was squashed before being merged into the 2.7 branch (closes #6017). Discussion ---------- Documented the Symfony Console Styles | Q | A | ------------- | --- | Doc fix? | no | New docs? | no | Applies to | 2.7+ | Fixed tickets | #14057 Commits ------- ab19079 Documented the Symfony Console Styles
2 parents b163920 + ab19079 commit d2f58e0

File tree

3 files changed

+381
-0
lines changed

3 files changed

+381
-0
lines changed

cookbook/console/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Console
66

77
console_command
88
usage
9+
style
910
command_in_controller
1011
sending_emails
1112
logging

cookbook/console/style.rst

Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
.. index::
2+
single: Console; Style commands
3+
4+
How to Style a Console Command
5+
==============================
6+
7+
.. versionadded:: 2.7
8+
Symfony Styles for console commands were introduced in Symfony 2.7.
9+
10+
One of the most boring tasks when creating console commands is to deal with the
11+
styling of the command's input and output. Displaying titles and tables or asking
12+
questions to the user involves a lot of repetitive code.
13+
14+
Consider for example the code used to display the title of the following command::
15+
16+
// src/AppBundle/Command/GreetCommand.php
17+
namespace AppBundle\Command;
18+
19+
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
20+
use Symfony\Component\Console\Input\InputInterface;
21+
use Symfony\Component\Console\Output\OutputInterface;
22+
23+
class GreetCommand extends ContainerAwareCommand
24+
{
25+
// ...
26+
27+
protected function execute(InputInterface $input, OutputInterface $output)
28+
{
29+
$output->writeln(array(
30+
'<info>Lorem Ipsum Dolor Sit Amet</>',
31+
'<info>==========================</>',
32+
'',
33+
));
34+
35+
// ...
36+
}
37+
}
38+
39+
Displaying a simple title requires three lines of code, to change the font color,
40+
underline the contents and leave an additional blank line after the title. Dealing
41+
with styles is required for well-designed commands, but it complicates their code
42+
unnecessarily.
43+
44+
In order to reduce that boilerplate code, Symfony commands can optionally use the
45+
**Symfony Style Guide**. These styles are implemented as a set of helper methods
46+
which allow to create *semantic* commands and forget about their styling.
47+
48+
Basic Usage
49+
-----------
50+
51+
In your command, instantiate the :class:`Symfony\\Component\\Console\\Style\\SymfonyStyle`
52+
class and pass the ``$input`` and ``$output`` variables as its arguments. Then,
53+
you can start using any of its helpers, such as ``title()``, which displays the
54+
title of the command::
55+
56+
// src/AppBundle/Command/GreetCommand.php
57+
namespace AppBundle\Command;
58+
59+
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
60+
use Symfony\Component\Console\Style\SymfonyStyle;
61+
use Symfony\Component\Console\Input\InputInterface;
62+
use Symfony\Component\Console\Output\OutputInterface;
63+
64+
class GreetCommand extends ContainerAwareCommand
65+
{
66+
// ...
67+
68+
protected function execute(InputInterface $input, OutputInterface $output)
69+
{
70+
$io = new SymfonyStyle($input, $output);
71+
$io->title('Lorem Ipsum Dolor Sit Amet');
72+
73+
// ...
74+
}
75+
}
76+
77+
Helper Methods
78+
--------------
79+
80+
The :class:`Symfony\\Component\\Console\\Style\\SymfonyStyle` class defines some
81+
helper methods that cover the most common interactions performed by console commands.
82+
83+
Titling Methods
84+
~~~~~~~~~~~~~~~
85+
86+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::title`
87+
It displays the given string as the command title. This method is meant to
88+
be used only once in a given command, but nothing prevents you to use it
89+
repeatedly::
90+
91+
$io->title('Lorem ipsum dolor sit amet');
92+
93+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::section`
94+
It displays the given string as the title of some command section. This is
95+
only needed in complex commands which want to better separate their contents::
96+
97+
$io->section('Adding a User');
98+
99+
// ...
100+
101+
$io->section('Generating the Password');
102+
103+
// ...
104+
105+
Content Methods
106+
~~~~~~~~~~~~~~~
107+
108+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::text`
109+
It displays the given string or array of strings as regular text. This is
110+
useful to render help messages and instructions for the user running the
111+
command::
112+
113+
// use simple strings for short messages
114+
$io->text('Lorem ipsum dolor sit amet');
115+
116+
// ...
117+
118+
// consider using arrays when displaying long messages
119+
$io->text(array(
120+
'Lorem ipsum dolor sit amet',
121+
'Consectetur adipiscing elit',
122+
'Aenean sit amet arcu vitae sem faucibus porta',
123+
));
124+
125+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::listing`
126+
It displays an unordered list of elements passed as an array::
127+
128+
$io->listing(array(
129+
'Element #1 Lorem ipsum dolor sit amet',
130+
'Element #2 Lorem ipsum dolor sit amet',
131+
'Element #3 Lorem ipsum dolor sit amet',
132+
));
133+
134+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::table`
135+
It displays the given array of headers and rows as a compact table::
136+
137+
$io->table(
138+
array('Header 1', 'Header 2'),
139+
array(
140+
array('Cell 1-1', 'Cell 1-2'),
141+
array('Cell 2-1', 'Cell 2-2'),
142+
array('Cell 3-1', 'Cell 3-2'),
143+
)
144+
);
145+
146+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::newLine`
147+
It displays a blank line in the command output. Although it may seem useful,
148+
most of the times you won't need it at all. The reason is that every helper
149+
already adds their own blank lines, so you don't have to care about the
150+
vertical spacing::
151+
152+
// outputs a single blank line
153+
$io->newLine();
154+
155+
// outputs three consecutive blank lines
156+
$io->newLine(3);
157+
158+
Admonition Methods
159+
~~~~~~~~~~~~~~~~~~
160+
161+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::note`
162+
It displays the given string or array of strings as a highlighted admonition.
163+
Use this helper sparingly to avoid cluttering command's output::
164+
165+
// use simple strings for short notes
166+
$io->note('Lorem ipsum dolor sit amet');
167+
168+
// ...
169+
170+
// consider using arrays when displaying long notes
171+
$io->note(array(
172+
'Lorem ipsum dolor sit amet',
173+
'Consectetur adipiscing elit',
174+
'Aenean sit amet arcu vitae sem faucibus porta',
175+
));
176+
177+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::caution`
178+
Similar to the ``note()`` helper, but the contents are more prominently
179+
highlighted. The resulting contents resemble an error message, so you should
180+
avoid using this helper unless strictly necessary::
181+
182+
// use simple strings for short caution message
183+
$io->caution('Lorem ipsum dolor sit amet');
184+
185+
// ...
186+
187+
// consider using arrays when displaying long caution messages
188+
$io->caution(array(
189+
'Lorem ipsum dolor sit amet',
190+
'Consectetur adipiscing elit',
191+
'Aenean sit amet arcu vitae sem faucibus porta',
192+
));
193+
194+
Progress Bar Methods
195+
~~~~~~~~~~~~~~~~~~~~
196+
197+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::progressStart`
198+
It displays a progress bar with a number of steps equal to the argument passed
199+
to the method (don't pass any value if the length of the progress bar is
200+
unknown)::
201+
202+
// displays a progress bar of unknown length
203+
$io->progressStart();
204+
205+
// displays a 100-step length progress bar
206+
$io->progressStart(100);
207+
208+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::progressAdvance`
209+
It makes the progress bar advance the given number of steps (or ``1`` step
210+
if no argument is passed)::
211+
212+
// advances the progress bar 1 step
213+
$io->progressAdvance();
214+
215+
// advances the progress bar 10 steps
216+
$io->progressAdvance(10);
217+
218+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::progressFinish`
219+
It finishes the progress bar (filling up all the remaining steps when its
220+
length is known)::
221+
222+
$io->progressFinish();
223+
224+
User Input Methods
225+
~~~~~~~~~~~~~~~~~~
226+
227+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::ask`
228+
It asks the user to provide some value::
229+
230+
$io->ask('What is your name?');
231+
232+
You can pass the default value as the second argument so the user can simply
233+
hit the <Enter> key to select that value::
234+
235+
$io->ask('Where are you from?', 'United States');
236+
237+
In case you need to validate the given value, pass a callback validator as
238+
the third argument::
239+
240+
$io->ask('Number of workers to start', 1, function ($number) {
241+
if (!is_integer($number)) {
242+
throw new \RuntimeException('You must type an integer.');
243+
}
244+
245+
return $number;
246+
});
247+
248+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::askHidden`
249+
It's very similar to the ``ask()`` method but the user's input will be hidden
250+
and it cannot define a default value. Use it when asking for sensitive information::
251+
252+
$io->askHidden('What is your password?');
253+
254+
// validates the given answer
255+
$io->askHidden('What is your password?', function ($password) {
256+
if (empty($password)) {
257+
throw new \RuntimeException('Password cannot be empty.');
258+
}
259+
260+
return $password;
261+
});
262+
263+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::confirm`
264+
It asks a Yes/No question to the user and it only returns ``true`` or ``false``::
265+
266+
$io->confirm('Restart the web server?');
267+
268+
You can pass the default value as the second argument so the user can simply
269+
hit the <Enter> key to select that value::
270+
271+
$io->confirm('Restart the web server?', true);
272+
273+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::choice`
274+
It asks a question whose answer is constrained to the given list of valid
275+
answers::
276+
277+
$io->choice('Select the queue to analyze', array('queue1', 'queue2', 'queue3'));
278+
279+
You can pass the default value as the third argument so the user can simply
280+
hit the <Enter> key to select that value::
281+
282+
$io->choice('Select the queue to analyze', array('queue1', 'queue2', 'queue3'), 'queue1');
283+
284+
Result Methods
285+
~~~~~~~~~~~~~~
286+
287+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::success`
288+
It displays the given string or array of strings highlighted as a successful
289+
message (with a green background and the ``[OK]`` label). It's meant to be
290+
used once to display the final result of executing the given command, but you
291+
can use it repeatedly during the execution of the command::
292+
293+
// use simple strings for short success messages
294+
$io->success('Lorem ipsum dolor sit amet');
295+
296+
// ...
297+
298+
// consider using arrays when displaying long success messages
299+
$io->success(array(
300+
'Lorem ipsum dolor sit amet',
301+
'Consectetur adipiscing elit',
302+
));
303+
304+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::warning`
305+
It displays the given string or array of strings highlighted as a warning
306+
message (with a read background and the ``[WARNING]`` label). It's meant to be
307+
used once to display the final result of executing the given command, but you
308+
can use it repeatedly during the execution of the command::
309+
310+
// use simple strings for short warning messages
311+
$io->warning('Lorem ipsum dolor sit amet');
312+
313+
// ...
314+
315+
// consider using arrays when displaying long warning messages
316+
$io->warning(array(
317+
'Lorem ipsum dolor sit amet',
318+
'Consectetur adipiscing elit',
319+
));
320+
321+
:method:`Symfony\\Component\\Console\\Style\\StyleInterface::error`
322+
It displays the given string or array of strings highlighted as an error
323+
message (with a read background and the ``[ERROR]`` label). It's meant to be
324+
used once to display the final result of executing the given command, but you
325+
can use it repeatedly during the execution of the command::
326+
327+
// use simple strings for short error messages
328+
$io->error('Lorem ipsum dolor sit amet');
329+
330+
// ...
331+
332+
// consider using arrays when displaying long error messages
333+
$io->error(array(
334+
'Lorem ipsum dolor sit amet',
335+
'Consectetur adipiscing elit',
336+
));
337+
338+
Defining your Own Styles
339+
------------------------
340+
341+
If you don't like the design of the commands that use the Symfony Style, you can
342+
define your own set of console styles. Just create a class that implements the
343+
:class:`Symfony\\Component\\Console\\Style\\StyleInterface`::
344+
345+
namespace AppBundle\Console;
346+
347+
use Symfony\Component\Console\Style\StyleInterface;
348+
349+
class CustomStyle implements StyleInterface
350+
{
351+
// ...implement the methods of the interface
352+
}
353+
354+
Then, instantiate this custom class instead of the default ``SymfonyStyle`` in
355+
your commands. Thanks to the ``StyleInterface`` you won't need to change the code
356+
of your commands to change their appearance::
357+
358+
namespace AppBundle\Console;
359+
360+
use AppBundle\Console\CustomStyle;
361+
use Symfony\Component\Console\Input\InputInterface;
362+
use Symfony\Component\Console\Output\OutputInterface;
363+
use Symfony\Component\Console\Style\SymfonyStyle;
364+
365+
class GreetCommand extends ContainerAwareCommand
366+
{
367+
// ...
368+
369+
protected function execute(InputInterface $input, OutputInterface $output)
370+
{
371+
// Before
372+
// $io = new SymfonyStyle($input, $output);
373+
374+
// After
375+
$io = new CustomStyle($input, $output);
376+
377+
// ...
378+
}
379+
}

cookbook/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
* :doc:`/cookbook/console/console_command`
4646
* :doc:`/cookbook/console/usage`
47+
* :doc:`/cookbook/console/style`
4748
* :doc:`/cookbook/console/command_in_controller`
4849
* :doc:`/cookbook/console/sending_emails`
4950
* :doc:`/cookbook/console/logging`

0 commit comments

Comments
 (0)