Creating a TYPO3 Neos plugin

Any Flow package can be used as a plugin with a little effort. This section will guide you through a simple example. First, we will create a really basic Flow package. Second, we’ll expose this Flow package as a Neos plugin.

Creating a Flow package

First we will create a very simple Flow package to use for integrating it as a plugin.


When developing sites the need for simple plugins will often arise. And those small plugins will be very site-specific most of the time. In these cases it makes sense to create the needed code inside the site package, instead of in a separate package.

For the sake of simplicity we will create a seperate package now.

If you do not have the Kickstart package installed, you must do this now:

cd /your/htdocs/Neos
php /path/to/composer.phar require typo3/kickstart \*

Now create a package with a model, so we have something to show in the plugin:

./flow kickstart:package Sarkosh.CdCollection
./flow kickstart:model Sarkosh.CdCollection Album title:string year:integer description:string rating:integer
./flow kickstart:repository Sarkosh.CdCollection Album

Then generate a migration to create the needed DB schema:

./flow doctrine:migrationgenerate
mkdir -p Packages/Application/Sarkosh.CdCollection/Migrations/Mysql
mv Data/DoctrineMigrations/Version<timestamp>.php Packages/Application/Sarkosh.CdCollection/Migrations/Mysql/
# check the generated migration
./flow doctrine:migrate

You should now have a package with a default controller and templates created.

In order to view them you can call the frontend like http://neos.demo/sarkosh.cdcollection, but you need to include the Flow default routes first (add them before the Neos routes):


  name: 'Flow'
  uriPattern: '<FlowSubroutes>'
    '@format': 'html'
      package: TYPO3.Flow

Now you can add some entries for your CD collection in the database:

INSERT INTO sarkosh_cdcollection_domain_model_album (
  persistence_object_identifier, title, year, description, rating
  uuid(), 'Jesus Christ Superstar', '1970',
  'Jesus Christ Superstar is a rock opera by Andrew Lloyd Webber, with lyrics by Tim Rice.',

(or using your database tool of choice) and adjust the templates so a list of CDs is shown. When you are done with that, you can make a plugin out of that.

As an optional step you can move the generated package from it’s default location Packages/Application/ to Packages/Plugins. This is purely a convention and at times it might be hard to tell an “application package” from a “plugin”, but it helps to keep things organized. Technically it has no relevance.

mkdir Packages/Plugins
mv Packages/Application/Sarkosh.CdCollection Packages/Plugins/Sarkosh.CdCollection

Converting a Flow Package Into a Neos Plugin

To activate a Flow package as a Neos plugin, you only need to provide two configuration blocks. First, you need to add a new node type for the plugin, such that the user can choose the plugin from the list of content elements:

Add the following to Configuration/NodeTypes.yaml of your package:

  superTypes: ['TYPO3.Neos:Plugin']
    label: 'CD Collection'
    group: 'plugins'

This will add a new entry labeled “CD Collection” to the “Plugins” group in the content element selector (existing groups are General, Structure and Plugins).

Second, the rendering of the plugin needs to be specified using TypoScript, so the following TypoScript needs to be added to your package.


prototype(Sarkosh.CdCollection:Plugin) < prototype(TYPO3.Neos:Plugin)
prototype(Sarkosh.CdCollection:Plugin) {
     package = 'Sarkosh.CdCollection'
     controller = 'Standard'
     action = 'index'

Finally tweak your site package’s Root.ts2 and include the newly created TypoScript file:

include: resource://Sarkosh.CdCollection/Private/TypoScripts/Library/Plugin.ts2

Now log in to your Neos backend (you must remove the Flow routes again), and you will be able to add your plugin just like any other content element.

Configuring a plugin to show specific actions on different pages

With the simple plugin you created above all of the actions of that plugin are executed on one specific page node. But sometimes you might want to break that up onto different pages. For this use case there is a node type called Plugin View. A plugin view is basically a view of a specific set of actions configured in your NodeTypes.yaml.

The steps to have one plugin which is rendered at multiple pages of your website is as follows:

  1. Create your plugin as usual; e.g. like in the above example.
  2. Insert your plugin at a specific page, just as you would do normally. This is later called the Master View of your plugin.
  3. You need to define the parts of your plugin you lateron want to have separated in a different page. This is done in the options.pluginViews setting inside NodeTypes.yaml (see below).
  4. Then, in Neos, insert a Plugin View instance on the other page where you want a part of the plugin to be rendered. In the inspector, you can then select the Plugin instance inside the Master View option, and afterwards choose the specific Plugin View you want to use.

You can update your Configuration/NodeTypes.yaml like this to configure which actions will be available for the Plugin View:

  superTypes: ['TYPO3.Neos:Plugin']
    label: 'CD Collection'
    group: 'plugins'
        label: 'Show Collection'
          'Sarkosh\CdCollection\Controller\CollectionController': ['show']
        label: 'Collection Overview'
          'Sarkosh\CdCollection\Controller\CollectionController': ['overview']

When you insert a plugin view for a node the links in both of this nodes get rewritten automatically to link to the view or plugin, depending on the action the link points to. Insert a “Plugin View” node in your page, and then, in the inspector, configure the “Master View” (the master plugin instance) and the “Plugin View”.

Fixing Plugin Output

If you check the HTML of a page that includes your plugin, you will clearly see that things are not as they should be. The plugin is included using it’s complete HTML, including head and body tags. This of course results in an invalid document.


The documentation is incomplete at this point. Please ask on in #typo3-neos for further details.