Refractored code and added extra comments

This commit is contained in:
Chris Josten 2020-06-24 19:57:04 +02:00
parent 99f493dec3
commit acd02aea20
8 changed files with 66 additions and 43 deletions

View file

@ -6,3 +6,11 @@ Hi there, lovely people!
# Test # Test
![Foo bar](/static/img/logo.png) ![Foo bar](/static/img/logo.png)
Hiep hiep hiep hiep hiep hahaaha warararararwararara flop adder flappppppp
Smerige lap met smeer. Doe daar je handen niet aan af. De maan is een grote
bal die zowat in de hemel hangt en daar dingen doet. Spinazie is een groente.
De maan is in tegenstelling tot spinazie geen groente.
Sjeetje, Vuurvos. Hoeveel letters moet ik nog tikken totdat je de leesmodus inschakeld?
Heel veel, heb ik zowat het idee. Wat verschrikkelijk.

View file

@ -12,12 +12,16 @@ import project;
import watcher; import watcher;
/** /**
* Internal list of articles by slug. * Internal list of articles, pages and projects by slug.
*/ */
Article[string] articles; Article[string] articles;
Page[string] pages; Page[string] pages;
Project[string] projects; Project[string] projects;
/**
* Default ordering and list with pointers to ordered articles.
* (Note: this is code which will actually be compiled and passed on!)
*/
immutable string articleSortPred = "a.firstPublished > b.firstPublished"; immutable string articleSortPred = "a.firstPublished > b.firstPublished";
Article*[] articleList; Article*[] articleList;
@ -27,6 +31,9 @@ Page*[] pageList;
immutable string projectSortPred = "a.title < b.title"; immutable string projectSortPred = "a.title < b.title";
Project*[] projectList; Project*[] projectList;
/**
* Output types for the content.
*/
enum OutputType { enum OutputType {
HTML, HTML,
MARKDOWN MARKDOWN
@ -38,7 +45,8 @@ const string MIME_MARKDOWN = "text/markdown";
/** /**
* Get's the document type for the given slug based on extension * Get's the document type for the given slug based on extension
* and returns the slug without extension and the document type. * and returns the slug without extension and the document type. Also removes the extension from the
* slug.
*/ */
private OutputType getOutputType(ref string slug) { private OutputType getOutputType(ref string slug) {
if (slug.endsWith(".md")) { if (slug.endsWith(".md")) {
@ -56,6 +64,16 @@ private OutputType getOutputType(ref string slug) {
} }
} }
/**
* Template method for fetching a single page for a subclass of page.
* Params:
* T = the data structure/class to be passed as template parameter. Must have a slug parameter.
* templ = The template to use when rendering.
* array = An associative array where the keys are slugs for parameters and the values the template parameter.
* req = The server request to consume. Assumes there is an slug parameter.
* res = The server response to write to.
*
*/
void getSingle(T, string templ)(ref T[string] array, HTTPServerRequest req, HTTPServerResponse res) { void getSingle(T, string templ)(ref T[string] array, HTTPServerRequest req, HTTPServerResponse res) {
string slug = req.params["slug"]; string slug = req.params["slug"];
OutputType outputType = getOutputType(slug); OutputType outputType = getOutputType(slug);
@ -82,13 +100,16 @@ void articleGetSingle(HTTPServerRequest req, HTTPServerResponse res) {
} }
/** /**
* Generates response for /posts/ and /palen/ * Generates response for /posts and /palen
*/ */
void articleGetOverview(HTTPServerRequest req, HTTPServerResponse res) { void articleGetOverview(HTTPServerRequest req, HTTPServerResponse res) {
res.headers["Cache-Control"] = "public"; res.headers["Cache-Control"] = "public";
render!("pages/article-list.dt", articleList)(res); render!("pages/article-list.dt", articleList)(res);
} }
/**
* Generates response for /projects and /projecten
*/
void projectGetOverview(HTTPServerRequest req, HTTPServerResponse res) { void projectGetOverview(HTTPServerRequest req, HTTPServerResponse res) {
res.headers["Cache-Control"] = "public"; res.headers["Cache-Control"] = "public";
render!("pages/project-list.dt", projectList)(res); render!("pages/project-list.dt", projectList)(res);
@ -122,8 +143,6 @@ void errorPage(HTTPServerRequest req, HTTPServerResponse res, HTTPServerErrorInf
} }
void main() { void main() {
//articles["hello-world"] = new Article("hello-world.yamd");
HTTPServerSettings settings = new HTTPServerSettings; HTTPServerSettings settings = new HTTPServerSettings;
settings.bindAddresses = ["0.0.0.0"]; settings.bindAddresses = ["0.0.0.0"];
settings.port = 3465; settings.port = 3465;
@ -147,6 +166,8 @@ void main() {
router.get("/", &pageGet); router.get("/", &pageGet);
listenHTTP(settings, router); listenHTTP(settings, router);
// Start indexing pages.
runTask({ runTask({
initPages!(Page, pageSortPred)(pages, pageList, "pages"); initPages!(Page, pageSortPred)(pages, pageList, "pages");
}); });

View file

@ -5,9 +5,11 @@ import std.datetime.date;
import std.experimental.logger; import std.experimental.logger;
import dyaml; import dyaml;
import page;
import vibe.d; import vibe.d;
import page;
import utils;
/** /**
* Represents an article on the blog * Represents an article on the blog
@ -47,35 +49,13 @@ class Article : Page {
@safe @safe
override protected void loadHeader(Node headerNode) { override protected void loadHeader(Node headerNode) {
super.loadHeader(headerNode); super.loadHeader(headerNode);
if (headerNode.containsKey("author")) { this.m_author = headerNode.getOr!string("author", "<unknown author>");
this.m_author = headerNode["author"].as!string; this.m_author = headerNode.getOr!string("excerpt", null);
} else {
this.m_author = "<unknown author>";
}
if ("excerpt" in headerNode) { SysTime firstPublished;
this.m_excerpt = headerNode["excerpt"].as!string; firstPublished = headerNode.getOr!SysTime("firstPublished", SysTime(DateTime.fromSimpleString("0001-Jan-01 00:00:00")));
} this.m_firstPublished = cast(DateTime) firstPublished;
this.m_updated = cast(DateTime) headerNode.getOr!SysTime("updated", firstPublished);
if ("firstPublished" in headerNode) {
try {
this.m_firstPublished = cast(DateTime) headerNode["firstPublished"].as!SysTime;
} catch(DateTimeException e) {
warningf("%s: invalid date format", this.m_slug);
}
} else {
this.m_firstPublished= DateTime.fromSimpleString("1970-Jan-01 00:00:00");
}
if ("updated" in headerNode) {
try {
this.m_updated = cast(DateTime) headerNode["updated"].as!SysTime();
} catch(DateTimeException e) {
warningf("%s: invalid date format", this.m_slug);
}
} else {
this.m_updated = this.m_firstPublished;
}
} }
@property string excerpt() { return m_excerpt; } @property string excerpt() { return m_excerpt; }

View file

@ -1,3 +1,6 @@
/**
* Constants which are passed to templates while rendering.
*/
class Constants { class Constants {
public static immutable string SITE_NAME = "Chris Netsoj.nl"; public static immutable string SITE_NAME = "Chris Netsoj.nl";
public static immutable string COPYRIGHT = "&copy; Chris Josten, 2020"; public static immutable string COPYRIGHT = "&copy; Chris Josten, 2020";

View file

@ -17,7 +17,8 @@ class ArticleParseException : Exception {
/** /**
* Represents a page on the blog * Represents a page on the blog. Every other page, including blog articles,
* projects and so on derrive from this class.
*/ */
class Page { class Page {
/** /**
@ -43,7 +44,7 @@ class Page {
private bool hasCalledSuper = false; private bool hasCalledSuper = false;
/** /**
* Creates a page from a file * Creates a page from a file. This will read from the file and parse it.
*/ */
this(string file) { this(string file) {
this.m_name = file; this.m_name = file;
@ -63,7 +64,8 @@ class Page {
/** /**
* Parse metadata from the header. * Parse metadata from the header. Subclasses should override this method,
* to parse their own metadata and call super.
* Params: * Params:
* headerNode = the YAML node to parse the header metadata from. * headerNode = the YAML node to parse the header metadata from.
*/ */

View file

@ -1,2 +1,6 @@
/**
* Paths to static data.
*/
immutable string STATIC_DIR = "/static/"; immutable string STATIC_DIR = "/static/";
immutable string IMG_DIR = STATIC_DIR ~ "img/"; immutable string IMG_DIR = STATIC_DIR ~ "img/";
immutable string SCRIPT_DIR = STATIC_DIR ~ "script/";

View file

@ -11,7 +11,11 @@ string toHumanString(DateTime value) {
T getOr(T)(Node node, string key, T or) { T getOr(T)(Node node, string key, T or) {
if (key in node) { if (key in node) {
return node[key].get!T; try {
return node[key].get!T;
} catch (Exception e) {
return or;
}
} else { } else {
return or; return or;
} }

View file

@ -8,12 +8,13 @@ block header
block sidebar block sidebar
block content block content
article article(itemscope, itemtype="https://schema.org/BlogPosting")
- import utils; - import utils;
header header
h1.title #{content.title} h1.title(itemprop="headline") #{content.title}
p.subtitle p.subtitle
| By #{content.author} on #{content.firstPublished.toHumanString} | By <span itemprop="author">#{content.author}</span>
| on <span itemprop="datePublished">#{content.firstPublished.toHumanString}</span>
- if (content.firstPublished != content.updated) - if (content.firstPublished != content.updated)
|, updated on #{content.updated.toHumanString} |, updated on <span itemprop="dateModified">#{content.updated.toHumanString}</span>
| !{content.content} section(itemprop="articleBody") !{content.content}