A little example how to handle custom dates with jbake, using groovy MarkupTemplateEngine, to generate a valid sitemap and atom feed.
Show the world you updated a post
Lets say you wrote a blog post a while ago, maybe September 2016, but you want to update a detail you have missed.
Introduce a new Property
So you open your post update it and add a new jbake Property to your header.
:jbake-updated: 26.04.2020 (1)
:jbake-type: post
:jbake-status: published
1 | A Property called updated with a date String dd.MM.yyyy |
Use the property to render the date
Extend your template to show when the post was updated.
import java.text.SimpleDateFormat
div(class:"row"){
div(class:"small-12 middle-12 large-12 columns"){
article(class:"wrap"){
header{
div(class:"row"){
div(class:"small-3 medium-1 large-1 columns"){
include template: 'bricks/date.tpl'
}
div(class:"small-9 medium-11 large-11 columns"){
include template: 'bricks/post-title.tpl'
}
}
div(class:'row') {
div(class:"small-offset-3 medium-offset-1 large-offset-1 small-6 medium-6 large-6 columns") {
model.put('tagList',post.tags)
include template: 'bricks/tags.tpl'
}
div(class:"small-3 medium-3 large-3 columns text-right") {
if( post.updated ){ (1)
strong('Updated: ')
yield post.updated
}
}
}
hr()
}
div(class:"row"){
div(class:"columns"){
yieldUnescaped post.body
}
}
}
}
}
1 | Render updated property only if set in the post |
Add format Strings to your configuration
As you want to render the date in different formats I recommend to add the format strings to your configuration.
That way you can reuse them in different templates.
jbake{
version = "2.5.1"
asciidoctorjVersion = "1.5.4.1"
configuration['blog.title'] = "calmdevelopment"
configuration['blog.description'] = "'A personal Blog. Mostly about tech stuff. groovy, gradle, asciidoctor, jbake and other interesting stuff that crosses my path...'"
configuration['db.store'] = "local"
configuration['db.path']= "build/cache"
configuration['site.host'] = config.server.url
configuration['render.tags'] = true
configuration['site.contextPath'] = config.server.contextPath
configuration['foundation.version'] = foundationVersion
configuration['twitter.user'] = "@knarfancho"
configuration['asciidoctor.option.requires'] = "asciidoctor-diagram"
configuration['asciidoctor.attributes'] = [
"sourceDir=${projectDir}",
"imagesdir=${config.server.contextPath}img",
"imagesoutdir=${bake.input}/assets/img",
"source-highlighter=highlight.js",
"icons=font"
]
configuration['feed.timestamp'] = "yyyy-MM-dd\'T\'HH:mm:ss\'Z\'" (1)
configuration['sitemap.format'] = 'yyyy-MM-dd' (2)
configuration['updated.format'] = "dd.MM.yyyy" (3)
}
1 | A date format for atom feeds |
2 | A date format for the sitemap |
3 | The date format I’m using for the updated property |
Update sitemap template
Change the sitemap template to use the updated
property to set the last modification date of your post.
import java.text.SimpleDateFormat (1)
xmlDeclaration()
urlset( xmlns:'http://www.sitemaps.org/schemas/sitemap/0.9'){
published_content.each {content ->
url {
Date dateUpdated (2)
if ( content.updated ) { (3)
dateUpdated = new SimpleDateFormat(config.updated_format).parse(content.updated) (4)
}
loc("${config.site_host}${config.site_contextPath}${content.uri}")
lastmod("${dateUpdated?dateUpdated.format(config.sitemap_format):content.date.format(config.sitemap_format)}") (5)
}
}
}
1 | import SimpleDateFormat to format and parse a date string |
2 | declare a Date variable |
3 | try to convert the date string if the updated property is set |
4 | parse the updated date string and format with updated.format from configuration |
5 | ternary condition to use dateUpdated or the post date to format with sitemap.format from configuration |
Update feed template
Now do the same for the feed template.
import java.text.SimpleDateFormat (1)
yieldUnescaped "<?xml version='1.0' encoding='UTF-8'?>"
newLine()
feed(xmlns:"http://www.w3.org/2005/Atom"){
title("${config.blog_title}")
newLine()
link(href:"${config.site_host}${config.site_contextPath}")
newLine()
link(rel:"self", type:"application/atom+xml", href:"${config.site_host}${config.site_contextPath}${config.feed_file}")
newLine()
subtitle("${config.blog_subtitle?:""}")
newLine()
updated("${published_date.format(config.feed_format)}")
newLine()
id("tag:${config.feed_id},${published_date.format('yyyy:MM')}")
newLine()
published_posts.each {post ->
entry{
title("${post.title}")
newLine()
author{
name("${post.author}")
}
newLine()
link(href:"${config.site_host}${config.site_contextPath}${post.uri}")
newLine()
Date dateUpdated (2)
if ( post.updated ) { (3)
dateUpdated = new SimpleDateFormat(config.updated_format).parse(post.updated) (4)
}
updated("${dateUpdated?dateUpdated.format(config.feed_format):post.date.format(config.feed_format)}") (5)
newLine()
id("${config.site_host}${config.site_contextPath}${post.uri}")
newLine()
post.tags.each { tag ->
category(term:"${tag}")
newLine()
}
content(type:"html") {
yield post.body
}
}
newLine()
}
}
1 | import SimpleDateFormat to format and parse a date string |
2 | declare a Date variable |
3 | try to convert the date string if the updated property is set |
4 | parse the updated date string and format with updated.format from configuration |
5 | ternary condition to use dateUpdated or the post date to format with feed.format from configuration |
That’s it!