Neos CMS introduction at the Liiptalk on the 27th of september 2016, record available https://www.youtube.com/watch?v=J6q5Hk7Dr4k
View Slide
building a CMS forambitious editors
history
born underthe TYPO3 umbrella
goals
foundation
FLOWfull stack PHP framework
yet an other framework
convention overconfiguration
security framework
privilegeTargets:'TYPO3\Flow\Security\Authorization\Privilege\Method\MethodPrivilege':'Acme.MyPackage:RestrictedController.customerAction':matcher: 'method(Acme\MyPackage\Controller\RestrictedController->customerAction())''Acme.MyPackage:RestrictedController.adminAction':matcher: 'method(Acme\MyPackage\Controller\RestrictedController->(admin|drop)Action())’'Acme.MyPackage:editOwnPost':matcher: ‘method(Acme\MyPackage\Controller\PostController->editAction(post.owner == current.userService.currentUser))'
roles:'Acme.MyPackage:Customer':privileges:-privilegeTarget: 'Acme.MyPackage:RestrictedController.customerAction'permission: GRANT-privilegeTarget: 'Acme.MyPackage:RestrictedController.adminAction'permission: GRANT-privilegeTarget: 'Acme.MyPackage:RestrictedController.editOwnPost'permission: GRANT'Acme.MyPackage:Customer':privileges:-privilegeTarget: 'Acme.MyPackage:RestrictedController.customerAction'permission: GRANT'Acme.MyPackage:PrivilegedCustomer':parentRoles: ['Acme.MyPackage:Customer']privileges:-privilegeTarget: 'Acme.MyPackage:RestrictedController.editOwnPost'permission: GRANT
security CLI helpers
$ ./flow security:showunprotectedactionsTYPO3\Neos\Controller\Backend\ContentControllerinitializeUploadAssetActioninitializeCreateImageVariantActionTYPO3\Neos\Controller\LoginControllerinitializeIndexActionTYPO3\Neos\Controller\Service\WorkspacesControllerinitializeUpdateActionTtree\CloudButler\Controller\JobControllerinitializeRegisterAction
AOP
help with singleresponsibility principle
danger zone
We compile your code
Powerful Reflection API
@Flow\CompileStatic
/*** Returns a map of action method names and their parameters.** @param \TYPO3\Flow\Object\ObjectManagerInterface $objectManager* @return array Array of method parameters by action name* @Flow\CompileStatic*/static public function getActionMethodParameters($objectManager) {$reflectionService = $objectManager->get('TYPO3\Flow\Reflection\ReflectionService');$className = get_called_class();$methodParameters = $reflectionService->getMethodParameters($className,get_class_methods($className));foreach ($methodParameters as $parameterName => $parameterInfo) {...}return $methodParameters;}
NEOS is just a package
NEOS Content Repository
where content lives
yaml configuration
'My.Package:SpecialHeadline':superTypes:'TYPO3.Neos:Content': trueui:label: 'Special Headline'group: 'general'properties:headline:type: 'string'defaultValue: 'My Headline Default'ui:inlineEditable: truevalidation:'TYPO3.Neos/Validation/StringLengthValidator':minimum: 1maximum: 255
inspired by PHPCR
editing content
editor experience
workspace
content dimensions
contents livesin multiple contexts
WYSIFTW
developer
don’t hide features
create values
flexible content structure
modern rendering stack
fusion
prototype(Vendor:Staff) < prototype(TYPO3.Neos:Content) {templatePath = ‘resource://Vendor.Site/Private/Templates/ElementName.html'headline = ${q(node).property('headline')}subheadline = ${q(node).property('subheadline')}text = ${q(node).property('text')}image = ${q(node).property('image')}}
prototype(Vendor:Staff) < prototype(TYPO3.Neos:Content) {templatePath = ‘resource://Vendor.Site/Private/Templates/ElementName.html'headline = ${q(node).property('headline')}subheadline = ${q(node).property('subheadline')}text = ${q(node).property('text')}image = ${q(node).property(‘image’)}staffIdentifier = ${q(node).property(‘staffIdentifier’)}[email protected] = ${ErpApi.getStaffDetails(value)}}
prototype(Vendor:YourTwoColumns) {prototype(Vendor:Staff) {templatePath = ‘resource://Vendor.Site/Private/Templates/Compact.html'}}prototype(Vendor:StaffDirectory.Document) {prototype(Vendor:Staff) {templatePath = ‘resource://Vendor.Site/Private/Templates/Square.html'staffPageLink = ${q(node).property(‘staffIdentifier’)}[email protected] = ${ErpApi.getStaffUri(value)}}}
prototype(Vendor:StaffListing) < prototype(Flowpack.Listable:Listable) {@context.limit = 10collection = ${q(site).find('[instanceof Vendor:Staff]’).get()}itemRenderer = ‘Vendor:StaffListingItem'}prototype(Vendor:StaffListingItem) < prototype(Vendor:Staff) {templatePath = ‘resource://Vendor.Site/Private/Templates/ListingItem.html'}
cache on steroid
prototype(Vendor:StaffListingItem) {@cache {mode = 'cached'maximumLifetime = '86400'entryIdentifier {node = ${node}}entryTags {1 = ${'Node_' + documentNode.identifier}}}}
much much moreopen to organize a workshop to buildsomething on top of NEOS
from the lab
CQRSfor the content repository
touch points
neos.io
[email protected] - @ttreeagency - github.com/ttreeagencytt ttreedigital beans