Mercurial > blahgd > experimental
changeset 584:d35b9749eb26 v3.2
Merge branch 'tmpl-conditionals'
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Mon, 08 Jun 2015 23:13:51 -0400 |
parents | d7bc8562f5db (current diff) 805b6e53e8fb (diff) |
children | c4bc73e34590 |
files | config.cmake config.h.in post.c template.y |
diffstat | 15 files changed, 198 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/config.cmake Mon Jun 08 22:19:28 2015 -0400 +++ b/config.cmake Mon Jun 08 23:13:51 2015 -0400 @@ -34,6 +34,8 @@ set_default(VAR_VAL_KEY_MAXLEN 32) set_default(VAR_NAME_MAXLEN 32) +set_default(COND_STACK_DEPTH 10) + set_default(TAGCLOUD_MIN_SIZE 6) set_default(TAGCLOUD_MAX_SIZE 18)
--- a/config.h.in Mon Jun 08 22:19:28 2015 -0400 +++ b/config.h.in Mon Jun 08 23:13:51 2015 -0400 @@ -31,6 +31,8 @@ #cmakedefine VAR_VAL_KEY_MAXLEN ${VAR_VAL_KEY_MAXLEN} #cmakedefine VAR_NAME_MAXLEN ${VAR_NAME_MAXLEN} +#cmakedefine COND_STACK_DEPTH ${COND_STACK_DEPTH} + #cmakedefine TAGCLOUD_MIN_SIZE ${TAGCLOUD_MIN_SIZE} #cmakedefine TAGCLOUD_MAX_SIZE ${TAGCLOUD_MAX_SIZE}
--- a/index.c Mon Jun 08 22:19:28 2015 -0400 +++ b/index.c Mon Jun 08 23:13:51 2015 -0400 @@ -27,7 +27,7 @@ SQL_BIND_INT(stmt, 1, req->opts.index_stories); SQL_BIND_INT(stmt, 2, page * req->opts.index_stories); - load_posts(req, stmt); + load_posts(req, stmt, req->opts.index_stories); SQL_END(stmt); } @@ -58,7 +58,7 @@ SQL_BIND_INT(stmt, 3, req->opts.index_stories); SQL_BIND_INT(stmt, 4, page * req->opts.index_stories); - load_posts(req, stmt); + load_posts(req, stmt, req->opts.index_stories); SQL_END(stmt); } @@ -71,6 +71,7 @@ static void __store_pages(struct vars *vars, int page) { vars_set_int(vars, "prevpage", page + 1); + vars_set_int(vars, "curpage", page); vars_set_int(vars, "nextpage", page - 1); }
--- a/parse.h Mon Jun 08 22:19:28 2015 -0400 +++ b/parse.h Mon Jun 08 23:13:51 2015 -0400 @@ -3,6 +3,7 @@ #include "req.h" #include "post.h" +#include "error.h" #include "str.h" struct parser_output { @@ -17,6 +18,10 @@ size_t len; size_t pos; int lineno; + + /* template related */ + bool cond_stack[COND_STACK_DEPTH]; + int cond_stack_use; }; typedef void* yyscan_t; @@ -30,4 +35,31 @@ extern int fmt3_lex_init(yyscan_t* scanner); extern int tmpl_lex_init(yyscan_t* scanner); +static inline bool cond_value(struct parser_output *data) +{ + return ((data->cond_stack_use == -1) || + data->cond_stack[data->cond_stack_use]); +} + +static inline void cond_if(struct parser_output *data, bool val) +{ + ASSERT3S(data->cond_stack_use, <, COND_STACK_DEPTH); + + data->cond_stack[++data->cond_stack_use] = val; +} + +static inline void cond_else(struct parser_output *data) +{ + ASSERT3S(data->cond_stack_use, >=, 0); + + data->cond_stack[data->cond_stack_use] = !data->cond_stack[data->cond_stack_use]; +} + +static inline void cond_endif(struct parser_output *data) +{ + ASSERT3S(data->cond_stack_use, >=, 0); + + data->cond_stack_use--; +} + #endif
--- a/post.c Mon Jun 08 22:19:28 2015 -0400 +++ b/post.c Mon Jun 08 23:13:51 2015 -0400 @@ -431,7 +431,7 @@ * post id * post time */ -void load_posts(struct req *req, sqlite3_stmt *stmt) +void load_posts(struct req *req, sqlite3_stmt *stmt, int expected) { nvlist_t **posts; uint_t nposts; @@ -466,6 +466,7 @@ vars_set_nvl_array(&req->vars, "posts", posts, nposts); vars_set_int(&req->vars, "lastupdate", maxtime); + vars_set_int(&req->vars, "moreposts", nposts == expected); for (i = 0; i < nposts; i++) nvlist_free(posts[i]);
--- a/post.h Mon Jun 08 22:19:28 2015 -0400 +++ b/post.h Mon Jun 08 23:13:51 2015 -0400 @@ -68,7 +68,7 @@ extern nvlist_t *load_post(struct req *req, int postid, const char *titlevar, bool preview); extern void dump_post(struct post_old *post); extern void destroy_post(struct post *post); -extern void load_posts(struct req *req, sqlite3_stmt *stmt); +extern void load_posts(struct req *req, sqlite3_stmt *stmt, int expected); #define max(a,b) ((a)<(b)? (b) : (a))
--- a/render.c Mon Jun 08 22:19:28 2015 -0400 +++ b/render.c Mon Jun 08 23:13:51 2015 -0400 @@ -23,6 +23,8 @@ x.len = strlen(str); x.pos = 0; + x.cond_stack_use = -1; + tmpl_lex_init(&x.scanner); tmpl_set_extra(&x, x.scanner);
--- a/tag.c Mon Jun 08 22:19:28 2015 -0400 +++ b/tag.c Mon Jun 08 23:13:51 2015 -0400 @@ -69,6 +69,7 @@ static void __store_pages(struct vars *vars, int page) { vars_set_int(vars, "prevpage", page + 1); + vars_set_int(vars, "curpage", page); vars_set_int(vars, "nextpage", page - 1); } @@ -91,7 +92,7 @@ SQL_BIND_INT(stmt, 2, req->opts.index_stories); SQL_BIND_INT(stmt, 3, page * req->opts.index_stories); - load_posts(req, stmt); + load_posts(req, stmt, req->opts.index_stories); SQL_END(stmt); }
--- a/template.l Mon Jun 08 22:19:28 2015 -0400 +++ b/template.l Mon Jun 08 23:13:51 2015 -0400 @@ -20,7 +20,7 @@ %} %% -[{}|%] { return *yytext; } +[{}|%(),] { return *yytext; } [A-Za-z0-9_]+ { yylval->ptr = xstrdup(yytext); return WORD; } [ \r\t] { yylval->c = *yytext; return CHAR; } \n {
--- a/template.y Mon Jun 08 22:19:28 2015 -0400 +++ b/template.y Mon Jun 08 23:13:51 2015 -0400 @@ -41,6 +41,16 @@ return ret; } +static char *condconcat(struct parser_output *data, char *a, char *b) +{ + if (!cond_value(data)) { + free(b); + return a; + } + + return concat(a, b); +} + static char *__foreach_nv(struct req *req, nvpair_t *var, char *tmpl) { nvlist_t **items; @@ -93,11 +103,15 @@ return out; } -char *foreach(struct req *req, char *varname, char *tmpl) +static char *foreach(struct parser_output *data, struct req *req, char *varname, + char *tmpl) { nvpair_t *var; char *ret; + if (!cond_value(data)) + return xstrdup(""); + var = vars_lookup(&req->vars, varname); if (!var) return xstrdup(""); @@ -161,13 +175,19 @@ return xstrdup(tmp); } -static char *pipeline(struct req *req, char *varname, struct pipeline *line) +static char *pipeline(struct parser_output *data, struct req *req, + char *varname, struct pipeline *line) { struct pipestage *cur; struct val *val; nvpair_t *var; char *out; + if (!cond_value(data)) { + pipeline_destroy(line); + return xstrdup(""); + } + var = vars_lookup(&req->vars, varname); if (!var) { pipeline_destroy(line); @@ -200,6 +220,95 @@ return out; } + +static char *variable(struct parser_output *data, struct req *req, char *name) +{ + nvpair_t *var; + + if (!cond_value(data)) + return xstrdup(""); + + var = vars_lookup(&req->vars, name); + + if (!var) + return render_template(req, name); + else + return print_var(var); +} + +enum if_fxns { + IFFXN_GT, + IFFXN_LT, + IFFXN_EQ, +}; + +static uint64_t __function_get_arg(struct req *req, const char *arg) +{ + nvpair_t *var; + uint64_t val; + + if (!str2u64(arg, &val)) + return val; + + var = vars_lookup(&req->vars, arg); + if (!var) + return 0; + + switch (nvpair_type(var)) { + case DATA_TYPE_UINT64: + return pair2int(var); + default: + ASSERT(0); + } +} + +static char *__function(struct parser_output *data, struct req *req, + enum if_fxns fxn, const char *sa1, + const char *sa2) +{ + uint64_t ia1, ia2; /* int value of saX */ + bool result = true; + + ia1 = __function_get_arg(req, sa1); + ia2 = __function_get_arg(req, sa2); + + switch (fxn) { + case IFFXN_GT: + result = ia1 > ia2; + break; + case IFFXN_LT: + result = ia1 < ia2; + break; + case IFFXN_EQ: + result = ia1 == ia2; + break; + } + + cond_if(data, result); + + return xstrdup(NULL); +} + +static char *function(struct parser_output *data, struct req *req, + const char *fxn, const char *sa1, const char *sa2) +{ + if (!strcmp(fxn, "ifgt")) { + return __function(data, req, IFFXN_GT, sa1, sa2); + } else if (!strcmp(fxn, "iflt")) { + return __function(data, req, IFFXN_LT, sa1, sa2); + } else if (!strcmp(fxn, "ifeq")) { + return __function(data, req, IFFXN_EQ, sa1, sa2); + } else if (!strcmp(fxn, "endif")) { + cond_endif(data); + } else if (!strcmp(fxn, "else")) { + cond_else(data); + } else { + LOG("unknown template function '%s'", fxn); + ASSERT(0); + } + + return xstrdup(NULL); +} %} %union { @@ -221,33 +330,40 @@ page : words { data->output = $1; } ; -words : words CHAR { $$ = concat($1, tostr($2)); } - | words WORD { $$ = concat($1, $2); } - | words '|' { $$ = concat($1, xstrdup("|")); } - | words '%' { $$ = concat($1, xstrdup("%")); } +words : words CHAR { $$ = condconcat(data, $1, tostr($2)); } + | words WORD { $$ = condconcat(data, $1, $2); } + | words '|' { $$ = condconcat(data, $1, xstrdup("|")); } + | words '%' { $$ = condconcat(data, $1, xstrdup("%")); } + | words '(' { $$ = condconcat(data, $1, xstrdup("(")); } + | words ')' { $$ = condconcat(data, $1, xstrdup(")")); } + | words ',' { $$ = condconcat(data, $1, xstrdup(",")); } | words cmd { $$ = concat($1, $2); } | { $$ = xstrdup(""); } ; cmd : '{' WORD pipeline '}' { - $$ = pipeline(data->req, $2, $3); + $$ = pipeline(data, data->req, $2, $3); free($2); } | '{' WORD '%' WORD '}' { - $$ = foreach(data->req, $2, $4); + $$ = foreach(data, data->req, $2, $4); free($2); free($4); } + | '{' WORD '(' WORD ',' WORD ')' '}'{ + $$ = function(data, data->req, $2, $4, $6); + free($2); + } + | '{' WORD '(' WORD ')' '}' { + $$ = function(data, data->req, $2, $4, NULL); + free($2); + } + | '{' WORD '(' ')' '}' { + $$ = function(data, data->req, $2, NULL, NULL); + free($2); + } | '{' WORD '}' { - nvpair_t *var; - - var = vars_lookup(&data->req->vars, $2); - - if (!var) - $$ = render_template(data->req, $2); - else - $$ = print_var(var); - + $$ = variable(data, data->req, $2); free($2); } ;
--- a/web/templates/html/archivepager.tmpl Mon Jun 08 22:19:28 2015 -0400 +++ b/web/templates/html/archivepager.tmpl Mon Jun 08 23:13:51 2015 -0400 @@ -1,4 +1,8 @@ <div class="navigation"> + {ifeq(moreposts,1)} <div class="alignleft"><a href="?m={archid}&paged={prevpage}">« Older Entries</a></div> + {endif()} + {ifgt(curpage,0)} <div class="alignright"><a href="?m={archid}&paged={nextpage}">Newer Entries »</a></div> + {endif()} </div>
--- a/web/templates/html/catpager.tmpl Mon Jun 08 22:19:28 2015 -0400 +++ b/web/templates/html/catpager.tmpl Mon Jun 08 23:13:51 2015 -0400 @@ -1,4 +1,8 @@ <div class="navigation"> + {ifeq(moreposts,1)} <div class="alignleft"><a href="?cat={tagid}&paged={prevpage}">« Older Entries</a></div> + {endif()} + {ifgt(curpage,0)} <div class="alignright"><a href="?cat={tagid}&paged={nextpage}">Newer Entries »</a></div> + {endif()} </div>
--- a/web/templates/html/fullstory.tmpl Mon Jun 08 22:19:28 2015 -0400 +++ b/web/templates/html/fullstory.tmpl Mon Jun 08 23:13:51 2015 -0400 @@ -1,9 +1,11 @@ {story} <h2>{numcom} Comments <a href="#respond" title="Leave a comment">»</a></h2> +{ifgt(numcom,0)} <ol id="commentlist"> {comments%comment} </ol> +{endif()} <p><a href='{baseurl}/?p={id}&feed=atom'>Atom feed for comments on this post.</a></p>
--- a/web/templates/html/indexpager.tmpl Mon Jun 08 22:19:28 2015 -0400 +++ b/web/templates/html/indexpager.tmpl Mon Jun 08 23:13:51 2015 -0400 @@ -1,4 +1,8 @@ <div class="navigation"> + {ifeq(moreposts,1)} <div class="alignleft"><a href="?paged={prevpage}">« Older Entries</a></div> + {endif()} + {ifgt(curpage,0)} <div class="alignright"><a href="?paged={nextpage}">Newer Entries »</a></div> + {endif()} </div>
--- a/web/templates/html/tagpager.tmpl Mon Jun 08 22:19:28 2015 -0400 +++ b/web/templates/html/tagpager.tmpl Mon Jun 08 23:13:51 2015 -0400 @@ -1,4 +1,8 @@ <div class="navigation"> + {ifeq(moreposts,1)} <div class="alignleft"><a href="?tag={tagid}&paged={prevpage}">« Older Entries</a></div> + {endif()} + {ifgt(curpage,0)} <div class="alignright"><a href="?tag={tagid}&paged={nextpage}">Newer Entries »</a></div> + {endif()} </div>