Thu 16 Feb 2017 — Mon 22 Jan 2018


We're using this at the Centre for Sustainable Energy (CSE) for the Thermos website.

TYPO3 is a content management system (CMS) written in PHP.

It has its own sub-language called TypoScript embedded in it. This language configures a website by putting values into a PHP array.

In other words, it's a horrendous nightmare.

There is plenty of documentation, but it is not all up to date, and it is usually unclear which thing is the current blessed path.

Getting Help

There are two main ways to get help. You can go on StackOverflow and tag things with TYPO3. This is encouraged.

Alternatively, there is a forum:

Using TYPO3


Users go in groups.

Admin users can access everything, regardless of group. They can effectively run arbitrary PHP.

Page permissions are a bit like Unix file system permissions.

Frontend and Backend

These terms don't mean what they would in normal web development. In TYPO3, the frontend is the actual website and the backend is the authoring interface for the CMS.

Useful backend terms:

modules list
select a module from the list on the left of the screen
navigation frame
usually displays the page hierarchy (depending on which module you have selected)
content area
make your changes to the currently selected page or database record


Go to the backend, use the Page module.

You can look at what you've done in the View module.

List Module

This is for mass editing. Things in this view correspond to records, which are rows in the database


The workspaces feature lets you edit things without changing the live website.

You can create these using new record inside the List Module.


By default, URLs look like The RealURL extension can turn these into more sensible URLs.

It's a bit flaky though.


Localization is probably the main selling point of TYPO3.

There is an interface in the backend, and a built-in language menu that you can put on a page.

When a person chooses a language from the language menu, it turns into ?L=<language-id> query string parameters. You then have to add some TypoScript to actually set the language based on that variable.

You can use the RealURL extension to turn the query string parameters into clearer URLs that look like .e.g. /en/my-page.html.

