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

@ -12,12 +12,16 @@ import project;
import watcher;
/**
* Internal list of articles by slug.
* Internal list of articles, pages and projects by slug.
*/
Article[string] articles;
Page[string] pages;
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";
Article*[] articleList;
@ -27,6 +31,9 @@ Page*[] pageList;
immutable string projectSortPred = "a.title < b.title";
Project*[] projectList;
/**
* Output types for the content.
*/
enum OutputType {
HTML,
MARKDOWN
@ -38,7 +45,8 @@ const string MIME_MARKDOWN = "text/markdown";
/**
* 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) {
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) {
string slug = req.params["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) {
res.headers["Cache-Control"] = "public";
render!("pages/article-list.dt", articleList)(res);
}
/**
* Generates response for /projects and /projecten
*/
void projectGetOverview(HTTPServerRequest req, HTTPServerResponse res) {
res.headers["Cache-Control"] = "public";
render!("pages/project-list.dt", projectList)(res);
@ -122,8 +143,6 @@ void errorPage(HTTPServerRequest req, HTTPServerResponse res, HTTPServerErrorInf
}
void main() {
//articles["hello-world"] = new Article("hello-world.yamd");
HTTPServerSettings settings = new HTTPServerSettings;
settings.bindAddresses = ["0.0.0.0"];
settings.port = 3465;
@ -147,6 +166,8 @@ void main() {
router.get("/", &pageGet);
listenHTTP(settings, router);
// Start indexing pages.
runTask({
initPages!(Page, pageSortPred)(pages, pageList, "pages");
});

View file

@ -5,9 +5,11 @@ import std.datetime.date;
import std.experimental.logger;
import dyaml;
import page;
import vibe.d;
import page;
import utils;
/**
* Represents an article on the blog
@ -47,35 +49,13 @@ class Article : Page {
@safe
override protected void loadHeader(Node headerNode) {
super.loadHeader(headerNode);
if (headerNode.containsKey("author")) {
this.m_author = headerNode["author"].as!string;
} else {
this.m_author = "<unknown author>";
}
this.m_author = headerNode.getOr!string("author", "<unknown author>");
this.m_author = headerNode.getOr!string("excerpt", null);
if ("excerpt" in headerNode) {
this.m_excerpt = headerNode["excerpt"].as!string;
}
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;
}
SysTime firstPublished;
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);
}
@property string excerpt() { return m_excerpt; }

View file

@ -1,3 +1,6 @@
/**
* Constants which are passed to templates while rendering.
*/
class Constants {
public static immutable string SITE_NAME = "Chris Netsoj.nl";
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 {
/**
@ -43,7 +44,7 @@ class Page {
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.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:
* 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 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) {
if (key in node) {
return node[key].get!T;
try {
return node[key].get!T;
} catch (Exception e) {
return or;
}
} else {
return or;
}