diff options
author | Danny van Kooten <dannyvankooten@users.noreply.github.com> | 2020-03-18 20:58:05 +0100 |
---|---|---|
committer | Danny van Kooten <dannyvankooten@users.noreply.github.com> | 2020-03-18 20:58:05 +0100 |
commit | dd1a5a34eaba875746d48f47056ee2748cc452ee (patch) | |
tree | d9831677ab3501ec09d5183ac307a9071926529a | |
parent | 303f93d34cfd8cc545b5c38c3a4712bc30e5177f (diff) | |
download | unja-dd1a5a34eaba875746d48f47056ee2748cc452ee.tar.gz unja-dd1a5a34eaba875746d48f47056ee2748cc452ee.zip |
add support for multi-level inheritance (depth > 1)
-rw-r--r-- | src/template.c | 30 | ||||
-rw-r--r-- | tests/data/inheritance-depth-1/base.tmpl (renamed from tests/data/01/base.tmpl) | 0 | ||||
-rw-r--r-- | tests/data/inheritance-depth-1/one.tmpl (renamed from tests/data/01/child.tmpl) | 0 | ||||
-rw-r--r-- | tests/data/inheritance-depth-2/base.tmpl | 9 | ||||
-rw-r--r-- | tests/data/inheritance-depth-2/one.tmpl | 9 | ||||
-rw-r--r-- | tests/data/inheritance-depth-2/two.tmpl | 5 | ||||
-rw-r--r-- | tests/test_template.c | 16 |
7 files changed, 58 insertions, 11 deletions
diff --git a/src/template.c b/src/template.c index a1b3ef4..58874e4 100644 --- a/src/template.c +++ b/src/template.c @@ -50,7 +50,7 @@ void buffer_reserve(struct buffer *buf, int l) { buf->string = realloc(buf->string, buf->cap * sizeof *buf->string); if (!buf->string) { - err(EXIT_FAILURE, "out of memory"); + errx(EXIT_FAILURE, "out of memory"); } } } @@ -152,9 +152,13 @@ struct hashmap *find_blocks_in_ast(mpc_ast_t *node, struct hashmap *map) { } struct env *env_new(char *dirname) { + /* store current working dir so we can revert to it after reading templates */ + char working_dir[256]; + getcwd(working_dir, 255); + DIR *dr = opendir(dirname); if (dr == NULL) { - err(EXIT_FAILURE, "could not open directory %s", dirname); + errx(EXIT_FAILURE, "could not open directory \"%s\"", dirname); } struct env *env = malloc(sizeof *env); @@ -187,10 +191,10 @@ struct env *env_new(char *dirname) { } hashmap_insert(env->templates, name, t); - } - closedir(dr); + closedir(dr); + chdir(working_dir); return env; } @@ -214,7 +218,7 @@ char *read_file(char *filename) { FILE *f = fopen(filename, "r"); if (!f) { - err(EXIT_FAILURE, "Could not open \"%s\" for reading", filename); + errx(EXIT_FAILURE, "could not open \"%s\" for reading", filename); } unsigned int read = 0; @@ -414,11 +418,15 @@ int eval(struct buffer *buf, mpc_ast_t* t, struct context *ctx) { // find block in "lowest" template struct template *templ = ctx->current_template; mpc_ast_t *block = hashmap_get(templ->blocks, block_name); + while (templ != NULL && block == NULL) { + templ = hashmap_get(ctx->env->templates, templ->parent); + block = hashmap_get(templ->blocks, block_name); + } + if (block) { eval(buf, block->children[4], ctx); } else { - /* TODO: Keep looking for block in parent templates */ - // just render this block if it wasn't found in any of the lower templates + /* block not found in any lower template, so just render the one we got */ eval(buf, t->children[4], ctx); } @@ -540,7 +548,13 @@ char *template(struct env *env, char *template_name, struct hashmap *vars) { // find root template while (t->parent != NULL) { - t = hashmap_get(env->templates, t->parent); + char *parent_name = t->parent; + t = hashmap_get(env->templates, parent_name); + + if (t == NULL) { + errx(EXIT_FAILURE, "template tried to extend unexisting parent \"%s\"", parent_name); + break; + } } return render_ast(t->ast, &ctx); diff --git a/tests/data/01/base.tmpl b/tests/data/inheritance-depth-1/base.tmpl index 241c78c..241c78c 100644 --- a/tests/data/01/base.tmpl +++ b/tests/data/inheritance-depth-1/base.tmpl diff --git a/tests/data/01/child.tmpl b/tests/data/inheritance-depth-1/one.tmpl index 05467a6..05467a6 100644 --- a/tests/data/01/child.tmpl +++ b/tests/data/inheritance-depth-1/one.tmpl diff --git a/tests/data/inheritance-depth-2/base.tmpl b/tests/data/inheritance-depth-2/base.tmpl new file mode 100644 index 0000000..2f5157c --- /dev/null +++ b/tests/data/inheritance-depth-2/base.tmpl @@ -0,0 +1,9 @@ +0 + +{%- block content %} +0 +{%- endblock %} + +{%- block footer %} +0 +{%- endblock -%}
\ No newline at end of file diff --git a/tests/data/inheritance-depth-2/one.tmpl b/tests/data/inheritance-depth-2/one.tmpl new file mode 100644 index 0000000..1e93d11 --- /dev/null +++ b/tests/data/inheritance-depth-2/one.tmpl @@ -0,0 +1,9 @@ +{% extends "base.tmpl" %} + +{% block content %} +1 +{% endblock %} + +{% block footer %} +1 +{% endblock %}
\ No newline at end of file diff --git a/tests/data/inheritance-depth-2/two.tmpl b/tests/data/inheritance-depth-2/two.tmpl new file mode 100644 index 0000000..cbdbe34 --- /dev/null +++ b/tests/data/inheritance-depth-2/two.tmpl @@ -0,0 +1,5 @@ +{% extends "one.tmpl" %} + +{% block footer %} +2 +{% endblock %}
\ No newline at end of file diff --git a/tests/test_template.c b/tests/test_template.c index b427f7c..9e23ca2 100644 --- a/tests/test_template.c +++ b/tests/test_template.c @@ -276,12 +276,22 @@ TEST(buffer_alloc) { free(output); } -TEST(inheritance) { - struct env *env = env_new("./tests/data/01/"); - char *output = template(env, "child.tmpl", NULL); +TEST(inheritance_depth_1) { + /* TODO: Check why this fails with files names 1.tmpl */ + struct env *env = env_new("./tests/data/inheritance-depth-1/"); + char *output = template(env, "one.tmpl", NULL); assert_str(output, "Header\nChild content\nFooter\n"); free(output); env_free(env); } + +TEST(inheritance_depth_2) { + struct env *env = env_new("./tests/data/inheritance-depth-2/"); + char *output = template(env, "two.tmpl", NULL); + assert_str(output, "0\n1\n2\n"); + free(output); + env_free(env); +} + END_TESTS
\ No newline at end of file |