Best practices for building Neos and Flow packages
Florian Weiss
@WeissheitenWien
Weissheiten
SkillDisplay
Dmitri Pisarev
@dimaip
SFI.ru
Billy Mitchell
Sebastian
Kurfürst
Increase your package score
Be aware that this could put a ghost in the machine
One size fits all
Ready to use extensions
can be twisted to fit
"Building bricks" instead of "ready to use" extensions
Embrace the power of TS2
Step 1: Site Package with TS2 Basics and NodeTypes
Step 2: Custom TypoScript Objects, Eel Helpers, etc
YES / NO
The pain grows with complexity.
Hard to "become all things to all people" [1Cor 9:22]
Works great when clear intent is defined.
Dangerous without thinking!
Extract single- responsibility pieces of code -> ship them as seperate packages
prototype(Neos.NeosIo:PostArchive) < prototype(Flowpack.Listable:Listable) {
@context.listClass = 'u-resetList siteWrapper siteWrapper--small'
@context.itemClass = 'u-mb1/1'
@context.sortProperty = '_index'
@context.sortOrder = 'ASC'
@context.itemsPerPage = 15
collection = ${q(site).find('[instanceof Neos.NeosIo:Post]').get()}
@cache {
mode = 'cached'
entryIdentifier {
node = ${node}
}
entryTags {
1 = ${'NodeType_Neos.NeosIo:Post'}
2 = ${'Node_' + node.identifier}
}
maximumLifetime = 3600
}
}
"Provide a package with all NodeTypes that I consider useful"
"Provide a package with all NodeTypes related to Zurb Foundation"
vs
<f:for each="{0:1, 1:2, 2:3, 3:4}" as="foo">
{foo}
</f:for>
myCollection = TYPO3.TypoScript:Collection {
collection = ${[1, 2, 3]}
itemName = 'element'
itemRenderer = My.Package:IntegerRenderer
}
Avoid putting too much
logic into Fluid
vs
Avoid many levels
of inheritance
'My.Package:SpecialPage':
superTypes:
'TYPO3.Neos.NodeTypes:Page':
properties:
metaDescription:
type: 'string'
defaultValue: 'My important text'
'My.Package:ExtraSpecialPage':
superTypes:
'My.Package:SpecialPage'
properties:
twitterCardType:
type: 'string'
defaultValue: 'Extra important text'
Use mixins over inheritance chaining
'TYPO3.Neos.Seo:SeoMetaTagsMixin':
abstract: TRUE
properties:
metaDescription:
type: string
Spoiler:
It's a great and
state of the art
DDD PHP framework
include: resource://TYPO3.TypoScript/Private/TypoScript/Root.ts2
include: resource://TYPO3.Neos/Private/TypoScript/Root.ts2
include: resource://Flowpack.Listable/Private/TypoScript/Root.ts2
listable.basicListing = Flowpack.Listable:Listable {
itemRenderer = ${node.properties.title}
collection = ${collection}
}
$newNode1 = $this->getMockBuilder(NodeInterface::class)->getMock();
$newNode1->method('getProperties')->willReturn(array('title' => 'Hello world'));
$newNode2 = $this->getMockBuilder(NodeInterface::class)->getMock();
$newNode2->method('getProperties')->willReturn(array('title' => 'Another hello world!'));
$view = $this->buildView();
$view->setTypoScriptPath('listable/basicListing');
$view->assign('collection', array($newNode1, $newNode2));
$this->assertXmlStringEqualsXmlString(
'<ul>
<li>Hello world</li>
<li>Another hello world!</li>
</ul>',
$view->render()
);
php composer.phar init
Vendor.Context.Purpose
Example
Flowpack.Neos.Frontendlogin
Flow Coding Guidelines
(one page!)
if (1 === 1)
echo "hello";
else
echo "not hello";
if (1 === 1) {
echo "hello";
} else {
echo "not hello";
}
Strg + Shift + Alt + L
Provide a readme
Don't ignore GitHub responses
Try to maintain your package
Namespaces
Flowpack / Community