Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Long-Pager with Neos – so simple even your clients can do it

Long-Pager with Neos – so simple even your clients can do it

Sometimes simple pages are not enough. Occasionally you need sections on a certain page. For example if you want to collect content (e. g. products, news, etc) and divide it into sections. In this slides you will see how to generate this «Page Sections», how to handle links (to pages and/or anchor), integrate SEO and see what is the benefit for you, your clients and their costumers.

Jon Uhlmann

April 22, 2016
Tweet

Other Decks in Technology

Transcript

  1. › CREATING WEBSITES SINCE 1997 › WORKING @ DOTPULSE AG,

    
 an web-agency based in Zurich, Switzerland › FELL IN LOVE WITH NEOS TWO YEARS AGO ABOUT ME Jonathan Uhlmann
  2. › We create USER-CENTRED websites and applications with FOCUS ON

    SEO, built with NEOS › In the last few years, we create about 20 NEOS & FLOW websites or applications ABOUT DOTPULSE
  3. BACK IN 1997 <frameset rows="80px,*,10%"> <frame src="header.html" name="header" /> <frameset

    cols="200px,*"> <frame src="navigation.html" name="navi" /> <frame src="maincontent.html" name="main" /> </frameset> <frame src="footer.html" name="footer" /> </frameset>
  4. STAY SIMPLE, Not all the time. But the chance is

    much higher. CLIENTS SMILE BECAUSE IT’LL MAKE YOUR
  5. STRUCTURED CONTENT <section> <div class="slide">Slide 01</div> <div class="slide">Slide 02</div> <div

    class="slide">Slide 03</div> </section> <section> <button>Call to Action</button> </section> <section> <form>Contact</form> </section> <section> <article>Blog</article> </section> <nav>Navigation</nav> <header>Logo</header> NAVIGATION SLIDER CALL TO ACTION BLOG CONTACT HEADER
  6. # Challenge are internal links You just can’t just go

    to a new site You have also to handle scroll links
  7. Third approach Long-Pager are stored in books Books contains Page-Sections

    Page-Sections can contain Bookmarks Sidenote: Think about the icons. Icons helps the editor a lot! Multiple Books can be rendered as slider, accordions or something else. There’s no limit.
  8. BENEFIT FOR THE USER No dead links. 
 At least

    the internal ones. It just works and feel right.
  9. BENEFIT FOR THE CLIENT Internal links to sections 
 are

    simple to handle Want to move whole sections?
 No problem, man! Multiple editors can 
 better work together
  10. BENEFIT FOR YOU More control over HTML structure Cleaner node

    structure No faults in nesting objects It’s much easier to update 
 design & structure D.R.Y. Code: You don’t have to 
 repeat yourself all the time
  11. With prototypes you can 
 better nest all the sections

    The use of Settings.yaml makes the code easy configurable and reusable STAY D.R.Y.
  12. PARENTSUNTIL Instance of Page First Instance of Section Section Section

    Section With the FlowQuery Operation parentsUntil you get the ancestors of each element in the current set of matched elements, up to but not including the element matched by the selector/filter
  13. SET UP YOUR SETTINGS.YAML Dotpulse: PageSection: page: '[instanceof TYPO3.Neos.NodeTypes:Page]' section:

    '[instanceof Dotpulse.PageSection:Document]' mixin: '[instanceof Dotpulse.PageSection:DocumentMixin]' headerHeight: FALSE ContentCollection: entryClass: FALSE subEntryClass: FALSE linkProperty: link idSeperator: '--' titleSeperator: ' / ' linkSeperator: first: '' default: '/'
  14. GET ALL KINDS OF COLLECTED PROPERTIES prototype(PageSection:CollectionProperty) < prototype(TypoScript:Collection){ @context.configuration

    = ${Configuration.setting('Dotpulse.PageSection')} property = 'uriPathSegment' nodeObject = ${node} seperator = TypoScript:RawArray { first = ${configuration.linkSeperator.first} default = ${configuration.linkSeperator.default} } @context.property = ${this.property} @context.seperator = ${this.seperator} array = ${q(this.nodeObject).add(q(this.nodeObject).parentsUntil(configuration.page)).get()} collection = ${Array.reverse(this.array)} iterationName = 'iterator' itemName = 'element' itemRenderer = ${(iterator.isFirst ? seperator.first : seperator.default) + q(element).property(property)} }
  15. GET THE ATTRIBUTES attributes { data-url = PageSection:CollectionProperty data-title =

    PageSection:CollectionProperty { property = 'title' seperator { first = '' default = ${configuration.titleSeperator} } } id = PageSection:CollectionProperty { seperator { first = '' default = ${configuration.idSeperator} } } } idSeperator: '--' titleSeperator: ' / ' Settings.yaml
  16. GET THE CONTENT TO THE PAGE prototype(PageSection:PageSection) < prototype(TypoScript:Template) {

    @context.configuration = ${Configuration.setting('Dotpulse.PageSection')} templatePath = 'resource://Dotpulse.PageSection/Private/Templates/ ↩︎
 TypoScriptObjects/PageSection.html' menu = PageSection:Menu content = TypoScript:Collection { collection = ${q(node).children(configuration.mixin)} itemName = 'node' iterationName = 'nodeIterator' itemRenderer = PageSection:Collection } }
  17. LINKHANDLING If the link is an instance 
 of a

    section, you need to scroll. If the parent is different from the actual page, you need to jump to another site.
 And scroll. Perhaps.
  18. GET THE NODE URI prototype(PageSection:NodeUri) < prototype(Neos:NodeUri){ @context.nodeObject = ${node}

    @context.configuration = ${Configuration.setting('Dotpulse.PageSection')} node = ${q(nodeObject).is(configuration.page) ? nodeObject : ↩︎ q(nodeObject).parents(configuration.page).get(0)} section = PageSection:CollectionProperty } With section you can add a hash to the URI
  19. GET THE NODE URI With all that you get for

    example (real world example) /en_us/insurance/health/product-and-pricing-management#pricing-process/persons /content_dimensions/path/to/site#path/to/section The scroll / jump handling can be easily achieved with Javascript
  20. REDIRECT FRONTEND REQUESTS // LIVE // If there is a

    PageSection in the Rootline root.pageSectionFrontendRedirect { condition = ${documentNode.context.live && q(node).children().parents().filter(Configuration.setting(‹Dotpulse.PageSection.section›)).is()} renderPath = '/pageSectionFrontendRedirect' } pageSectionFrontendRedirect = PageSection:Redirect prototype(PageSection:Redirect) < prototype(TypoScript:Http.Message) { httpResponseHead { statusCode = 301 headers.Location = PageSection:NodeUri } }
  21. SEO, GOOGLE AND SITEMAPS Unfortunately, Google can’t handle sections in

    sitemaps Google render you site with Javascript, so you can’t use tricks with javascript redirects. But as soon as Google can handle sections, you have a great base for sitemaps with sections.
  22. BUT HOW DO I CREATE A SITEMAP? composer require jonnitto/sitemap

    Set the Settings (in your site Settings.yaml), 
 include the route and you are ready to go! The code will be merged into the 
 official sitemap. (TYPO3.Neos.Seo)
  23. THE SITEMAP You can set which types of pages are

    included 
 to get hashed links. In that way you can provide 
 a sitemap who links to ajax pages. The property metaRobotsNoindex get observed. You can also set which kind of pages 
 (like Shortcuts) are getting ignored.
  24. OPEN SOURCE. The Package Dotpulse.PageSection will be published on github.

    Beside that we will release a complete demo of a small website Just drop a line to [email protected] and we’ll keep you informed.