blog.Resource
April 2, 2014

Something Neos V - Building on a solid foundation

Category: Florian Weiss, TYPO3

By: Florian Weiss

Creating a package and your own content element types

Your responsive framework

Foundation Yeti

You did setup your site - basic content elements are

working and your main template is based on your favourite templating engine.

So far so good - but many of those templating engines provide specific classes or other markups to provide some additional functionality or layout.
My personal layouting framework of choice is foundation (http://foundation.zurb.com/), which provides a nice and easy to setup grid layout in combination with a bunch of neat extras.

Sidenote: I'm going to skip the setup part for Foundation because I believe most of you reading these lines already have their favorite way of including their framework (npm, bower, "hard" inclusion with download, own directory structure, scss/less compiled client or server side, you know the drill) and will assume you already completed these steps. (If you want to see an example setup, shoot me a line - perhaps I can team up with someone from #typo3-neos to provide some insight on possible options)

Déjà-vu ain't what it used to be - Documentation and this article

Following one of the tunes of Skyclad (you should defenitely check this band out), you could ask why there's an article on the topic of content creation, when we already have: The Integrator Guide.

While some parts may seem familiar - this article focuses on creating a whole package that will host the content elements you need for your responsive framework in an easy to follow step-by-step guide.

Divide and conquer - Keeping it neat and tidy

Packages Foundation Neos"What are we waiting for! Let's edit this nodetypes.yaml of my presence and go go go!" I hear you say - and that is what I also did "for a quick" test the first time - nevertheless after integrating your first content element you might realise you'll need this content element on a different deployment of Neos too.

That's what packages are for.
To create a new package connect to the shell and run the command

./flow package:create Your.Home.Framework

The name can be anything you want – I personally went for Weissheiten.Neos.Foundation (Company.CMS.Framework) – for easier reference I’ll just continue with this markup for an Orbit Slider content element fitting for the Foundation framework.

Congratulations – you should find your newly created package in the ./Packages/Application folder. If you want you can edit the description in composer.json – after creation you’ll find a placeholder for it there. Ready – Set? Let’s fill the details.

Filename: NodeTypes.yaml
Use: Defines the NodeTypes you want to use when including this package on your site

Weissheiten.Neos.Foundation:Orbit':
   superTypes: ['TYPO3.Neos:Content']
   childNodes:
      main:
         type: 'TYPO3.Neos:ContentCollection'
   ui:
      label: 'Orbit Slider'
      icon: 'icon-expand'
      group: 'foundation'
      inlineEditable: TRUE

Supertype lets us inherit the properties of the parent type so we don’t have to define those details again – our node type is based on this “super” NodeType. (You can find this Nodetype in Packages/Application/TYPO3.Neos/Configuration/NodeTypes.yaml) The childNodes part automatically creates a ContentCollection when our element is used, which can later be filled by the editors. (For a slider we would prefer that only images can be included there, at the time this article is written there is no way to limit the editors to specific content types inside a node however – for the moment we’ll have to trust in their ability to remember that a slider consists of multiple images) Regarding ui we should note that we use the group “foundation” – this sets the group in which the content element should be put when the “New content element” wizard is presented – this group doesn’t exist yet – we should therefore add it.

Filename: Settings.yaml
Use: We define the new content element group for the “New content element” wizard inside this file by extending the configuration
Looking at Packages/Application/TYPO3.Neos/Configuration/Settings.yaml we can find the groups already well known to us inside there: general, structure and plugins We will add a new group now by defining our own Settings.yaml in our package and therefore extending the existing entries. (We don’t alter the one found in the TYPO3.Neos package, because we would have to do this over and over with multiple sites using our package)

TYPO3:
    Neos:
      nodeTypes:
         groups:
            foundation:
               position: 300
               label: 'Foundation'

Filename: Resources/TypoScripts/Library/Prototype/Orbit.ts2
Use: Generate a prototype for the new content element with TypoScript
UPDATE: You don't need the @cache part when using Neos 1.1 and up - see comments

prototype(Weissheiten.Neos.Foundation:Orbit) {
   @cache {
      mode = 'uncached'
      context {
         0 = 'node'
         1 = 'documentNode'
      }
   }
   sectionName = 'main' 
   items = TYPO3.Neos:ContentCollection {
      nodePath = 'main'
tagName = 'ul'
attributes.data-orbit = 'data-orbit'
      iterationName = 'iteration'
   }
   prototype(TYPO3.Neos.NodeTypes:Image) {
      templatePath = 'resource://Weissheiten.Neos.Foundation/Private/Templates/NodeTypes/Orbit.html'
      sectionName = 'item'
      iteration = ${carouselItemsIteration}
   }
}

The @cache part sets our content element as uncached, main matches the according section in the html template (see below). We define the needed atrribute - because we want to have a result like

<ul class="weissheiten-neos-foundation-orbit" data-orbit="data-orbit">

Our items object consists of the contents of the content collection (the editors will hopefully remember only to use images), as iterationName we just use the term ‘iteration’.
tagName changes the used tag that wraps the content collection from <div> to <ul>
Furthermore we set a new prototype for "all Images inside an orbit element" with the according template.

Let's define a template now to complete the creation of the new content element:

Filename: Resources/Private/Templates/NodeTypes/Orbit.html
Use: Template for the orbit element

{namespace neos=TYPO3\Neos\ViewHelpers}
{namespace media=TYPO3\Media\ViewHelpers}
<f:section name="main">
{items -> f:format.raw()}
</f:section>


<f:section name="item">
<li{attributes -> f:format.raw()}>
<f:if condition="{image}">
<f:then>
<media:image image="{image}" alt="{alternativeText}" title="{title}" maximumWidth="{maximumWidth}" maximumHeight="{maximumHeight}" />
</f:then>
<f:else>
<img src="{f:uri.resource(package: 'TYPO3.Neos', path: 'Images/dummy-image.png')}" title="Dummy image" alt="Dummy image" />
</f:else>
</f:if>
<f:if condition="{hasCaption}">
<div class="orbit-caption">
{neos:contentElement.editable(property: 'caption')}
</div>
</f:if>
</li>
</f:section>

First we define the main section that gets rendered with the according attributes (we did set "data-orbit") - for our item we need an unordered list.
The item section defines the rendering of each single image and its according caption (only rendered when the condition that it actually has a caption is met)
If no image is set we instruct NEOS to render a placeholder (dummy-image.png) from the Images path.

We built this city on rock and... foundation

Time to put our new content element to use - which should prove to be pretty easy now.
First make sure that your package is installed

./flow package:list

If your package is listed under "Active packages" (which it should be - if it isn't check http://docs.typo3.org/flow/TYPO3FlowDocumentation/TheDefinitiveGuide/PartIII/PackageManagement.html for a full set of commands)

Now we just have to include our package in our sites "Root.ts2" with the line

include: resource://Weissheiten.Neos.Foundation/Private/TypoScripts/Library/Prototype/Orbit.ts2

Other foundation elements and shoutouts

That's about it - if you need additional elements for the same responsive framework I recommend putting them into the same package and if you're even working with foundation yourself and did create additional content elements freel free to drop me a line via E-mail or Twitter - perhaps we can collaborate on putting a package together that's free and easy for everyone to use - inspire people to share!

Speaking of sharing - A big shoutout to Rens Admiraal of #typo3-neos, who did provide me with valuable insights and even a demo on the content element I presented in this article.
Additional thanks go to the friendly folks at #typo3-neos on IRC freenode.net - we look forward to seeing you - the reader - there.


comments

comment #1
Gravatar: Christopher Hlubek Christopher Hlubek April 9, 2014 14:13
Hi Florian,

thanks for the nice article!

I have one question though: why @cache.mode = 'uncached'? For static content elements this shouldn't be needed and the default 'embed' should just work.

comment #2
Gravatar: Florian Weiss Florian Weiss April 11, 2014 10:22
I checked back with Rens Admiraal on your question.
Prior to the release of T3Neos 1.1 you would have needed the line because Neos would not flush the cache if the template/ts would change. (quite annoying in development)

With the release of the new version you'll safely be able to leave this out. (thx to the fast response at #typo3-neos)

comment #3
Gravatar: Florian Weiss Florian Weiss April 15, 2014 17:28
I included a small fix in this article today. In the original version of the article the slider would refuse to work on certain configurations due to an extra div wrapping around the list items - changing the tagName of the content collection fixed this. (changes are already applied in the article)

Sorry, comments are closed for this post.