aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/blogc-template.7.ronn62
-rw-r--r--src/blogc/renderer.c13
-rw-r--r--src/blogc/template-parser.c10
-rwxr-xr-xtests/blogc/check_blogc.sh.in41
-rw-r--r--tests/blogc/check_renderer.c30
-rw-r--r--tests/blogc/check_template_parser.c20
6 files changed, 137 insertions, 39 deletions
diff --git a/man/blogc-template.7.ronn b/man/blogc-template.7.ronn
index f418654..5184941 100644
--- a/man/blogc-template.7.ronn
+++ b/man/blogc-template.7.ronn
@@ -22,7 +22,8 @@ matches the requirements of the given block.
Blocks can be defined more than once, but can't be nested.
-The available blocks are: `entry`, `listing` and `listing_once`.
+The available blocks are: `entry`, `listing`, `listing_empty`, `listing_entry`
+and `listing_once`.
### entry block
@@ -56,6 +57,42 @@ This is how a `listing` block is defined:
will be included once for each entry.
{% endblock %}
+### listing_empty block
+
+This block is similar to the `listing` block, but its content is included
+only when there are no entries to be listed, either because no source files
+were provided or because there are no entries remaining after filtering (see
+blogc-pagination(7)).
+
+This is how a `listing_empty` block is defined:
+
+ {% block listing_empty %}
+ No entries available.
+ {% endblock %}
+
+### listing_entry block
+
+This block is identical to the `entry` block, but its content is included in
+the output file only when blogc(1) is called with `-l` and `-e` <SOURCE>
+options. The variables available in the block are provided by the source
+file provided using `-e` <SOURCE> option.
+
+This is how a `listing_entry` block is defined:
+
+ {% block listing_entry %}
+ This content will only be included when rendering a listing, but with
+ content provided by a single entry.
+ {% endblock %}
+
+When multiple `listing_entry` blocks are defined, blogc(1) should be called
+with multiple `-e` <SOURCE> options. If a `listing_entry` block does not have
+a corresponding `-e` <SOURCE> option, or if its value is an empty string,
+the content of the `listing_entry` block is not included.
+
+`listing_entry` blocks inside iterator are evaluated as multiple blocks and
+also require multiple `-e` <SOURCE> options. blogc(1) won't use the same
+source for every iteration.
+
### listing_once block
The content of a `listing_once` block is included in the output file when
@@ -87,29 +124,6 @@ that the `TITLE` variable is defined:
</ul>
{% endblock %}
-### listing_entry block
-
-This block is identical to the `entry` block, but its content is included in
-the output file only when blogc(1) is called with `-l` and `-e` <SOURCE>
-options. The variables available in the block are provided by the source
-file provided using `-e` <SOURCE> option.
-
-This is how a `listing_entry` block is defined:
-
- {% block listing_entry %}
- This content will only be included when rendering a listing, but with
- content provided by a single entry.
- {% endblock %}
-
-When multiple `listing_entry` blocks are defined, blogc(1) should be called
-with multiple `-e` <SOURCE> options. If a `listing_entry` block does not have
-a corresponding `-e` <SOURCE> option, or if its value is an empty string,
-the content of the `listing_entry` block is not included.
-
-`listing_entry` blocks inside iterator are evaluated as multiple blocks and
-also require multiple `-e` <SOURCE> options. blogc(1) won't use the same
-source for every iteration.
-
## TEMPLATE VARIABLES
Template variables are used to provide content to templates from blogc(1)
diff --git a/src/blogc/renderer.c b/src/blogc/renderer.c
index 140a86e..8f576e0 100644
--- a/src/blogc/renderer.c
+++ b/src/blogc/renderer.c
@@ -242,6 +242,7 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
tmp_source = listing_entry;
}
else if ((0 == strcmp("listing", node->data[0])) ||
+ (0 == strcmp("listing_empty", node->data[0])) ||
(0 == strcmp("listing_once", node->data[0]))) {
if (!listing) {
@@ -254,6 +255,18 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries,
break;
}
}
+ if (0 == strcmp("listing_empty", node->data[0])) {
+ if (sources != NULL) {
+
+ // we can just skip anything and walk until the next
+ // 'endblock'
+ while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) {
+ tmp = tmp->next;
+ node = tmp->data;
+ }
+ break;
+ }
+ }
if (0 == strcmp("listing", node->data[0])) {
if (sources == NULL) {
diff --git a/src/blogc/template-parser.c b/src/blogc/template-parser.c
index 0b4eb55..d3e9daf 100644
--- a/src/blogc/template-parser.c
+++ b/src/blogc/template-parser.c
@@ -380,6 +380,14 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
break;
}
else if ((current - start == 13) &&
+ (0 == strncmp("listing_empty", src + start, 13)))
+ {
+ block_open = true;
+ end = current;
+ state = TEMPLATE_BLOCK_END_WHITESPACE_CLEANER;
+ break;
+ }
+ else if ((current - start == 13) &&
(0 == strncmp("listing_entry", src + start, 13)))
{
block_open = true;
@@ -391,7 +399,7 @@ blogc_template_parse(const char *src, size_t src_len, bc_error_t **err)
*err = bc_error_parser(BLOGC_ERROR_TEMPLATE_PARSER, src,
src_len, current,
"Invalid block type. Allowed types are: 'entry', 'listing', "
- "'listing_once' and 'listing_entry'.");
+ "'listing_once', 'listing_empty' and 'listing_entry'.");
break;
case TEMPLATE_BLOCK_IF_START:
diff --git a/tests/blogc/check_blogc.sh.in b/tests/blogc/check_blogc.sh.in
index 87b71fa..208524d 100755
--- a/tests/blogc/check_blogc.sh.in
+++ b/tests/blogc/check_blogc.sh.in
@@ -183,7 +183,7 @@ cat > "${TEMP}/main.tmpl" <<EOF
<div class="meta">{{ DATE_FORMATTED }}</div>
<a href="{{ BASE_URL }}/post/{{ FILENAME }}/"><div>{{ TITLE }}</div></a>
</li>
- {% endblock %}
+ {% endblock %}{% block listing_empty %}vazio{% endblock %}
{% block listing_once %}
</ul>
</div>
@@ -576,6 +576,45 @@ ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
diff -uN "${TEMP}/output14.html" "${TEMP}/expected-output5.html"
+
+cat > "${TEMP}/expected-output6.html" <<EOF
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>Chunda's website</title>
+ </head>
+ <body>
+ <a href="/"><div class="name">Chunda's website</div></a>
+
+ <section class="main">
+ <div class="container">
+ <div class="content">
+ <div class="page-heading">Blog</div>
+ <ul>
+
+ vazio
+
+ </ul>
+ </div>
+ </div>
+ </section>
+
+
+ </body>
+</html>
+EOF
+
+${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
+ -D BASE_DOMAIN=http://bola.com/ \
+ -D BASE_URL= \
+ -D SITE_TITLE="Chunda's website" \
+ -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \
+ -t "${TEMP}/main.tmpl" \
+ -o "${TEMP}/output15.html" \
+ -l
+
+diff -uN "${TEMP}/output15.html" "${TEMP}/expected-output6.html"
+
echo "{% block listig %}foo{% endblock %}\n" > "${TEMP}/error.tmpl"
${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \
diff --git a/tests/blogc/check_renderer.c b/tests/blogc/check_renderer.c
index c1a9f9d..81e4a67 100644
--- a/tests/blogc/check_renderer.c
+++ b/tests/blogc/check_renderer.c
@@ -75,7 +75,8 @@ test_render_entry(void **state)
"{% if GUDA > \"zxd\" %}LOL3{% else %}ELSE{% endif %}\n"
"{% if GUDA <= \"zxc\" %}LOL4{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% foreach TAGS_ASD %}yay{% endforeach %}\n";
+ "{% foreach TAGS_ASD %}yay{% endforeach %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -100,6 +101,7 @@ test_render_entry(void **state)
"ELSE\n"
"LOL4\n"
"lol foo haha lol bar haha lol baz haha \n"
+ "\n"
"\n");
blogc_template_free_ast(l);
bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
@@ -122,7 +124,8 @@ test_render_listing(void **state)
"bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
"{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n";
+ "{% endblock %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -149,6 +152,7 @@ test_render_listing(void **state)
"bola: asd3\n"
"\n"
"\n"
+ "\n"
"\n");
blogc_template_free_ast(l);
bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
@@ -172,7 +176,8 @@ test_render_listing_entry(void **state)
"bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
"{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n";
+ "{% endblock %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -200,6 +205,7 @@ test_render_listing_entry(void **state)
"bola: asd3\n"
"\n"
"\n"
+ "\n"
"\n");
blogc_template_free_ast(l);
bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
@@ -224,7 +230,8 @@ test_render_listing_entry2(void **state)
"bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
"{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n";
+ "{% endblock %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -259,6 +266,7 @@ test_render_listing_entry2(void **state)
"bola: asd3\n"
"\n"
"\n"
+ "\n"
"\n");
blogc_template_free_ast(l);
bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
@@ -283,7 +291,8 @@ test_render_listing_entry3(void **state)
"bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
"{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n";
+ "{% endblock %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -319,6 +328,7 @@ test_render_listing_entry3(void **state)
"bola: asd3\n"
"\n"
"\n"
+ "\n"
"\n");
blogc_template_free_ast(l);
bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
@@ -343,7 +353,8 @@ test_render_listing_entry4(void **state)
"bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
"{% foreach TAGS_ASD %}yay{% endforeach %}\n"
- "{% endblock %}\n";
+ "{% endblock %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -382,6 +393,7 @@ test_render_listing_entry4(void **state)
"bola: asd3\n"
"\n"
"\n"
+ "\n"
"\n");
blogc_template_free_ast(l);
bc_slist_free_full(s, (bc_free_func_t) bc_trie_free);
@@ -403,7 +415,8 @@ test_render_listing_empty(void **state)
"{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n"
"bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n"
"{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n"
- "{% endblock %}\n";
+ "{% endblock %}\n"
+ "{% block listing_empty %}vazio{% endblock %}\n";
bc_error_t *err = NULL;
bc_slist_t *l = blogc_template_parse(str, strlen(str), &err);
assert_non_null(l);
@@ -413,7 +426,8 @@ test_render_listing_empty(void **state)
"foo\n"
"fuuu\n"
"\n"
- "\n");
+ "\n"
+ "vazio\n");
blogc_template_free_ast(l);
free(out);
}
diff --git a/tests/blogc/check_template_parser.c b/tests/blogc/check_template_parser.c
index 15ef7c4..79d41fb 100644
--- a/tests/blogc/check_template_parser.c
+++ b/tests/blogc/check_template_parser.c
@@ -59,7 +59,8 @@ test_template_parse(void **state)
"{% block listing_once %}asd{% endblock %}\n"
"{%- foreach BOLA %}hahaha{% endforeach %}\n"
"{% if BOLA == \"1\\\"0\" %}aee{% else %}fffuuuuuuu{% endif %}\n"
- "{% block listing_entry %}lol{% endblock %}";
+ "{% block listing_entry %}lol{% endblock %}\n"
+ "{% block listing_empty %}empty{% endblock %}";
bc_error_t *err = NULL;
bc_slist_t *ast = blogc_template_parse(a, strlen(a), &err);
assert_null(err);
@@ -125,8 +126,17 @@ test_template_parse(void **state)
blogc_assert_template_node(tmp, "\n", BLOGC_TEMPLATE_NODE_CONTENT);
blogc_assert_template_node(tmp->next, "listing_entry", BLOGC_TEMPLATE_NODE_BLOCK);
blogc_assert_template_node(tmp->next->next, "lol", BLOGC_TEMPLATE_NODE_CONTENT);
- blogc_assert_template_node(tmp->next->next->next, NULL, BLOGC_TEMPLATE_NODE_ENDBLOCK);
- assert_null(tmp->next->next->next->next);
+ blogc_assert_template_node(tmp->next->next->next, NULL,
+ BLOGC_TEMPLATE_NODE_ENDBLOCK);
+ blogc_assert_template_node(tmp->next->next->next->next, "\n",
+ BLOGC_TEMPLATE_NODE_CONTENT);
+ blogc_assert_template_node(tmp->next->next->next->next->next, "listing_empty",
+ BLOGC_TEMPLATE_NODE_BLOCK);
+ blogc_assert_template_node(tmp->next->next->next->next->next->next, "empty",
+ BLOGC_TEMPLATE_NODE_CONTENT);
+ blogc_assert_template_node(tmp->next->next->next->next->next->next->next, NULL,
+ BLOGC_TEMPLATE_NODE_ENDBLOCK);
+ assert_null(tmp->next->next->next->next->next->next->next->next);
blogc_template_free_ast(ast);
}
@@ -841,8 +851,8 @@ test_template_parse_invalid_block_type(void **state)
assert_null(ast);
assert_int_equal(err->type, BLOGC_ERROR_TEMPLATE_PARSER);
assert_string_equal(err->msg,
- "Invalid block type. Allowed types are: 'entry', 'listing', 'listing_once' "
- "and 'listing_entry'.\n"
+ "Invalid block type. Allowed types are: 'entry', 'listing', 'listing_once', "
+ "'listing_empty' and 'listing_entry'.\n"
"Error occurred near line 1, position 16: {% block chunda %}");
bc_error_free(err);
}