aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2019-04-27 04:22:56 +0200
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2019-04-28 22:09:39 +0200
commit792ac4ec66dd098109a88065420ef95c1a78624f (patch)
tree4cf068a60006b7691ca1e01ba4f110725e72631d
parent2793a94367e7b163ff3738619a2a764f1c6645b7 (diff)
downloadblogc-792ac4ec66dd098109a88065420ef95c1a78624f.tar.gz
blogc-792ac4ec66dd098109a88065420ef95c1a78624f.tar.bz2
blogc-792ac4ec66dd098109a88065420ef95c1a78624f.zip
make: support posts autoloading
-rw-r--r--man/blogcfile.5.ronn9
-rw-r--r--src/blogc-make/ctx.c108
-rw-r--r--src/blogc-make/ctx.h3
-rw-r--r--src/blogc-make/rules.c48
-rw-r--r--src/blogc-make/settings.c1
-rwxr-xr-xtests/blogc-make/check_blogc_make.sh.in248
6 files changed, 393 insertions, 24 deletions
diff --git a/man/blogcfile.5.ronn b/man/blogcfile.5.ronn
index fd77e1c..b63bcf7 100644
--- a/man/blogcfile.5.ronn
+++ b/man/blogcfile.5.ronn
@@ -110,6 +110,12 @@ however these rules can be customized with the following settings, from the
The prefix of the posts file names. It is used for both content and output
directories, and is relative to `content_dir` and the output directory.
+ * `posts_autoload` (default: `false`):
+ If true, blogc-make(1) will guess the source files from the posts directory
+ (`content_dir`/`post_prefix`) and ignore anything listed in `[posts]` section.
+ This setting automatically enable `posts_sort`, as there's no manually-provided
+ order of posts to follow.
+
* `posts_per_page` (default: `10`):
Number of posts per page in the pagination pages. If negative, all the posts
are included. If `0`, no post listing pages are generated. Also, if negative or
@@ -141,6 +147,9 @@ is `foo`.
All the posts are relative to the `post_prefix` in the root of the website.
+This section can be omitted if using the `posts_autoload` setting, as it will
+guess the posts from the directory.
+
### Pages listing
The `[pages]` section is a listing of the pages that will be included in the
diff --git a/src/blogc-make/ctx.c b/src/blogc-make/ctx.c
index 423b334..d7a503d 100644
--- a/src/blogc-make/ctx.c
+++ b/src/blogc-make/ctx.c
@@ -13,6 +13,7 @@
#include <libgen.h>
#include <limits.h>
#include <time.h>
+#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
@@ -267,7 +268,11 @@ bm_ctx_new(bm_ctx_t *base, const char *settings_file, const char *argv0,
}
rv->posts_fctx = NULL;
- if (settings->posts != NULL) {
+ rv->posts_deleted = false;
+ if (bc_str_to_bool(bc_trie_lookup(settings->settings, "posts_autoload"))) {
+ bm_ctx_autoload_posts(rv);
+ }
+ else if (settings->posts != NULL) {
for (size_t i = 0; settings->posts[i] != NULL; i++) {
char *f = bm_generate_filename(content_dir, post_prefix,
settings->posts[i], source_ext);
@@ -306,7 +311,7 @@ bm_ctx_reload(bm_ctx_t **ctx)
if (*ctx == NULL || (*ctx)->settings_fctx == NULL)
return false;
- if (bm_filectx_changed((*ctx)->settings_fctx, NULL, NULL)) {
+ if ((*ctx)->posts_deleted || bm_filectx_changed((*ctx)->settings_fctx, NULL, NULL)) {
// reload everything! we could just reload settings_fctx, as this
// would force rebuilding everything, but we need to know new/deleted
// files
@@ -328,8 +333,13 @@ bm_ctx_reload(bm_ctx_t **ctx)
bm_filectx_reload((*ctx)->atom_template_fctx);
bm_filectx_reload((*ctx)->listing_entry_fctx);
- for (bc_slist_t *tmp = (*ctx)->posts_fctx; tmp != NULL; tmp = tmp->next)
- bm_filectx_reload((bm_filectx_t*) tmp->data);
+ if (bc_str_to_bool(bm_ctx_settings_lookup(*ctx, "posts_autoload"))) {
+ bm_ctx_autoload_posts(*ctx);
+ }
+ else {
+ for (bc_slist_t *tmp = (*ctx)->posts_fctx; tmp != NULL; tmp = tmp->next)
+ bm_filectx_reload((bm_filectx_t*) tmp->data);
+ }
for (bc_slist_t *tmp = (*ctx)->pages_fctx; tmp != NULL; tmp = tmp->next)
bm_filectx_reload((bm_filectx_t*) tmp->data);
@@ -342,6 +352,96 @@ bm_ctx_reload(bm_ctx_t **ctx)
void
+bm_ctx_autoload_posts(bm_ctx_t *ctx)
+{
+ if (ctx == NULL)
+ return;
+
+ const char *content_dir = bm_ctx_settings_lookup(ctx, "content_dir");
+ const char *post_prefix = bm_ctx_settings_lookup(ctx, "post_prefix");
+ const char *source_ext = bm_ctx_settings_lookup(ctx, "source_ext");
+
+ char *posts_dir = bm_generate_filename(content_dir, post_prefix, NULL, NULL);
+ char *abs_posts_dir = bc_strdup_printf("%s/%s", ctx->root_dir, posts_dir);
+ DIR *dir = opendir(abs_posts_dir);
+ if (dir == NULL) {
+ fprintf(stderr,
+ "blogc-make: warning: failed to open directory for posts autoload "
+ "(%s): %s\n", abs_posts_dir, strerror(errno));
+ free(posts_dir);
+ free(abs_posts_dir);
+ return;
+ }
+ free(abs_posts_dir);
+
+ // trick 0: avoid additional loops if we are not reloading
+ bool reloading = ctx->posts_fctx != NULL;
+
+ // trick 1: set all the post file contexts as unreadable, so we can detect
+ // which ones were deleted.
+ for (bc_slist_t *tmp = ctx->posts_fctx; tmp != NULL; tmp = tmp->next) {
+ bm_filectx_t *fc = tmp->data;
+ if (fc->readable) {
+ fc->readable = false;
+ }
+ }
+
+ struct dirent *e;
+ while (NULL != (e = readdir(dir))) {
+ if ((0 == strcmp(e->d_name, ".")) || (0 == strcmp(e->d_name, "..")))
+ continue;
+ if (!bc_str_ends_with(e->d_name, source_ext))
+ continue;
+ char *tmp = bc_strdup_printf("%s/%s", posts_dir, e->d_name);
+
+ // trick 2: if the file context exists in the index, just set it as
+ // readable
+ bm_filectx_t *fc = NULL;
+ if (reloading) {
+ for (bc_slist_t *t = ctx->posts_fctx; t != NULL; t = t->next) {
+ bm_filectx_t *fct = t->data;
+ if (0 == strcmp(fct->short_path, tmp)) {
+ fc = fct;
+ break;
+ }
+ }
+ }
+ if (fc != NULL) {
+ fc->readable = true;
+ bm_filectx_reload(fc);
+ }
+ else {
+ e->d_name[strlen(e->d_name) - strlen(source_ext)] = 0;
+ fc = bm_filectx_new(ctx, tmp, e->d_name, NULL);
+ ctx->posts_fctx = bc_slist_append(ctx->posts_fctx, fc);
+ }
+ free(tmp);
+ }
+
+ // trick 3: delete the unreadable file contexts
+ ctx->posts_deleted = false;
+ if (reloading) {
+ for (bc_slist_t *tmp = ctx->posts_fctx; tmp != NULL;) {
+ bm_filectx_t *fc = tmp->data;
+ if (!fc->readable) {
+ bc_slist_t *next = tmp->next;
+ ctx->posts_fctx = bc_slist_remove(ctx->posts_fctx, tmp,
+ (bc_free_func_t) bm_filectx_free);
+ tmp = next;
+ ctx->posts_deleted = true;
+ }
+ else {
+ tmp = tmp->next;
+ }
+ }
+ }
+
+ closedir(dir);
+ free(posts_dir);
+}
+
+
+void
bm_ctx_free_internal(bm_ctx_t *ctx)
{
if (ctx == NULL)
diff --git a/src/blogc-make/ctx.h b/src/blogc-make/ctx.h
index a66d51c..43284a5 100644
--- a/src/blogc-make/ctx.h
+++ b/src/blogc-make/ctx.h
@@ -63,8 +63,10 @@ typedef struct {
bm_filectx_t *listing_entry_fctx;
bc_slist_t *posts_fctx;
+ bool posts_deleted;
bc_slist_t *pages_fctx;
bc_slist_t *copy_fctx;
+
} bm_ctx_t;
bm_filectx_t* bm_filectx_new(bm_ctx_t *ctx, const char *filename, const char *slug,
@@ -76,6 +78,7 @@ void bm_filectx_free(bm_filectx_t *fctx);
bm_ctx_t* bm_ctx_new(bm_ctx_t *base, const char *settings_file,
const char *argv0, bc_error_t **err);
bool bm_ctx_reload(bm_ctx_t **ctx);
+void bm_ctx_autoload_posts(bm_ctx_t *ctx);
void bm_ctx_free_internal(bm_ctx_t *ctx);
void bm_ctx_free(bm_ctx_t *ctx);
const char* bm_ctx_settings_lookup(bm_ctx_t *ctx, const char *key);
diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c
index 96cf51d..f42b99a 100644
--- a/src/blogc-make/rules.c
+++ b/src/blogc-make/rules.c
@@ -32,7 +32,9 @@ posts_ordering(bm_ctx_t *ctx, bc_trie_t *variables, const char *variable)
const char *value = bm_ctx_settings_lookup_str(ctx, variable);
bool asc = 0 == strcasecmp(value, "asc");
- bool sort = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_sort"));
+ bool posts_autoload = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_autoload"));
+ bool posts_sort = bc_str_to_bool(bm_ctx_settings_lookup(ctx, "posts_sort"));
+ bool sort = posts_sort || posts_autoload;
if (sort) {
bc_trie_insert(variables, "FILTER_SORT", bc_strdup("1"));
@@ -75,7 +77,7 @@ posts_pagination_enabled(bm_ctx_t *ctx, const char *variable)
static bc_slist_t*
index_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "posts_per_page"))
@@ -97,7 +99,7 @@ index_outputlist(bm_ctx_t *ctx)
static int
index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -114,7 +116,8 @@ index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bm_filectx_t *fctx = l->data;
if (fctx == NULL)
continue;
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
@@ -135,7 +138,7 @@ index_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
atom_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "atom_posts_per_page"))
@@ -157,7 +160,7 @@ atom_outputlist(bm_ctx_t *ctx)
static int
atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -173,7 +176,8 @@ atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bm_filectx_t *fctx = l->data;
if (fctx == NULL)
continue;
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, NULL, ctx->atom_template_fctx,
@@ -194,7 +198,7 @@ atom_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
atom_tags_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "atom_posts_per_page"))
@@ -218,7 +222,7 @@ atom_tags_outputlist(bm_ctx_t *ctx)
static int
atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return 0;
int rv = 0;
@@ -239,7 +243,8 @@ atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bc_trie_insert(variables, "FILTER_TAG",
bc_strdup(ctx->settings->tags[i]));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx, NULL, NULL,
fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, NULL, ctx->atom_template_fctx,
@@ -260,7 +265,7 @@ atom_tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
pagination_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
// not using posts_pagination_enabled() here because we need to calculate
@@ -293,7 +298,7 @@ pagination_outputlist(bm_ctx_t *ctx)
static int
pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -315,7 +320,8 @@ pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
if (fctx == NULL)
continue;
bc_trie_insert(variables, "FILTER_PAGE", bc_strdup_printf("%zu", page));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
@@ -336,7 +342,7 @@ pagination_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
posts_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return NULL;
bc_slist_t *rv = NULL;
@@ -344,9 +350,10 @@ posts_outputlist(bm_ctx_t *ctx)
const char *post_prefix = bm_ctx_settings_lookup(ctx, "post_prefix");
const char *html_ext = bm_ctx_settings_lookup(ctx, "html_ext");
- for (size_t i = 0; ctx->settings->posts[i] != NULL; i++) {
+ for (bc_slist_t *l = ctx->posts_fctx; l != NULL; l = l->next) {
+ bm_filectx_t *fc = l->data;
char *f = bm_generate_filename(ctx->short_output_dir, post_prefix,
- ctx->settings->posts[i], html_ext);
+ fc->slug, html_ext);
rv = bc_slist_append(rv, bm_filectx_new(ctx, f, NULL, NULL));
free(f);
}
@@ -357,7 +364,7 @@ posts_outputlist(bm_ctx_t *ctx)
static int
posts_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL)
return 0;
int rv = 0;
@@ -403,7 +410,7 @@ posts_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
static bc_slist_t*
tags_outputlist(bm_ctx_t *ctx)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return NULL;
if (!posts_pagination_enabled(ctx, "posts_per_page"))
@@ -427,7 +434,7 @@ tags_outputlist(bm_ctx_t *ctx)
static int
tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
{
- if (ctx == NULL || ctx->settings->posts == NULL || ctx->settings->tags == NULL)
+ if (ctx == NULL || ctx->posts_fctx == NULL || ctx->settings->tags == NULL)
return 0;
int rv = 0;
@@ -449,7 +456,8 @@ tags_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
bc_trie_insert(variables, "FILTER_TAG",
bc_strdup(ctx->settings->tags[i]));
- if (bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
+ if (ctx->posts_deleted ||
+ bm_rule_need_rebuild(ctx->posts_fctx, ctx->settings_fctx,
ctx->listing_entry_fctx, ctx->main_template_fctx, fctx, false))
{
rv = bm_exec_blogc(ctx, variables, NULL, true, ctx->listing_entry_fctx,
diff --git a/src/blogc-make/settings.c b/src/blogc-make/settings.c
index be976e3..2f56d9c 100644
--- a/src/blogc-make/settings.c
+++ b/src/blogc-make/settings.c
@@ -28,6 +28,7 @@ static const struct default_settings_map {
{"main_template", "main.tmpl"},
{"source_ext", ".txt"},
{"listing_entry", NULL},
+ {"posts_autoload", NULL},
{"posts_sort", NULL},
// pagination
diff --git a/tests/blogc-make/check_blogc_make.sh.in b/tests/blogc-make/check_blogc_make.sh.in
index 36dfceb..d171027 100755
--- a/tests/blogc-make/check_blogc_make.sh.in
+++ b/tests/blogc-make/check_blogc_make.sh.in
@@ -755,6 +755,254 @@ diff -uN "${TEMP}/proj/_build/post/post11/index.html" "${TEMP}/expected-post-pos
rm -rf "${TEMP}/proj/_build"
+### default settings with some posts, order asc, posts_autoload
+
+mkdir -p "${TEMP}/proj/content/post2"
+
+cat > "${TEMP}/proj/content/post2/foo.txt" <<EOF
+TITLE: Foo
+DATE: 2016-10-01
+----------------
+This is foo.
+EOF
+
+cat > "${TEMP}/proj/content/post2/bar.txt" <<EOF
+TITLE: Bar
+DATE: 2016-09-01
+----------------
+This is bar.
+EOF
+
+cat > "${TEMP}/proj/blogcfile" <<EOF
+[global]
+AUTHOR_NAME = Lol
+AUTHOR_EMAIL = author@example.com
+SITE_TITLE = Lol's Website
+SITE_TAGLINE = WAT?!
+BASE_DOMAIN = http://example.org
+
+[settings]
+html_order = asc
+atom_order = asc
+posts_autoload = yes
+post_prefix = post2
+EOF
+
+ls "${TEMP}/proj/content/post"
+${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
+grep "_build/index\\.html" "${TEMP}/output.txt"
+grep "_build/atom\\.xml" "${TEMP}/output.txt"
+grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
+grep "_build/post2/foo/index\\.html" "${TEMP}/output.txt"
+grep "_build/post2/bar/index\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+cat > "${TEMP}/expected-index.html" <<EOF
+
+Listing: Bar - Sep 01, 2016, 12:00 AM GMT
+
+Listing: Foo - Oct 01, 2016, 12:00 AM GMT
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
+
+cat > "${TEMP}/expected-atom.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website</title>
+ <id>http://example.org/atom.xml</id>
+ <updated>2016-09-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atom.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Bar</title>
+ <id>http://example.org/post2/bar/index.html</id>
+ <updated>2016-09-01T00:00:00Z</updated>
+ <published>2016-09-01T00:00:00Z</published>
+ <link href="http://example.org/post2/bar/index.html" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is bar.</p>
+]]></content>
+ </entry>
+
+ <entry>
+ <title type="text">Foo</title>
+ <id>http://example.org/post2/foo/index.html</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <published>2016-10-01T00:00:00Z</published>
+ <link href="http://example.org/post2/foo/index.html" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is foo.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
+
+cat > "${TEMP}/expected-post-foo.html" <<EOF
+
+
+Foo - Oct 01, 2016, 12:00 AM GMT
+
+<p>This is foo.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post2/foo/index.html" "${TEMP}/expected-post-foo.html"
+
+cat > "${TEMP}/expected-post-bar.html" <<EOF
+
+
+Bar - Sep 01, 2016, 12:00 AM GMT
+
+<p>This is bar.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post2/bar/index.html" "${TEMP}/expected-post-bar.html"
+
+rm -rf "${TEMP}/proj/_build" "${TEMP}/proj/content/post2"
+
+
+### default settings with some posts, order desc, posts_autoload
+
+mkdir -p "${TEMP}/proj/content/post2"
+
+cat > "${TEMP}/proj/content/post2/foo.txt" <<EOF
+TITLE: Foo
+DATE: 2016-08-01
+----------------
+This is foo.
+EOF
+
+cat > "${TEMP}/proj/content/post2/bar.txt" <<EOF
+TITLE: Bar
+DATE: 2016-09-01
+----------------
+This is bar.
+EOF
+
+cat > "${TEMP}/proj/blogcfile" <<EOF
+[global]
+AUTHOR_NAME = Lol
+AUTHOR_EMAIL = author@example.com
+SITE_TITLE = Lol's Website
+SITE_TAGLINE = WAT?!
+BASE_DOMAIN = http://example.org
+
+[settings]
+posts_autoload = yes
+post_prefix = post2
+EOF
+
+ls "${TEMP}/proj/content/post"
+${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" 2>&1 | tee "${TEMP}/output.txt"
+grep "_build/index\\.html" "${TEMP}/output.txt"
+grep "_build/atom\\.xml" "${TEMP}/output.txt"
+grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
+grep "_build/post2/foo/index\\.html" "${TEMP}/output.txt"
+grep "_build/post2/bar/index\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+cat > "${TEMP}/expected-index.html" <<EOF
+
+Listing: Bar - Sep 01, 2016, 12:00 AM GMT
+
+Listing: Foo - Aug 01, 2016, 12:00 AM GMT
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
+
+cat > "${TEMP}/expected-atom.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website</title>
+ <id>http://example.org/atom.xml</id>
+ <updated>2016-09-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atom.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Bar</title>
+ <id>http://example.org/post2/bar/index.html</id>
+ <updated>2016-09-01T00:00:00Z</updated>
+ <published>2016-09-01T00:00:00Z</published>
+ <link href="http://example.org/post2/bar/index.html" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is bar.</p>
+]]></content>
+ </entry>
+
+ <entry>
+ <title type="text">Foo</title>
+ <id>http://example.org/post2/foo/index.html</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <published>2016-08-01T00:00:00Z</published>
+ <link href="http://example.org/post2/foo/index.html" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is foo.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
+
+cat > "${TEMP}/expected-post-foo.html" <<EOF
+
+
+Foo - Aug 01, 2016, 12:00 AM GMT
+
+<p>This is foo.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post2/foo/index.html" "${TEMP}/expected-post-foo.html"
+
+cat > "${TEMP}/expected-post-bar.html" <<EOF
+
+
+Bar - Sep 01, 2016, 12:00 AM GMT
+
+<p>This is bar.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post2/bar/index.html" "${TEMP}/expected-post-bar.html"
+
+rm -rf "${TEMP}/proj/_build" "${TEMP}/proj/content/post2"
+
+
### default settings with some posts, order asc, posts_sort
cat > "${TEMP}/proj/blogcfile" <<EOF