by Sebastian Kurfürst
for T3BOARD12
Usage: Slides are nested into other slides, press ▼ to go to the nested slides.
Great, you were able to navigate to here!
There is no further slide below, so press ► to go to the next top-level slide.
Hint: at the bottom-right you see the navigation controls.
Extensible Rendering Configuration
What's the underlying programming paradigm?
Declarative vs Imparative
Procedural vs Object Oriented
not side-effect free: REGISTER
however, very pragmatic
What do we expect from the new TypoScript?
sometimes, we want to output static text
sometimes, rendering of content
sometimes, one node is rendered multiple times
► m:n relation nodes -- TypoScript objects
stdWrap generalized: processors
match the hierarchical nature of nodes
Rendering single content elements
► side-effect-free language
► compact addressing needed
Node Path: /sites/flow3org/home[TYPO3.TYPO3:Page]
TypoScript Path: page/body
also use it outside TYPO3, just with FLOW3
TypoScript v4: extensibility, stdWrap
Fluid: HTML Templating
JavaScript: Prototype-based inheritance
jQuery: selecting nodes, fluent interface
CSS: set-based API; Selector Syntax
XPath: Traversal Operations
page = TYPO3.TYPO3:Page
page.body.templatePath = 'resource://TYPO3.Flow3Org/Private/Templates/Page/Default.html'
page.body.sectionName = 'body'
page.body.parts {
mainMenu = TYPO3.TYPO3:MenuRenderer
mainMenu.templatePath = 'resource://TYPO3.Flow3Org/Private/Templates/TypoScriptObjects/MainMenu.html'
mainMenu.entryLevel = 1
mainMenu.maximumLevels = 2
subMenu = TYPO3.TYPO3:MenuRenderer
subMenu.templatePath = 'resource://TYPO3.Flow3Org/Private/Templates/TypoScriptObjects/SubMenu.html'
subMenu.entryLevel = 2
subMenu.maximumLevels = 3
}
page.head {
stylesheets {
fromTemplate = TYPO3.TypoScript:FluidRenderer
fromTemplate.templatePath = 'resource://TYPO3.Flow3Org/Private/Templates/Page/Default.html'
fromTemplate.sectionName = 'stylesheets'
}
javascripts {
fromTemplate = TYPO3.TypoScript:FluidRenderer
fromTemplate.templatePath = 'resource://TYPO3.Flow3Org/Private/Templates/Page/Default.html'
fromTemplate.sectionName = 'javascripts'
}
}
// Static Title
page.body.title = 'My Static Title'
// make it dynamic:
page.body.title = ${context.attr('title')}
Each TypoScript object operates on a context (a TYPO3CR Node).
${...}
is an EEL Expression
(it's like jQuery)
page.body.sections.main = TYPO3.TYPO3:Section
page.body.sections.main.nodePath = 'main'
Make the headline texts static
prototype(TYPO3.TYPO3:Text).headline = 'Static Headline'
Wrap the headline texts might be more useful :-)
prototype(TYPO3.TYPO3:Text).headline << 1.wrap(prefix: '-', suffix: '-')
Make the headline texts inside all three-column elements static
prototype(TYPO3.Flow3Org:ThreeColumn).prototype(TYPO3.TYPO3:Text).headline = 'Static Headline'
Make the headline texts inside the left column of all three-column elements static
prototype(TYPO3.Flow3Org:ThreeColumn).left.prototype(TYPO3.TYPO3:Text).headline = 'Static Headline'
That's of course also possible with processors :-)
prototype(TYPO3.Flow3Org:TwoColumn) < prototype(TYPO3.TypoScript:FluidRenderer)
prototype(TYPO3.Flow3Org:TwoColumn) {
templatePath = 'resource://TYPO3.Flow3Org/Private/Templates/TypoScriptObjects/TwoColumn.html'
left = TYPO3.TYPO3:Section
left.nodePath = 'left'
right = TYPO3.TYPO3:Section
right.nodePath = 'right'
}
OK, then let's dive into the internals :-)
TypoScript is a hierarchical, prototype-based, object oriented, declarative, side-effect free language.
// Setting implementation class name
prototype(TYPO3.TypoScript:CollectionRenderer).implementationClassName = 'TYPO3\\TypoScript\\TypoScriptObjects\\CollectionRenderer'
prototype(TYPO3.TypoScript:Case).implementationClassName = 'TYPO3\\TypoScript\\TypoScriptObjects\\CaseTsObject'
prototype(TYPO3.TypoScript:CollectionRenderer) {
collection = ${context.children()}
itemRenderer = TYPO3.TypoScript:Case
}
// a CASE TypoScript object maps a TYPO3CR Node to a certain TypoScript object based on a condition.
// It has a list of MATCHERS which are evaluated in-order
// Each matcher consists of a "condition", which is in most cases an EEL expression,
// and a TypoScript type which shall be used if the condition is TRUE.
// Catch-all condition for the default case
prototype(TYPO3.TypoScript:Case).matchers.999999999999 {
condition = ${true}
type = ${context.attr('_contentType')}
}
is a JavaScript-like syntax for calling methods and functions
${foo.bar} // Traversal
${foo.bar()} // Method call
${foo.bar().baz()} // Method call
${foo.bar("arg1", true, 42)} // Method call with arguments
// true, false, numbers are all valid eel expressions
${12+18.5} // you can calculate as well
${foo == bar} // ... and compare
${foo.bar(12+18.5, foo == bar)} // and of course also use it inside arguments
${[foo, bar]} // Array Literal
${{foo: bar, baz:test}} // Object Literal
is like jQuery for FLOW3
# output text property of node
${context.property('text')}
# find all parent nodes
${context.parents()}
# find all parent nodes and add the current node to the selected set
${context.parents().add(context)}
isAtLeastOnThirdLevel = ${context.parents().count() >= 3}
${context.children('left').first()}
${context.children().filter('left').first()}
isOfTypeText = ${context.is('[instanceof TYPO3.TYPO3:Text]')} # returns boolean value
Lazy Evaluation
Easily possible now :)
OK, then I have some :-)
"static TypoScript" / Embedding in TYPO3
Do we still need Variables or constants?
How can we implement the reference operator?
How to use TypoScript for hierarchical configuration? Configure two plugin instances on the same page differently
Should there be TS objects for accessing repositories?
what about Conditions?(problematic for Out of Band-rendering; influences caching)
Slides based on reveal.js