diff options
author | sternenseemann <sternenseemann@systemli.org> | 2020-08-07 23:58:50 +0200 |
---|---|---|
committer | sternenseemann <sternenseemann@systemli.org> | 2020-08-08 02:16:15 +0200 |
commit | e5cd70a596f797ddff973861a5b72d2af1dec1b9 (patch) | |
tree | 95f8d2f93e79e8b1a67475897cff5a10f8f4225a /templates | |
parent | 351d951158992488df4a679a4a882468b0b21793 (diff) |
feat(treewide): major rework
Unfortunately, I got a bit carried away after realizing that the initial change would be a breaking change anyways, so I am now left with a huge diff which can't be really split up. Please excuse this. The changes are as follows: * Rename blogpost → entry (breaking): make_blogpost → make_entry, blog_post → blog_entry etc. * Rename blogdefs.h → core.h (breaking) * Split functions from main.c into cgiutil and entry * entry / make_entry: * Use modification time instead of time in filename (breaking) * Rename timestamp → time (breaking) * Add field title (currently basename, breaking) * Add field text and text_size which can be use to store the contents of the associated file using mmap (fields default to NULL and -1 respectively, breaking) * Do PATH_INFO resolving and on disk path building in make_entry instead of in blog_index / blog_rss / blog_entry * entry_get_text: add function to mmap an entry's file into the structure * free_entry: also unmap file if present * make_index: Add function to build an array of entries reverse sorted by time * blog_index / blog_rss: * use make_index instead of scandir and make_blogpost_from_dirent * (blog_rss) use entry_get_text to pass the template the text of the entry. * template: * template_post_index_entry → template_index_entry (breaking) * template_post_single_entry → template_single_entry (breaking) * replace template_error_404() with generic template_error(status) * templates/simple.c: * Use xml library instead of printf * Use entry.text instead of opening the file in the template * include CSS if BLOG_CSS is set in config.h * document internal and public interfaces using doxygen * build process: * build object files individually * build process configuration in config.mk (breaking) * support templates in arbitrary locations * build default config.h if it's missing * add install phase * Rename target to sternenblog.cgi (breaking)
Diffstat (limited to 'templates')
-rw-r--r-- | templates/simple.c | 203 |
1 files changed, 159 insertions, 44 deletions
diff --git a/templates/simple.c b/templates/simple.c index eec43cc..8e1037e 100644 --- a/templates/simple.c +++ b/templates/simple.c @@ -1,69 +1,184 @@ +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> -#include "../template.h" -#include "../config.h" +#include <string.h> +#include <time.h> -void template_header(void) { - printf("<!doctype html>\n" - "<html>\n" - "<head>\n" - "\t<title>%s</title>\n" - "\t<meta charset=\"utf-8\"/>\n" - "\t<style type=\"text/css\">\n" - "\ta:link, a:visited{\n" - "\tcolor:blue;\n" - "\t}</style>\n" - "</head>\n" - "<body><h1>%s</h1>\n", BLOG_TITLE, BLOG_TITLE); -} +#include <core.h> +#include <template.h> +#include <config.h> +#include <cgiutil.h> +#include <xml.h> -void template_footer(void) { - printf("\t<footer><a href=\"%s/rss.xml\">RSS feed</a></footer>\n" - "</body></html>", getenv("SCRIPT_NAME")); +extern long timezone; + +static struct xml_context ctx; + +int make_link(char *buf, size_t size, char *abs_path) { + // TODO pass to template somehow? + char *script_name = getenv("SCRIPT_NAME"); + + if(script_name == NULL || buf == NULL || abs_path == NULL) { + return -1; + } + + size_t script_name_len = strlen(script_name); + size_t abs_path_len = strlen(abs_path); + + size_t min_buf_len = script_name_len + abs_path_len + 1; + + if(min_buf_len > size) { + return -1; + } + + if(script_name_len > 0) { + memcpy(buf, script_name, script_name_len); + } + if(abs_path_len > 0) { + memcpy(buf + script_name_len, abs_path, abs_path_len); + } + + buf[script_name_len + abs_path_len] = '\0'; + + return min_buf_len; } -void template_post_single_entry(struct blogpost post) { - FILE *fp = fopen(post.path, "r"); - char c; +void output_entry_time(struct xml_context *ctx, struct entry entry) { + tzset(); + char *format = timezone == 0 ? "%Y-%m-%d %TZ" : "%Y-%m-%d %T%z"; + + char strtime[32]; + struct tm *local = localtime(&entry.time); - if(fp == NULL) { - template_error_404(); - exit(EXIT_SUCCESS); - /* TODO: does CGI still work correctly if we exit - * with EXIT_FAILURE? */ + if(strftime(strtime, sizeof strtime, format, local) > 0) { + xml_open_tag_attrs(ctx, "time", 1, "datetime", strtime); + xml_raw(ctx, strtime); + xml_close_tag(ctx, "time"); } +} + +void template_header(void) { + new_xml_context(&ctx); + ctx.warn = stderr; + ctx.closing_slash = 0; + + xml_raw(&ctx, "<!doctype html>"); + xml_open_tag_attrs(&ctx, "html", 1, "lang", "en"); + + xml_open_tag(&ctx, "head"); - printf("<article>\n"); + xml_empty_tag(&ctx, "meta", 1, "charset", "utf-8"); - while((c = fgetc(fp)) != EOF) { - printf("%c", c); + #ifdef BLOG_CSS + xml_empty_tag(&ctx, "link", 3, + "rel", "stylesheet", + "type", "text/css", + "href", BLOG_CSS); + #endif + + xml_open_tag(&ctx, "title"); + xml_raw(&ctx, BLOG_TITLE); + xml_close_tag(&ctx, "title"); + + xml_close_tag(&ctx, "head"); + + xml_open_tag(&ctx, "body"); + xml_open_tag(&ctx, "header"); + xml_open_tag(&ctx, "h1"); + xml_raw(&ctx, BLOG_TITLE); + xml_close_including(&ctx, "header"); + + xml_open_tag(&ctx, "main"); +} + +void template_footer(void) { + xml_close_tag(&ctx, "main"); + + xml_open_tag(&ctx, "footer"); + + char rss_link[256]; + if(make_link(rss_link, sizeof rss_link, "/rss.xml") != -1) { + xml_open_tag_attrs(&ctx, "a", 1, "href", rss_link); + xml_raw(&ctx, "RSS Feed"); + xml_close_tag(&ctx, "a"); } - printf("<p><a href=\"%s\">Back</a></p></article>\n", getenv("SCRIPT_NAME")); + xml_close_all(&ctx); - fclose(fp); + del_xml_context(&ctx); } -void template_post_index_entry(struct blogpost post) { - FILE *fp = fopen(post.path, "r"); - char c; +void template_single_entry(struct entry entry) { + xml_open_tag(&ctx, "article"); - if(fp == NULL) { - fprintf(stderr, "No such file or directory: %s\n", post.path); - exit(EXIT_FAILURE); + if(entry.text_size > 0) { + xml_open_tag_attrs(&ctx, "div", 1, "class", "content"); + xml_raw(&ctx, entry.text); + xml_close_tag(&ctx, "div"); } - printf("<article>\n"); + char *script_name = getenv("SCRIPT_NAME"); + + xml_open_tag_attrs(&ctx, "div", 1, "class", "meta"); + xml_open_tag(&ctx, "ul"); + + // time of publishing + xml_open_tag(&ctx, "li"); + output_entry_time(&ctx, entry); + xml_close_tag(&ctx, "li"); - while((c = fgetc(fp)) != EOF) { - printf("%c", c); + // link back to index + xml_open_tag(&ctx, "li"); + xml_open_tag_attrs(&ctx, "a", 1, "href", script_name); + xml_raw(&ctx, "Back"); + xml_close_tag(&ctx, "a"); + xml_close_tag(&ctx, "li"); + + xml_close_including(&ctx, "article"); +} + +void template_index_entry(struct entry entry) { + // TODO time? + xml_open_tag_attrs(&ctx, "article", 1, "id", entry.title); + if(entry.text_size > 0) { + xml_open_tag_attrs(&ctx, "div", 1, "class", "content index"); + xml_raw(&ctx, entry.text); + xml_close_tag(&ctx, "div"); } - printf("<p><a href=\"%s\">Permalink</a></p></article>\n", post.link); + xml_open_tag_attrs(&ctx, "div", 1, "class", "meta index"); + xml_open_tag(&ctx, "p"); + xml_open_tag_attrs(&ctx, "a", 1, "href", entry.link); + xml_raw(&ctx, "Permalink"); - fclose(fp); + xml_close_including(&ctx, "article"); } -void template_error_404(void) { - printf("<article><h2>Error 404</h2><p>This page does not exist. I am so sorry</p></article>"); +void template_error(int status) { + xml_open_tag_attrs(&ctx, "div", 1, "class", "error-page"); + xml_open_tag(&ctx, "h2"); + xml_raw(&ctx, "An error occured while handling your request"); + xml_close_tag(&ctx, "h2"); + + xml_open_tag(&ctx, "p"); + + if(status == 500) { + xml_raw(&ctx, "Something is wrong with this application and/or its server (error 500)."); + } else if(status == 404) { + xml_raw(&ctx, "What you requested doesn't exist (error 404)."); + } else { + xml_raw(&ctx, "The error encoutered is: "); + xml_raw(&ctx, http_status_line(status)); + } + + xml_close_tag(&ctx, "p"); + + char *script_name = getenv("SCRIPT_NAME"); + + xml_open_tag(&ctx, "nav"); + xml_open_tag(&ctx, "p"); + xml_open_tag_attrs(&ctx, "a", 1, "href", script_name); + xml_raw(&ctx, "Back"); + + xml_close_including(&ctx, "div"); } |