Code blocks with syntax highlighting 

Quick reference 

A code block consists of a code-block 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:

Documentation/MyDocs.rst
..  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/
        }
      }
    }
Copied!
EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
page = PAGE
page {
  10 = PAGEVIEW
  10 {
    paths {
      100 = EXT:my_sitepackage/Resources/Private/PageView/
    }
  }
}
Copied!

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-name>) 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:

Documentation/MyDocs.rst
..  code-block:: <language>
    :caption: <caption>
    <options>

    <code>
Copied!

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 caption is 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-16, 24-35, that stay visible. Every other line is folded away behind a placeholder that opens it. all switches 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 , namespace and use statements, 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',
    ],
Copied!

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 

Documentation/MyDocs.rst
..  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/
        }
      }
    }
Copied!
EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
page = PAGE
page {
  10 = PAGEVIEW
  10 {
    paths {
      100 = EXT:my_sitepackage/Resources/Private/PageView/
    }
  }
}
Copied!

Code block with line numbers and highlighted lines 

Documentation/MyDocs.rst
..  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/
        }
      }
    }
Copied!
EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
page = PAGE
page {
  10 = PAGEVIEW
  10 {
    paths {
      100 = EXT:my_sitepackage/Resources/Private/PageView/
    }
  }
}
Copied!

Folding lines in code blocks 

The header of the file is folded on its own because the example is PHP. :visible-lines: names the lines to keep beyond it, here the method the example is about:

Documentation/MyDocs.rst
..  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
        }
    }
Copied!
EXT:my_extension/Classes/EventListener/MyListener.php
<?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
    }
}
Copied!

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:

Documentation/MyDocs.rst
..  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'
Copied!
EXT:my_extension/Configuration/Services.yaml
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'
Copied!

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:

Documentation/MyDocs.rst
..  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.
Copied!
EXT:my_extension/Classes/EventListener/MyListener.php
<?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
  }
}
Copied!

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:

Documentation/MyDocs.rst
..  code-block:: diff
    :caption: ext_localconf.php.diff

     <?php

    -defined('TYPO3_MODE') or die();
    +defined('TYPO3') or die();
Copied!
ext_localconf.php.diff
 <?php

-defined('TYPO3_MODE') or die();
+defined('TYPO3') or die();
Copied!

Show a directory tree 

To display an expandable directory tree, use the directive '.. directory-tree::'.

Documentation/MyDocs.rst
..  code-block:: none
    :caption: Page tree of directory :file:`vendor/composer`

    $ tree vendor/composer
    ├── ClassLoader.php
    ├── LICENSE
    ├── autoload_classmap.php
    ├── ...
    └── installed.json
Copied!
Page tree of directory vendor/composer
$ tree vendor/composer
├── ClassLoader.php
├── LICENSE
├── autoload_classmap.php
├── ...
└── installed.json
Copied!

Use syntactically correct code 

Available languages 

The following languages are supported. They can be used in a code-block 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-block . Store the code in a file of its own with the proper file extension, for example in Documentation/_CodeSnippets/, 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-block for a few lines, for shell commands, and for a fragment that would not be valid code in a file of its own.

Documentation/SiteConfiguration/Index.rst
..  literalinclude:: /_CodeSnippets/LiteralIncludes/example.yaml
    :emphasize-lines: 5,10-13
    :linenos:
Copied!
base: /
errorHandling: {  }
languages:
  -
    title: English
    enabled: true
    languageId: 0
    base: /
    typo3Language: default
    locale: en_US.UTF-8
    iso-639-1: en
    navigationTitle: English
    hreflang: en-us
    direction: ltr
    flag: us
rootPageId: 1
routes: {  }
Copied!

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:

  1. The last extension, in any case, for example .php or .YAML.
  2. The extension before it, if the last one does not name a language. Example.php.inc is PHP, and services.yaml.dist is YAML.
  3. The name of the file, for a file without such an extension: Dockerfile and Makefile. A leading underscore, as in _Dockerfile, does not count.

A known last extension wins, so _Example.rst.txt 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:

Documentation/MyDocs.rst
..  literalinclude:: /_CodeSnippets/LiteralIncludes/site-config-after.yaml
    :diff: /_CodeSnippets/LiteralIncludes/site-config-before.yaml
    :caption: config/sites/my-site/config.yaml
Copied!
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
Copied!

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-lines: and :visible-lines: count the lines of the diff, not the lines of the file. Use :visible-lines: all 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-name> 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.
Copied!

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.
Copied!

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>`.
Copied!

In the XML and HTML markup languages, which make extensive use of angle brackets, the comment tag <!-- placeholder-name --> is used to insert placeholders. A <placeholder-name> 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:my_sitepackage/, and the namespace is \MyVendor\MySitepackage .
my_extension
An extension that brings its own functionality, such as fields, tables, and plugins. Paths start with EXT:my_extension/, and the namespace is \MyVendor\MyExtension . Its tables and fields start with tx_myextension_.

The main set of an extension or a site package is always in Configuration/Sets/Main/, for example EXT:my_sitepackage/Configuration/Sets/Main/ and EXT:my_extension/Configuration/Sets/Main/. Only an additional set next to the main set gets a name of its own, one that says what it does, such as Sets/RssFeed/. Do not name the main set after the package or give it a generic name, such as Sets/SitePackage/, Sets/MyExtension/, or Sets/MySet/.

..  code-block:: typoscript
    :caption: EXT:my_sitepackage/Configuration/Sets/Main/setup.typoscript
Copied!

A TSconfig file that TYPO3 does not load on its own, such as a static file that an extension registers, goes below Configuration/TsConfig/, for example EXT:my_sitepackage/Configuration/TsConfig/User/editor.tsconfig. Write the directory name in CamelCase, like Configuration/TypoScript/. 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/site-package and t3docs/site-package-data, the repository TYPO3-Documentation/site_package, and my_site_package, the site package that the site package tutorial builds. A real extension keeps the names of its sets as well, such as Sets/Sitemap/ 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:

UpdateShorthandCode.diff
 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;
Copied!