Skip to content

Instantly share code, notes, and snippets.

@lpereira
Last active January 26, 2016 23:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lpereira/6694015 to your computer and use it in GitHub Desktop.
Save lpereira/6694015 to your computer and use it in GitHub Desktop.
How to use sequences with lwan template
#include <assert.h>
#include <sys/types.h>
#include <dirent.h>
#include "lwan-status.h"
#include "lwan-template.h"
#include "strbuf.h"
struct file_list {
const char *path;
struct {
lwan_tpl_generator_t generator;
const char *name;
} file_list;
};
int dir_list_generator(coro_t *coro)
{
DIR *dir;
struct dirent *ent;
struct file_list *fl = coro_get_data(coro);
dir = opendir(fl->path);
if (!dir)
return 0;
while ((ent = readdir(dir))) {
fl->file_list.name = ent->d_name;
coro_yield(coro, 1);
}
closedir(dir);
return 0;
}
int main(void)
{
static const char *str_tpl = "Listing of {{path}}: " \
"files={{#file_list}}\t{{file_list.name}}\t{{/file_list}}";
static lwan_var_descriptor_t lst_item_desc[] = {
TPL_VAR_STR(struct file_list, files_list.name),
TPL_VAR_SENTINEL
};
static lwan_var_descriptor_t main_desc[] = {
TPL_VAR_STR(struct file_list, path),
TPL_VAR_SEQUENCE(struct file_list, file_list, dir_list_generator, lst_item_desc),
TPL_VAR_SENTINEL
};
lwan_tpl_t *tpl;
tpl = lwan_tpl_compile_string(str_tpl, main_desc);
if (!tpl) {
puts("could not compile template");
return 1;
}
struct bla_t b;
b.str1 = "ola!";
b.str2 = "mundo";
b.files.path = "/tmp";
strbuf_t *str = lwan_tpl_apply(tpl, &b);
if (!str) {
puts("could not apply template");
return 1;
}
printf("applied template:\n\n------%s\n------\n", strbuf_get_buffer(str));
lwan_tpl_free(tpl);
strbuf_free(str);
return 0;
}
@adam-hanna
Copy link

Hi lpereira,

Thanks for this, it was very helpful! However, it didn't compile as there were some very minor bugs and it was slightly outdated for your newer templating library. It also took me a second to understand what was happening with the file system, so I removed that and used a simple array of structs.

Lastly, my example is outputting integers rather than the strings I input. I don't know why that's happening?!? Hope it helps!

#include <stdio.h>
#include "strbuf.h"
#include "lwan-template.h"

/* slightly modified from https://gist.github.com/lpereira/6694015 */

// an individual toDo struct
struct toDo_t
{
    char *note;
};

// an array to hold all of our toDo items
struct toDo_t toDos[3];

struct toDos_list {
    struct {
        lwan_tpl_list_generator_t generator;
        char *note;
    } toDos_list;
};

int toDos_list_generator(coro_t *coro)
{
    struct toDos_list *c = coro_get_data(coro);

    for ( int i = 0; i < 3; i++ ) {
        c->toDos_list.note = toDos[i].note;
        coro_yield(coro, 1);
    }

    return 0;
}

int
main(int argc, char **argv)
{
    lwan_var_descriptor_t toDo_descriptor[] = {
        TPL_VAR_INT(struct toDos_list, toDos_list.note),
        TPL_VAR_SENTINEL
    };
    lwan_var_descriptor_t toDos_descriptor[] = {
        TPL_VAR_SEQUENCE(struct toDos_list, toDos_list, toDos_list_generator, toDo_descriptor),
        TPL_VAR_SENTINEL
    };

    lwan_tpl_t *toDo_templ;
    strbuf_t *rendered_Sequence;

    toDo_templ = lwan_tpl_compile_string("Things to do: {{#toDos_list}}\t{{toDos_list.note}}\t{{/toDos_list}}", toDos_descriptor);


    /* initialize some data */
    toDos[0].note = "Stoofs0";
    toDos[1].note = "Stoofs1";
    toDos[2].note = "Stoofs2";

    rendered_Sequence = lwan_tpl_apply(toDo_templ, &toDos);

    printf("%s\n", strbuf_get_buffer(rendered_Sequence));


    lwan_tpl_free(toDo_templ);
    strbuf_free(rendered_Sequence);

    return 0;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment