Marketing departement has special requirements for a special formatted blog list, where the images are rendered in a column and the text in another column.
I was thinking about a user-macro that extracts the first image of every blog-posts for the output of the first column.
I know that I can get the body of an page/blog with $page.getBodyAsString().
But I have no idea how to extract a piece of markup from the body.
Any ideas?
Thanks a lot!
philipp
Community moderators have prevented the ability to post new answers.
Looks like this should work:
## @param Width:title=Image width|type=int|desc=If set, displays image with desired size. Otherwise, the value on the original page is used. #set ( $blogs = $pageManager.getBlogPosts($space, true) ) #set ( $count = 0 ) #set ( $width = "" ) #set ( $width = $paramWidth ) <ul class="user-macro-list-blog-posts" #foreach($blog in $blogs) #if ($count < 10) <li><a href="${req.contextPath}${blog.urlPath}">${blog.title}</a></li> #set ( $contentBody = $blog.getBodyAsString() ) #if ( $contentBody.contains("<ac:image") ) #set ( $firstIndex = $contentBody.indexOf("<ac:image") ) #set ( $middleIndex = $contentBody.indexOf("><ri:attachment") ) #set ( $endIndex = $contentBody.indexOf("</ac:image>") + 11 ) #set ( $imagePart = $contentBody.substring($firstIndex, $endIndex) ) #set ( $middleIndex = $imagePart.indexOf("<ri:attachment") ) #set ( $pageRefIndex = $imagePart.indexOf(" />") ) #if ( !$imagePart.contains("content-title") ) #set ( $continueIndex = $pageRefIndex + 3 ) #set ( $imagePart = $imagePart.substring(0, $pageRefIndex) + '><ri:blog-post ri:content-title="' + $blog.title + '" ri:posting-day="' + $blog.datePath + '" /></ri:attachment>' + $imagePart.substring($continueIndex) ) #end #if ( $width == "" ) #set ( $imageString = $imagePart ) #else #set ( $imageString = '<ac:image ac:thumbnail="true" ac:width="' + $width + '">' + $imagePart.substring($middleIndex) ) #end #end $imageString ##<p class='$imagePart.substring($middleIndex)'></p> ##$blog.getBodyAsString() #set ( $count = $count + 1 ) #end #end <ul>
If it works, please mark it as an answer
What would be the nicest way to reverse the order of the posts? I forgot that normally the newest posts are on top of a news-list.... Thanks!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I tried reversing the order, but that doesn't necessarily mean that the newest is on top; it seems like it doesn't sort by date, so I'll have to come up with another way to return the newest post, especially because the Velocity used by Confluence doesn't include the SortTool...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I found a solution: getRecentlyAddedBlogPosts() returns a list with the correct order. {code} #set ( $blogs = $pageManager.getRecentlyAddedBlogPosts(20, "news") ) {code} whereas `news`is the space-key.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Stephen!
I just discovered that the loop does of course noch take into consideration any permissions set on the single blog-posts.
Do you have an idea how the check for permissions before outputting the single lines of blog-posts?
Thanks
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks Stephen!
I extended your concept in order to extract also the excerpt.
In that way the layout of the Blogpost can be absolutely free and the macro is listing always the first image and the excerpt.
Very nice result!
Philipp
This is the final user-macro.
## Custom List of Blog Items listing the first image and the excerpt ## @param Width:title=Image width|type=int|desc=If set, displays image with desired size. Otherwise, the value on the original page is used. #set ( $blogs = $pageManager.getBlogPosts($space, true) ) #set ( $count = 0 ) #set ( $width = "" ) #set ( $width = $paramWidth ) <div class="custom-blog-list" #foreach($blog in $blogs) #if ($count < 10) #set ($crDate=$action.dateFormatter.format($blog.getCreationDate())) <div class="custom-blog-list-item"> <a class="blogHeading" href="${req.contextPath}${blog.urlPath}">${blog.title} </a> <p class="custom-blog-list-meta">$userAccessor.getUser("${blog.CreatorName}").getFullName(), $crDate </p> #set ( $contentBody = $blog.getBodyAsString() ) #if ( $contentBody.contains("<ac:rich-text-body") ) #set ( $firstEIndex = $contentBody.indexOf("<ac:rich-text-body>") ) #set ( $endEIndex = $contentBody.indexOf("</ac:rich-text-body>") + 20 ) #set ( $ExcerptPart = $contentBody.substring($firstEIndex, $endEIndex) ) #end #if ( $contentBody.contains("<ac:image") ) #set ( $firstIndex = $contentBody.indexOf("<ac:image") ) #set ( $middleIndex = $contentBody.indexOf("><ri:attachment") ) #set ( $endIndex = $contentBody.indexOf("</ac:image>") + 11 ) #set ( $imagePart = $contentBody.substring($firstIndex, $endIndex) ) #set ( $middleIndex = $imagePart.indexOf("<ri:attachment") ) #set ( $pageRefIndex = $imagePart.indexOf(" />") ) #if ( !$imagePart.contains("content-title") ) #set ( $continueIndex = $pageRefIndex + 3 ) #set ( $imagePart = $imagePart.substring(0, $pageRefIndex) + '><ri:blog-post ri:content-title="' + $blog.title + '" ri:posting-day="' + $blog.datePath + '" /></ri:attachment>' + $imagePart.substring($continueIndex) ) #end #if ( $width == "" ) #set ( $imageString = $imagePart ) #else #set ( $imageString = '<ac:image ac:thumbnail="true" ac:width="' + $width + '" >' + $imagePart.substring($middleIndex) ) #end #end <div class="custom-blog-list-image"> $imageString </div> <div class="custom-blog-list-text"> $ExcerptPart </div> <p style="float:none;break:before;clear:both;display:block;"> &nbsp;</p> #set ( $count = $count + 1 ) #end </div> ## /custom-blog-list-item #end </div>
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Stephen,
Wow this looks great. Tank you
So this is my macro for looping through blog items. But I get "unknown attachment" instead of the image.
## @param Width:title=Image width|type=int|desc=If set, displays image with desired size. Otherwise, the value on the original page is used. #set ( $blogs = $pageManager.getBlogPosts($space, true) ) #set ( $count = 0 ) #set ( $width = "" ) #set ( $width = $paramWidth ) <ul class="user-macro-list-blog-posts" #foreach($blog in $blogs) #if ($count < 10) <li><a href="${req.contextPath}${blog.urlPath}">${blog.title}</a></li> #set ( $contentBody = $blog.getBodyAsString() ) ## $contentBody #if ( $contentBody.contains("<ac:image") ) #set ( $firstIndex = $contentBody.indexOf("<ac:image") ) #set ( $middleIndex = $contentBody.indexOf("><ri:attachment") ) #set ( $endIndex = $contentBody.indexOf("</ac:image>") + 11 ) #set ( $imagePart = $contentBody.substring($firstIndex, $endIndex) ) #set ( $middleIndex = $imagePart.indexOf("><ri:attachment") ) #if ( $width == "" ) #set ( $imageString = $imagePart ) #else #set ( $imageString = '<ac:image ac:thumbnail="true" ac:width="' + $width + '"' + $imagePart.substring($middleIndex) ) #end #end $imageString <p class='$imagePart.substring($middleIndex)'></p> ##$blog.getBodyAsString() #set ( $count = $count + 1 ) #end #end <ul>
After some fiddling I found out that images from blog-posts need some special syntax.
Looks that the simple way does not work with blog posts.
<ac:image><ri:attachment ri:filename="image2015-8-27 11:10:27.png" /></ac:image>
But this does work:
<ac:image ac:height="250"> <ri:attachment ri:filename="image2015-8-27 11:10:27.png"> <ri:blog-post ri:content-title="Visit of the Slovenian delegation" ri:posting-day="2015/08/20"/> </ri:attachment> </ac:image>
So I would need to inject the ri:blog-post part into the ri:attachment part.
Any help would be really appreciated!!!
Tanks
philipp
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Philipp,
This should work, or you should be able to adapt it for your needs:
## @param Width:title=Image width|type=int|desc=If set, displays image with desired size. Otherwise, the value on the original page is used. #set ( $width = "" ) #set ( $width = $paramWidth ) #set ( $contentBody = $content.getBodyAsString() ) #if ( $contentBody.contains("<ac:image") ) #set ( $firstIndex = $contentBody.indexOf("<ac:image") ) #set ( $endIndex = $contentBody.indexOf("</ac:image>") + 11 ) #set ( $imagePart = $contentBody.substring($firstIndex, $endIndex) ) #set ( $middleIndex = $imagePart.indexOf("><ri:attachment") ) #if ( $width == "" ) #set ( $imageString = $imagePart ) #else #set ( $imageString = '<ac:image ac:thumbnail="true" ac:width="' + $width + '"' + $imagePart.substring($middleIndex) ) #end #end $imageString
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Community moderators have prevented the ability to post new answers.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.