aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny van Kooten <dannyvankooten@users.noreply.github.com>2020-03-18 20:58:05 +0100
committerDanny van Kooten <dannyvankooten@users.noreply.github.com>2020-03-18 20:58:05 +0100
commitdd1a5a34eaba875746d48f47056ee2748cc452ee (patch)
treed9831677ab3501ec09d5183ac307a9071926529a
parent303f93d34cfd8cc545b5c38c3a4712bc30e5177f (diff)
downloadunja-dd1a5a34eaba875746d48f47056ee2748cc452ee.tar.gz
unja-dd1a5a34eaba875746d48f47056ee2748cc452ee.zip
add support for multi-level inheritance (depth > 1)
-rw-r--r--src/template.c30
-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.tmpl9
-rw-r--r--tests/data/inheritance-depth-2/one.tmpl9
-rw-r--r--tests/data/inheritance-depth-2/two.tmpl5
-rw-r--r--tests/test_template.c16
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