diff --git a/src/main/java/org/jbake/app/Filter.java b/src/main/java/org/jbake/app/Filter.java index 7a2c7dd5d..d1cbd321a 100644 --- a/src/main/java/org/jbake/app/Filter.java +++ b/src/main/java/org/jbake/app/Filter.java @@ -18,16 +18,16 @@ public class Filter { * @param posts The posts to filter * @return Just the published posts */ - public static List> getPublishedPosts(List> posts) { - List> publishedPosts = new ArrayList>(); - for (Map post : posts) { - if (post.get("status") != null) { - if (((String)post.get("status")).equalsIgnoreCase("published")) { - publishedPosts.add(post); + public static List> getPublishedContent(List> contentList) { + List> publishedContent = new ArrayList>(); + for (Map content : contentList) { + if (content.get("status") != null) { + if (((String)content.get("status")).equalsIgnoreCase("published")) { + publishedContent.add(content); } } } - return publishedPosts; + return publishedContent; } } diff --git a/src/main/java/org/jbake/app/Oven.java b/src/main/java/org/jbake/app/Oven.java index 4aee1a3ce..1a2025365 100644 --- a/src/main/java/org/jbake/app/Oven.java +++ b/src/main/java/org/jbake/app/Oven.java @@ -140,8 +140,9 @@ public void bake() throws Exception { } } - // only interested in published posts from here on - List> publishedPosts = Filter.getPublishedPosts(posts); + // only interested in published content from here on + List> publishedPosts = Filter.getPublishedContent(posts); + List> publishedPages = Filter.getPublishedContent(pages); // write index file if (config.getBoolean("render.index")) { @@ -153,6 +154,11 @@ public void bake() throws Exception { renderer.renderFeed(publishedPosts, config.getString("feed.file")); } + // write sitemap file + if (config.getBoolean("render.sitemap")) { + renderer.renderSitemap(publishedPages, publishedPosts, config.getString("sitemap.file")); + } + // write master archive file if (config.getBoolean("render.archive")) { renderer.renderArchive(publishedPosts, config.getString("archive.file")); diff --git a/src/main/java/org/jbake/app/Renderer.java b/src/main/java/org/jbake/app/Renderer.java index 9c5ea6288..21d0be634 100644 --- a/src/main/java/org/jbake/app/Renderer.java +++ b/src/main/java/org/jbake/app/Renderer.java @@ -176,8 +176,33 @@ public void renderFeed(List> posts, String feedFile) { System.out.println("failed!"); } } - - /** + + /** + * Render an XML sitemap file using the supplied content. + * + * @param pages The combined list of pages and posts to render + * + * @see About Sitemaps + * @see Sitemap protocol + */ + public void renderSitemap(List> pages, List> posts, String sitemapFile) { + File outputFile = new File(destination.getPath() + File.separator + sitemapFile); + System.out.print("Rendering sitemap [" + outputFile + "]... "); + + Map model = new HashMap(); + model.put("published_pages", pages); + model.put("published_posts", posts); + + try { + render(model, config.getString("template.sitemap.file"), outputFile); + System.out.println("done!"); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("failed!"); + } + } + + /** * Render an archive file using the supplied content. * * @param posts The content to render @@ -209,7 +234,7 @@ public void renderTags(Map>> tags, String tagPa Map model = new HashMap(); model.put("tag", tag); // TODO: sort posts here - List> posts = Filter.getPublishedPosts(tags.get(tag)); + List> posts = Filter.getPublishedContent(tags.get(tag)); model.put("tag_posts", posts); tag = tag.trim().replace(" ", "-"); diff --git a/src/main/resources/default.properties b/src/main/resources/default.properties index f29d0478d..d19df57ec 100644 --- a/src/main/resources/default.properties +++ b/src/main/resources/default.properties @@ -14,6 +14,8 @@ template.feed.file=feed.ftl template.archive.file=archive.ftl # filename of tag template file template.tag.file=tags.ftl +# filename of sitemap template file +template.sitemap.file=sitemap.ftl # folder that contains all content files content.folder=content # folder that contains all asset files @@ -33,6 +35,10 @@ feed.file=feed.xml render.archive=true # filename to use for archive file archive.file=archive.html +# render sitemap.xml file? +render.sitemap=true +# filename to use for sitemap file +sitemap.file=sitemap.xml # render tag files? render.tags=true # folder name to use for tag files @@ -51,4 +57,4 @@ asciidoctor.attributes=source-highlighter=prettify date.format=yyyy-MM-dd # comma delimited default markdown extensions; for available extensions: # http://www.decodified.com/pegdown/api/org/pegdown/Extensions.html -markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS \ No newline at end of file +markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS diff --git a/src/main/templates/base.zip b/src/main/templates/base.zip index 754ace88c..97474b851 100644 Binary files a/src/main/templates/base.zip and b/src/main/templates/base.zip differ diff --git a/src/test/java/org/jbake/app/RendererTest.java b/src/test/java/org/jbake/app/RendererTest.java index facc2d340..124932e7b 100644 --- a/src/test/java/org/jbake/app/RendererTest.java +++ b/src/test/java/org/jbake/app/RendererTest.java @@ -1,7 +1,17 @@ package org.jbake.app; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import org.junit.Assert; import org.junit.Before; @@ -149,7 +159,30 @@ public void renderFeed() throws Exception { Assert.assertTrue(foundFirstTitle); Assert.assertTrue(foundSecondTitle); } - + + @Test + public void renderSitemaps() throws Exception { + Crawler crawler = new Crawler(sourceFolder, config); + crawler.crawl(new File(sourceFolder.getPath()+File.separator+"content")); + Renderer renderer = new Renderer(sourceFolder, destinationFolder, templateFolder, config, crawler.getPosts(), crawler.getPages()); + renderer.renderSitemap(Filter.getPublishedContent(crawler.getPages()), Filter.getPublishedContent(crawler.getPosts()), config.getString("sitemap.file")); + File outputFile = new File(destinationFolder, config.getString("sitemap.file")); + Assert.assertTrue(outputFile.exists()); + + final String[] lines = FileUtils.readLines(outputFile).toArray(new String[0]); + + Assert.assertTrue(lines[0].trim().equals("")); + Assert.assertTrue(lines[1].trim().startsWith("")); + Assert.assertTrue(lines[3].trim().startsWith("")); + Assert.assertTrue(lines[3].trim().contains("about.html")); + Assert.assertTrue(lines[4].trim().startsWith("")); + + Assert.assertTrue(lines[lines.length - 2].trim().equals("")); + Assert.assertTrue(lines[lines.length - 1].trim().equals("")); + + } + @Test public void renderArchive() throws Exception { Crawler crawler = new Crawler(sourceFolder, config); diff --git a/src/test/resources/custom.properties b/src/test/resources/custom.properties index 05f87767b..d4f176b5b 100644 --- a/src/test/resources/custom.properties +++ b/src/test/resources/custom.properties @@ -11,4 +11,5 @@ archive.file=archive.html render.tags=false tag.path=tags test.property=testing123 -markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS \ No newline at end of file +markdown.extensions=HARDWRAPS,AUTOLINKS,FENCED_CODE_BLOCKS,DEFINITIONS +site.host=http://www.jbake.org \ No newline at end of file diff --git a/src/test/resources/templates/sitemap.ftl b/src/test/resources/templates/sitemap.ftl new file mode 100644 index 000000000..cf2b81639 --- /dev/null +++ b/src/test/resources/templates/sitemap.ftl @@ -0,0 +1,15 @@ + + +<#list published_pages as page> + + ${config.site_host}${page.uri} + ${page.date?string("yyyy-MM-dd")} + + +<#list published_posts as post> + + ${config.site_host}${post.uri} + ${post.date?string("yyyy-MM-dd")} + + + \ No newline at end of file