diff options
-rw-r--r-- | man/blogc-template.7.ronn | 62 | ||||
-rw-r--r-- | src/blogc/renderer.c | 13 | ||||
-rw-r--r-- | src/blogc/template-parser.c | 10 | ||||
-rwxr-xr-x | tests/blogc/check_blogc.sh.in | 41 | ||||
-rw-r--r-- | tests/blogc/check_renderer.c | 30 | ||||
-rw-r--r-- | tests/blogc/check_template_parser.c | 20 |
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); } |