Simple instructions
Someone's guide
Full docs


  • HTML

    Start by making a web page as normal.

    Marks look like this, they have no spaces, and shouldn't go inside comments:


    Things get substituted into them.

    Subparts are things inside a pair of marks. In this case, the marks can be inside comments.

  • Using it

    We create a template, and set it on our root page. It is then inherited.

    Then we write some TypoScript to use it:

    page = PAGE { // Create page object
        includeCSS.base = fileadmin/my_template/style.css
        10 = TEMPLATE { // Set first content object as template
            workOnSubpart = DOCUMENT // What our content is templating over
            template = FILE { // Set template object's template to a file
                file = fileadmin/my_template/index.html // Set file object's file to a filename
            subparts {
                SUBPART_NAME = thing
            marks {
                MARK_NAME = TEXT {
                    value = my text
  • Menus

    We need a HMENU object

    nav = HMENU {
        wrap = <ul>|</ul> // Tell our menu what its outer object is
        special = list { // We'll provide a list of pages
            value = 2, 3 // List of pages by id
        entryLevel = 0 // Start from the top
        // Inside our HMENU, we need some items like TMENU and GMENU
        // Nav depth 1: text menu
        1 = TMENU {
            NO = 1 # Activate normal link styles
            NO {
                // If we had multiple levels, we'd need wrapItemAndSub instead
                allWrap = <li>|</li>
            ACT = 1 # Activate active link styles
            ACT {
                allWrap = <li class="current">|</li>
  • Content
    CONTENTRIGHT < styles.content.getRight



Backup wiki page

Zip up the following directories:

  • fileadmin
  • typo3conf
  • uploads

Use mysqldump on the database.

Take the outputs of these two commands, zip them together, and you're done.

The downside of this approach is that typo3conf contains a lot of extensions, that it would be better to just re-download.

However, it seems to work fine.


  • fileadmin

    Files uploaded by the content authors. Can be accessed using the File Module.

  • typo3

    This is a symlink to the actual typo3 PHP code.

    The .tar.gz package you download has all the composer stuff (which fetches libraries) already done.

    • typo3/sysext

      System extensions.

      Each extension folder can contain:

      • extemconf.php describes the extension programatically
      • extlocalconf.php sets up hooks and configuration
      • exttables.sql create table statements which should look like MySQL dump outputs
      • exttables.php sets up backend display of database tables
      • Classes
      • Configuration
      • Documentation (in restructured text format)
      • Resources
      • Tests
      • hooks
      • composer.json
      • exticon.svg
  • typo3conf

    Configuration. All configuration in typo3 is state: it's done after installation.

    • typo3conf/ext

      Downloaded extensions live here.

  • typo3temp

    Cache. You can delete this at any point and TYPO3 will make it again.

  • uploads

    Uploads directory. Not sure how this differs from fileadmin?

Developing Extensions for TYPO3


Inside TYPO3

Design to be extensible. Much of the core functionality is built as System extensions.

Extbase is an MVC framework based on Flow.

Fluid is a type of templating engine / view part of MVC.

So we use Extbase/Fluid to make our templates.

Command Controller

The Extbase command controller lets extensions register command line tasks.

Users can then schedule them with the interface.

File Abstraction

File Abstraction Layer

Files are grouped by storage. A storage can be a file system, some other server somewhere, or whatever. They are described in sysfilestorage.

There is a sysfile table in the database which records files we know about and some metadata about them.

There is also a filemetadata extension which adds more metadata like licensing.

The sysfilereference table connects a file to a content element. I don't know what this means. There is a matching \TYPO3\CMS\Core\Resource\FileReference class.

sysfileprocessedfile contains temporary generated files.

sysfilecollection lets you group files.

A Driver lets us do operations on a file.


DatabaseConnection class.

You can get the singleton from $GLOBALS['TYPO3DB'].

  • Schema

    In $GLOBALS['TCA'] there is a database table description.

    See TCA Reference.


    • validation
    • join fields
    • backend vs layout (hmm?)

    An extension controls this using a file <ext_name>/Configuration/TCA/<database-table-name>.php. This file is automatically found, and its result cached.

    Each element of $GLOBALS['TCA'] is a table name => associative array mapping.

    Each table has the following:

    • ctrl (mandatory) is general stuff about the table
    • interface backend display properties
    • columns
    • types maps columns to an editing form
    • palettes a list of special fields which don't get in the main editing form.
  • Schema Upgrades

    There are tools in the backend for checking that the schema is up to date, and migrating it if not.

Fluid Templates

  • Content templates

    You need to create a backend layout which goes with your content template.

    Then you write a typoscript template for your root page.

    Then you assign that backend layout to your pages.

  • Layout

    This is the part you share between all your pages.


    You can reference a layout from within your content template.

  • Partials

    These are small pieces like headers.

    I could just include them in my layout instead.

TypoScript Syntax

It has object-property dot notation (like a JS object).

Parsed line-by-line.

Looks like: path operator value e.g. myObject.myProperty = value 2.

Paths are defined with A-Za-z0-9-_.

Escape dots with \. (don't do this).

Values are trimmed for whitespace.


  • = assigns
  • := modifies using a function of the previous value
  • { lets you assign lots of properties at once in a tree structure (like = { in Javascript).
  • ( lets you assign a multiline value (e.g. some HTML).
  • < copies one path to another. The whole value is copied, there are no references involved here.
  • =< assigns a reference.
  • > deletes.


A line only applies when the condition above it is met.

A condition holds true until it is superceded.

[GLOBAL] means no conditions.

[ELSE] means, did the previous condition fail.

[END] means, cancel the previous condition.

You can combine conditions with || or &&.

We can create our own custom conditions by extending the parser.


These are relative to the page.

They can have a condition property.


These are /* comment comment comment */ multiline comments. They must be the first non-whitespace thing in a line.

Page TypoScript

Customizes things based on where you are in the page hierarchy

User TypoScript

Customizes things based on who you are.