jkleiss
(Jürgen Kleiß)
November 22, 2016, 4:17pm
#1
Hey guys!
I created a blog package which has a BlogPostList-Plugin for listing blog posts on a page.
Now i have problems with rendering the single blog posts.
I have the correct blog posts in the blogPost variable and then i want to render them as a Collection. In the template i render the Collection path to display every single blog post. But that doesn’t work. Can someone help me and tell me my mistakes.
My fusion code:
prototype(DigitalpunktCom.Neos.Blog:BlogPostList) < prototype(TYPO3.Neos:Content) {
templatePath = 'resource://DigitalpunktCom.Neos.Blog/Private/Templates/NodeTypes/BlogPostList.html'
sectionName = 'BlogPostList'
node = ${node}
@context.blogFolderNode = ${q(node).property('blogFolderNode')}
blogFolderNode = ${blogFolderNode}
@context.allCategories = ${q(node).property('categories') ? q(node).property('categories') : NULL}
@context.allTags = ${q(node).property('tags') ? q(node).property('tags') : NULL}
blogLimit = ${q(node).property('blogLimit')}
blogPosts = ${q(blogFolderNode).is('[instanceof DigitalpunktCom.Neos.Blog:BlogFolder]') ? q(blogFolderNode).find('[instanceof DigitalpunktCom.Neos.Blog:BlogPostsFolder]').children('[instanceof DigitalpunktCom.Neos.Blog:BlogPost]') : NULL}
blogPosts.@process.filterBlogPostsByCategories = ${ value.filterBlogPostsByCategories(allCategories) }
blogPosts.@process.filterBlogPostsByTags = ${ value.filterBlogPostsByTags(allTags) }
@context.blogPosts = ${this.blogPosts}
blogPostItemRenderer = TYPO3.TypoScript:Collection {
collection = ${blogPosts}
itemRenderer = DigitalpunktCom.Neos.Bootstrap:BlogPostListItem
itemName = 'blogPost'
}
@cache {
mode = 'uncached'
context {
1 = 'node'
2 = 'documentNode'
3 = 'site'
}
}
}
prototype(DigitalpunktCom.Neos.Bootstrap:BlogPostListItem) < prototype(TYPO3.TypoScript:Template) {
templatePath = 'resource://DigitalpunktCom.Neos.Blog/Private/Templates/NodeTypes/BlogPostList.html'
sectionName = 'BlogPostListItem'
blogPost = ${blogPost}
}
My template:
{namespace blog=DigitalpunktCom\Neos\Blog\ViewHelpers}
{namespace neos=TYPO3\Neos\ViewHelpers}
{namespace typo3cr=TYPO3\TYPO3CR\ViewHelpers}
{namespace ts=TYPO3\TypoScript\ViewHelpers}
<f:section name="BlogPostList">
<div class="blog-post-list">
<f:if condition="{blogPosts}">
<f:then>
<ul class="posts">
<ts:render path="blogPostItemRenderer"/>
</ul>
</f:then>
<f:else>
<p>Error no blog posts!</p>
</f:else>
</f:if>
</div>
</f:section>
<f:section name="BlogPostListItem">
<li class="post">
<div class="blog-title">
<h2>
<neos:link.node node="{blogPost}">{blogPost.properties.title}</neos:link.node>
<f:if condition="{blogPost.removed}"> (removed)</f:if>
</h2>
</div>
<p class="content">
<blog:teaser node="{blogPost}"/>
<neos:link.node node="{blogPost}" class="read-more">read more</neos:link.node>
</p>
</li>
</f:section>
I think it has something to do with collection = ${blogPosts} which is empty. But if i do a for each in the main template i get the correct number of “test” strings
<f:for each="{blogPosts}" as="blogPost">
<h1> test</h1>
</f:for>
hd77
(Christian Schwahn)
November 22, 2016, 4:24pm
#2
I think you could try TYPO3.Neos:ContentCase, i did the same with a carousel element:
prototype(My.Package:Carousel) < prototype(TYPO3.Neos:Content) {
templatePath = ‘resource://My.Package/Private/Templates/NodeTypes/Carousel.html’
carouselContent = TYPO3.TypoScript:Collection {
collection = ${q(node).children(’[instanceof TYPO3.Neos:ContentCollection]’).children()}
maximumLevels = 1
itemRenderer = My.Package:CarouselItem
itemName = ‘carouselItem’
}
carouselItemArray = ${q(node).children(‘carouselItems’).children()}
}
prototype(My.Package:CarouselItem) < prototype(TYPO3.Neos:Content) {
templatePath = 'resource://My.Package/Private/Templates/NodeTypes/CarouselItem.html’
itemContent = TYPO3.TypoScript:Collection {
collection = ${q(carouselItem)}
itemName = 'node’
itemRenderer = TYPO3.Neos:ContentCase
}
}
jkleiss
(Jürgen Kleiß)
November 22, 2016, 4:56pm
#3
My problem is that i don’t get any blog posts at with collection = ${blogPosts}
dfeyer
(Dominique Feyer)
November 22, 2016, 9:50pm
#4
Try to replace q(blogFolderNode) by q(this.blogFolderNode) and you don’t need to push blogFolderNode in the context
blogFolderNode = ${q(node).property('blogFolderNode')}
...
blogPosts = ${q(this.blogFolderNode).is('[instanceof DigitalpunktCom.Neos.Blog:BlogFolder]') ? q(this.blogFolderNode).find('[instanceof DigitalpunktCom.Neos.Blog:BlogPostsFolder]').children('[instanceof DigitalpunktCom.Neos.Blog:BlogPost]') : NULL}
jkleiss
(Jürgen Kleiß)
November 23, 2016, 1:20pm
#5
I solved it with the help of the Shel.Blog Package
But i don’t really understand why my solution wasn’t working.
@dfeyer i already tried it that way, but the result was the same
Here my working code:
prototype(DigitalpunktCom.Neos.Blog:BlogPostList) < prototype(DigitalpunktCom.Neos.Bootstrap:Content) {
templatePath = 'resource://DigitalpunktCom.Neos.Blog/Private/Templates/NodeTypes/BlogPostList.html'
sectionName = 'BlogPostList'
node = ${node}
@context.blogFolderNode = ${q(node).property('blogFolderNode')}
blogFolderNode = ${blogFolderNode}
@context.allCategories = ${q(node).property('categories') ? q(node).property('categories') : NULL}
@context.allTags = ${q(node).property('tags') ? q(node).property('tags') : NULL}
blogLimit = ${q(node).property('blogLimit')}
blogPosts = ${q(blogFolderNode).is('[instanceof DigitalpunktCom.Neos.Blog:BlogFolder]') ? q(blogFolderNode).find('[instanceof DigitalpunktCom.Neos.Blog:BlogPostsFolder]').children('[instanceof DigitalpunktCom.Neos.Blog:BlogPost]') : NULL}
blogPosts.@process.filterBlogPostsByCategories = ${ value.filterBlogPostsByCategories(allCategories) }
blogPosts.@process.filterBlogPostsByTags = ${ value.filterBlogPostsByTags(allTags) }
#blogPosts.@process.sort = ${ value.sort('publicationDate','DESC') }
#blogPosts.@process.slice = ${ Array.slice(value, 0, this.blogLimit) }
@context.blogPosts = ${this.blogPosts}
blogPostItemRenderer = TYPO3.TypoScript:Collection {
collection = ${blogPosts}
itemRenderer = DigitalpunktCom.Neos.Bootstrap:BlogPostListItem
itemName = 'node'
}
@cache {
mode = 'uncached'
context {
1 = 'node'
2 = 'documentNode'
3 = 'site'
}
}
}
prototype(DigitalpunktCom.Neos.Bootstrap:BlogPostListItem) < prototype(DigitalpunktCom.Neos.Bootstrap:Content) {
templatePath = 'resource://DigitalpunktCom.Neos.Blog/Private/Templates/NodeTypes/BlogPostList.html'
sectionName = 'BlogPostListItem'
image = ${q(node).property('image')}
description = ${q(node).property('description')}
createDate = ${q(node).property('_creationDateTime')}
prototype(DigitalpunktCom.Neos.Bootstrap:Image) {
maximumWidth = 500
maximumHeight = 500
}
}
The template:
{namespace blog=DigitalpunktCom\Neos\Blog\ViewHelpers}
{namespace neos=TYPO3\Neos\ViewHelpers}
{namespace typo3cr=TYPO3\TYPO3CR\ViewHelpers}
{namespace ts=TYPO3\TypoScript\ViewHelpers}
{namespace media=TYPO3\Media\ViewHelpers}
<f:section name="BlogPostList">
<div class="blog-post-list">
<f:if condition="{blogPosts}">
<f:then>
<div class="row posts">
<f:for each="{blogPosts}" as="blogPost">
<ts:render path="blogPostItemRenderer.itemRenderer" context="{node: blogPost}"/>
</f:for>
</div>
</f:then>
<f:else>
<p>Error no blog posts!</p>
</f:else>
</f:if>
</div>
</f:section>
<f:section name="BlogPostListItem">
<div class="col-sm-4 post">
<div class="blog-create-date">
<f:translate id="blogPostList.createdOn" package="DigitalpunktCom.Neos.Blog" source="Main">Created on</f:translate>
{createDate -> f:format.date(format:'D j. M Y')}
</div>
<f:if condition="{image}">
<div class="blog-image">
<figure class="image-alignment-center full-width">
<media:image asset="{image}" alt="{imageAlternativeText}" title="{imageTitle}" width="{width}"
maximumWidth="{maximumWidth}" height="{height}" maximumHeight="{maximumHeight}"
allowUpScaling="{allowUpScaling}" allowCropping="{allowCropping}" />
</figure>
</div>
</f:if>
<div class="blog-title headline underscored-left">
<h2>
<neos:link.node node="{node}">{node.properties.title}</neos:link.node>
<f:if condition="{node.removed}"> (removed)</f:if>
</h2>
</div>
<div class="blog-content">
<p>{description}</p>
</div>
<div class="blog-more">
<neos:link.node node="{node}" class="read-more"><f:translate id="blogPostList.readMore" package="DigitalpunktCom.Neos.Blog" source="Main">read more</f:translate></neos:link.node>
</div>
</div>
</f:section>
mficzel
(Martin Ficzel)
November 24, 2016, 1:46pm
#6
The first thing i see is that this is a strange use of blogPostItemRenderer
I would use it more like this,
in fluid
<f:if condition="{blogPosts}">
<f:then>
<ul class="posts">
<f:for each="{blogPosts}" as="blogPost">
<ts:render path="blogPostItemRenderer" context="{blogPost:blogPost}" />
<f:for>
</ul>
</f:then>
<f:else>
<p>Error no blog posts!</p>
</f:else>
</f:if>
in fusion/ts2
blogPostItemRenderer = DigitalpunktCom.Neos.Bootstrap:BlogPostListItem
For debugging you can try this before using the template again
prototype(DigitalpunktCom.Neos.Bootstrap:BlogPostListItem) < prototype(TYPO3.TypoScript:Value) {
value = TYPO3.TypoScript:Debug {
blogPost = ${blogPost}
}
}
jkleiss
(Jürgen Kleiß)
November 30, 2016, 9:03pm
#7
Thank you guys for your help!
I reworked my package. Now the solution looks like that (i removed some code, so that the post is not that long):
prototype(DigitalpunktCom.Neos.Blog:BlogPostList) < prototype(TYPO3.Neos:Content) {
` templatePath = 'resource://DigitalpunktCom.Neos.Blog/Private/Templates/NodeTypes/BlogPostList.html'
sectionName = 'BlogPostList'
@context.blogPosts = ${this.blogPosts}
blogPostRenderer = TYPO3.TypoScript:Collection {
collection = ${blogPosts}
itemRenderer = DigitalpunktCom.Neos.Blog:BlogPostRenderer
itemName = 'node'
}`
}
prototype(DigitalpunktCom.Neos.Blog:BlogPostRenderer) < prototype(TYPO3.TypoScript:Template) {
templatePath = 'resource://DigitalpunktCom.Neos.Blog/Private/Templates/NodeTypes/BlogPostRenderer.html'
sectionName = 'BlogPost'
title = ${q(node).property('title')}
}
And the template for the BlogPostList nodeType
<f:section name="BlogPostList">
<div class="blog-post-list">
<ts:render path="blogPostRenderer"/>
</div>
</f:section>
And the template for the BlogPostRenderer prototype
<f:section name="BlogPost">
<div class="blog-post">
<div class="blog-post-title">
<h2>
{title}
</h2>
</div>
</div>
</f:section>