Code blocks with syntax highlighting
Table of contents
Quick reference
A code block consists of a code- directive and the actual code indented
by four spaces for consistency with other code bases.
A code block can have one or more options. To make orientation in code examples easier
try to always add a :caption: with the path and name of the file where the example should go:
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:my_sitepackage/Resources/Private/PageView/
}
}
}
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:my_sitepackage/Resources/Private/PageView/
}
}
}
Always use syntactically correct code in a code block.
For code longer than about three lines in a programming or configuration language, prefer a file of its own included with literalinclude.
Use placeholders in angle brackets
(<placeholder-) to refer to a place in the code where the exact
value is not important.
Code block directive
A code block has the following syntax:
.. code-block:: <language>
:caption: <caption>
<options>
<code>
There must be a newline between the options and the code. There must not be a newline between the directive line and options or within options. Otherwise the rendering will fail.
- <language>
-
The language of the code-block. We commonly use the following:
php,typoscript(also for TSconfig),yaml,javascript,html(also for Fluid),shell,xml,plaintext.See all available languages
- <caption>
- To make orientation in code examples easier try to always add a caption with the name of the file where the example should go. If the code should be manually entered in the TYPO3 backend explain where it should go there.
- <options>
-
The following options may be used, all options are optional, but
captionis highly recommended:.. code-block:: <language> :caption: <caption> :linenos: :lineno-start: <start-number> :emphasize-lines: <emphasized-line-numbers> :visible-lines: <visible-line-numbers> :name: <reference-label>Copied!linenos- Show line numbers. Use it whenever the text refers to a line by its number, so the reader can see that number instead of counting, see Referring to a line by its number.
lineno-start - Start line numbers with <start-number>.
emphasize-lines - <emphasized-line-numbers> contains a comma separated list of line numbers to be emphasized.
visible-lines - <visible-line-numbers> contains a comma separated list of line numbers
and ranges, for example
15-, that stay visible. Every other line is folded away behind a placeholder that opens it.16, 24- 35 allswitches the folding off. Unlike the options above, this one only works in the TYPO3 rendering. name- Set a <reference-label>. This label can be used to link from any given text to the specific code block. The name needs to be unique within one manual.
A PHP block folds its header on its own, without any option: the open tag, the
declare,namespaceandusestatements, and the comments and blank lines among them. It stays as it is when that header is shorter than three lines, and an emphasized line is never folded.Folding hides nothing from the reader who wants it: copying the block takes every line, and so do the print view, the Markdown of the page and a browser without JavaScript.
See also the official Sphinx documentation on code blocks.
Captioning a part of a file
A caption names the file the code belongs in, so the reader knows where to put
it. Add
(excerpt)
after the path when the block shows only a part of
that file:
.. code-block:: php
:caption: EXT:my_extension/Configuration/Backend/Modules.php (excerpt)
'mymodule' => [
'parent' => 'content',
],
Use it whenever the block would not work on its own: a few keys out of a longer array, one method out of a class, the changed lines of a file that has more in it. Without the marker the caption reads as the whole file, and a reader who copies the block into a new file of that name loses everything around it.
Examples
A simple code block with syntax highlighting
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:my_sitepackage/Resources/Private/PageView/
}
}
}
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:my_sitepackage/Resources/Private/PageView/
}
}
}
Code block with line numbers and highlighted lines
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
:linenos:
:emphasize-lines: 3, 6
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:my_sitepackage/Resources/Private/PageView/
}
}
}
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:my_sitepackage/Resources/Private/PageView/
}
}
}
Folding lines in code blocks
The header of the file is folded on its own because the example is PHP.
:visible- names the lines to keep beyond it, here the method the
example is about:
.. code-block:: php
:caption: EXT:my_extension/Classes/EventListener/MyListener.php
:visible-lines: 12-17
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Resource\Event\AfterFileAddedEvent;
final class MyListener
{
#[AsEventListener]
public function __invoke(AfterFileAddedEvent $event): void
{
// Your code here
}
}
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Resource\Event\AfterFileAddedEvent;
final class MyListener
{
#[AsEventListener]
public function __invoke(AfterFileAddedEvent $event): void
{
// Your code here
}
}
In a language other than PHP nothing is folded until you say so. Here only the service the text is about stays visible, and the rest of the file folds away:
.. code-block:: yaml
:caption: EXT:my_extension/Configuration/Services.yaml
:visible-lines: 9-11
services:
_defaults:
autowire: true
autoconfigure: true
public: false
MyVendor\MyExtension\:
resource: '../Classes/*'
MyVendor\MyExtension\Service\GreeterService:
public: true
MyVendor\MyExtension\EventListener\MyListener:
tags:
- name: event.listener
identifier: 'my-extension/my-listener'
services:
_defaults:
autowire: true
autoconfigure: true
public: false
MyVendor\MyExtension\:
resource: '../Classes/*'
MyVendor\MyExtension\Service\GreeterService:
public: true
MyVendor\MyExtension\EventListener\MyListener:
tags:
- name: event.listener
identifier: 'my-extension/my-listener'
Use it where a reader has to see the code in its file, but only a part of it is the point. Where the block works on its own, show that part alone and mark the caption as an excerpt, see Captioning a part of a file.
Referring to a line by its number
When the text refers to a line by its number, show the line numbers with
:linenos:
and use the number the reader sees beside the line. Do not
count the lines yourself.
The numbers count the lines of the source, one per line break. A folded line keeps its number, so the first visible line below is line 10, not line 1. A line too long for the screen wraps but is still one line.
Emphasize the lines the text is about, so the reader finds them without counting:
.. code-block:: php
:caption: EXT:my_extension/Classes/EventListener/MyListener.php
:linenos:
:emphasize-lines: 12-13
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Resource\Event\AfterFileAddedEvent;
final class MyListener
{
#[AsEventListener]
public function __invoke(AfterFileAddedEvent $event): void
{
// Your code here
}
}
The attribute in line 12 registers the method as an event listener. The type
of its argument in line 13 tells TYPO3 which event the method listens to.
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Resource\Event\AfterFileAddedEvent;
final class MyListener
{
#[AsEventListener]
public function __invoke(AfterFileAddedEvent $event): void
{
// Your code here
}
}
The attribute in line 12 registers the method as an event listener. The type of its argument in line 13 tells TYPO3 which event the method listens to.
A line number goes out of date as soon as a line is added above it. Name what is in the line as well, like "the attribute in line 12", so the sentence still leads the reader to the right line, and check the numbers whenever you change the code.
Use code blocks containing diffs
If you have the file before and after the change, use literalinclude with the option :diff: instead of a diff that you write by hand.
To show a change in a short fragment, write the diff in a code block:
.. code-block:: diff
:caption: ext_localconf.php.diff
<?php
-defined('TYPO3_MODE') or die();
+defined('TYPO3') or die();
<?php
-defined('TYPO3_MODE') or die();
+defined('TYPO3') or die();
Hint
You can use diff tools such as the
bartlweb diff file generator. Make
sure to use the type unified context
Show a directory tree
To display an expandable directory tree, use the directive '.. directory-tree::'.
.. code-block:: none
:caption: Page tree of directory :file:`vendor/composer`
$ tree vendor/composer
├── ClassLoader.php
├── LICENSE
├── autoload_classmap.php
├── ...
└── installed.json
vendor/composer
$ tree vendor/composer
├── ClassLoader.php
├── LICENSE
├── autoload_classmap.php
├── ...
└── installed.json
Use syntactically correct code
Attention
Please: No syntax errors!
Syntax highlighting only works if the lexer can parse the code without errors. In other words: If there's a syntax error in the code the highlighting will not work.
.. code-block:: php
$a = array(
'one' => 1,
// ...
);
.. code-block:: php
$a = array(
'one' => 1,
...
);
Available languages
The following languages are supported. They can be used in a
code-
and a
literalinclude
directive.
- 1c
- abnf
- accesslog
- actionscript
- ada
- angelscript
- apache
- applescript
- arcade
- arduino
- armasm
- asciidoc
- aspectj
- autohotkey
- autoit
- avrasm
- awk
- axapta
- bash
- basic
- bnf
- brainfuck
- cal
- capnproto
- ceylon
- clean
- clojure
- clojure-repl
- cmake
- coffeescript
- coq
- cos
- cpp
- crmsh
- crystal
- cs
- csp
- css
- d
- dart
- delphi
- diff
- django
- dns
- dockerfile
- dos
- dsconfig
- dts
- dust
- ebnf
- elixir
- elm
- erb
- erlang
- erlang-repl
- excel
- fix
- flix
- fortran
- fsharp
- gams
- gauss
- gcode
- gherkin
- glsl
- gml
- go
- golo
- gradle
- groovy
- haml
- handlebars
- haskell
- haxe
- hsp
- htmlbars
- http
- hy
- inform7
- ini
- irpf90
- isbl
- java
- javascript
- jboss-cli
- json
- julia
- julia-repl
- kotlin
- lasso
- ldif
- leaf
- less
- lisp
- livecodeserver
- livescript
- llvm
- lsl
- lua
- makefile
- markdown
- mathematica
- matlab
- maxima
- mel
- mercury
- mipsasm
- mizar
- mojolicious
- monkey
- moonscript
- n1ql
- nginx
- nimrod
- nix
- nsis
- objectivec
- ocaml
- openscad
- oxygene
- parser3
- perl
- pf
- pgsql
- php
- plaintext
- pony
- powershell
- processing
- profile
- prolog
- properties
- protobuf
- puppet
- purebasic
- python
- q
- qml
- r
- reasonml
- rib
- roboconf
- routeros
- rsl
- rst
- ruby
- ruleslanguage
- rust
- sas
- scala
- scheme
- scilab
- scss
- shell
- smali
- smalltalk
- sml
- sqf
- sql
- stan
- stata
- step21
- stylus
- subunit
- swift
- taggerscript
- tap
- tcl
- tex
- thrift
- tp
- twig
- typescript
- typoscript
- vala
- vbnet
- vbscript
- vbscript-html
- verilog
- vhdl
- vim
- x86asm
- xl
- xml
- xquery
- yaml
- zephir
Literalinclude
The directive
literalinclude
imports a file and displays its content as
a code block.
When the code is longer than about three lines and written in a programming or
configuration language, such as PHP, YAML, TypoScript or JavaScript, prefer
literalinclude
over
code-. Store the code in a file of its
own with the proper file extension, for example in
Documentation/_, and include it from there:
- Linters and coding guideline checks can run on the file, so the example stays free of syntax errors and follows the coding guidelines.
- You can work on the file in your IDE, with its highlighting, completion and formatting. Most editors cannot do that for code inside a code block.
Keep a
code- for a few lines, for shell commands, and for a
fragment that would not be valid code in a file of its own.
.. literalinclude:: /_CodeSnippets/LiteralIncludes/example.yaml
:emphasize-lines: 5,10-13
:linenos:
See also literalinclude directive.
Language of the included file
A
literalinclude
takes the language for the syntax highlighting from
the name of the file. The example above needs no option
:language:
,
because the file ends in .yaml.
The rendering looks at the name in this order:
- The last extension, in any case, for example
.phpor.YAML. - The extension before it, if the last one does not name a language.
Example.is PHP, andphp. inc services.is YAML.yaml. dist - The name of the file, for a file without such an extension:
DockerfileandMakefile. A leading underscore, as in_Dockerfile, does not count.
A known last extension wins, so _Example. is plain text.
| Language | Extension or file name |
|---|---|
apache | .htaccess |
bash | .bash, .env, .sh, .zsh |
css | .css |
diff | .diff, .patch |
dockerfile | Dockerfile |
html | .html |
ini | .ini, .toml |
javascript | .cjs, .js, .mjs |
json | .json |
less | .less |
makefile | Makefile |
markdown | .md |
php | .php |
plaintext | .csv, .txt |
python | .py |
rst | .rst |
scss | .scss |
sql | .sql |
twig | .twig |
typescript | .ts |
typoscript | .tsconfig, .typoscript |
xml | .svg, .xlf, .xliff, .xml, .xsd |
yaml | .yaml, .yml |
If the name tells no language, the rendering shows the file as plain text
and logs a warning. Set the language with
:language:
in this case.
The option also wins over the name of the file, for example to highlight
a .txt file as TypoScript.
Show the changes between two files
To show how a file changes, keep the file as it was and the file as it is.
Include the file as it is, and name the file as it was in the option
:diff:
. The block then shows the changes as a unified diff:
.. literalinclude:: /_CodeSnippets/LiteralIncludes/site-config-after.yaml
:diff: /_CodeSnippets/LiteralIncludes/site-config-before.yaml
:caption: config/sites/my-site/config.yaml
--- /_CodeSnippets/LiteralIncludes/site-config-before.yaml
+++ /_CodeSnippets/LiteralIncludes/site-config-after.yaml
@@ -9,6 +9,16 @@
locale: en_US.UTF-8
navigationTitle: English
flag: us
+ -
+ title: Deutsch
+ enabled: true
+ languageId: 1
+ base: /de/
+ locale: de_DE.UTF-8
+ navigationTitle: Deutsch
+ flag: de
+ fallbackType: fallback
+ fallbacks: '0'
errorHandling:
-
errorCode: 404
The block shows each changed line with one unchanged line above and below it. The headers of the diff and the other unchanged lines are folded. The reader can click a folded part to open it.
The other options of
literalinclude
still work.
:emphasize- and
:visible- count the lines of the
diff, not the lines of the file. Use
:visible- to show the
whole diff.
If the two files are the same, the block shows the file without a diff, and the rendering reports a warning.
Prefer
:diff:
over a diff that you write by hand: the two files can
be checked like other code, and the diff always matches them.
Placeholders
Placeholders in this context are named tags in code and
example URLs where the exact value does not matter,
but is referenced in the surrounding documentation.
Use the Backus-Naur form <placeholder- for placeholders in code and
URLs, i.e. use angle brackets to encapsulate the placeholder name.
For example in PHP
Set up a controller class to handle user interaction with the entity data
model:
.. code-block:: php
class <Entity>Controller extends ActionController
{
..
}
where `<Entity>` corresponds to the entity data model class name.
or on the command line
To import a TYPO3 dump file, run:
.. code-block:: bash
typo3/sysext/core/bin/typo3 impexp:import <file>
where `<file>` can be the absolute path on the server or the relative path
in the TYPO3 project folder.
or in an example URL
The TYPO3 backend normally appends the session token ID to the URL as
follows: :samp:`https://example.org/typo3/main?token=<token-id>`.
In the XML and HTML markup languages, which make extensive use of angle
brackets, the comment tag
<!-- placeholder- is used to insert
placeholders. A <placeholder- looks like a regular element and would lead to confusion.
Example names for extensions and site packages
A code example needs the name of the extension it belongs to, in the caption, in paths, and in namespaces. Use the same names in all manuals, so that a reader recognizes them:
my_sitepackage - The site package of the example site. It contains what makes up the
theme and the output of the site: page templates, and the TypoScript and
TSconfig of the site. Paths start with
EXT:, and the namespace ismy_ sitepackage/ \My.Vendor\ My Sitepackage my_extension - An extension that brings its own functionality, such as fields, tables,
and plugins. Paths start with
EXT:, and the namespace ismy_ extension/ \My. Its tables and fields start withVendor\ My Extension tx_.myextension_
The main set of an extension or a site package is always in
Configuration/, for example
EXT: and
EXT:. Only an additional set next to
the main set gets a name of its own, one that says what it does, such as
Sets/. Do not name the main set after the package or give it a
generic name, such as Sets/, Sets/, or
Sets/.
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
A TSconfig file that TYPO3 does not load on its own, such as a static file
that an extension registers, goes below Configuration/, for
example EXT:.
Write the directory name in CamelCase, like Configuration/. The
spelling TSconfig is for text, not for directory names. The file name ends
with .tsconfig.
Some names look like these, but are real packages. Keep them as they are:
the packages t3docs/ and t3docs/, the
repository TYPO3-, and my_, the
site package that the
site package tutorial
builds. A real extension keeps the names of its sets as well, such as
Sets/ of
typo3/cms-seo
.
Outdated code block formats
For historic reasons the
:caption:
option is missing in many code blocks.
Try to add them whenever you touch the reST files. Do not add new code blocks
without a caption stating the file name. It is often very confusing for new
developers where a certain code snippet should go. The recommended file name
can help to clear this up.
We recommend that you always write the language name after the code block directive. This makes it easier for first time contributors to adjust or copy-paste code blocks. For historic reasons there are code blocks without an explicit language.
If you do not explicitly set the language, the default language (PHP) is used.
In the past a simplified shorthand directive was widely used: A sentence ending
with a double colon
::
, followed by a new line and an indented
block of code. This quick syntax has several drawbacks:
- It is confusing to developers who seldom contribute
- We cannot give a caption and state the file name where the code should go.
- The script language is only stated implicitly.
- Such code blocks cannot be easily copy-pasted to use them as a foundation for your own code blocks.
You can change these code blocks like this:
The extension already contains some unit tests that extend the base
-unit test class in directory :file:`Tests/Unit/Hooks` (stripped)::
+unit test class in directory :file:`Tests/Unit/Hooks` (stripped):
+
+.. code-block:: php
+ :caption: EXT:my_extension/Tests/Unit/Hooks/DataHandlerFlushByTagHookTest.php
<?php
namespace MyVendor\MyExtension\Tests\Unit\Hooks;