Refractored code and added extra comments
This commit is contained in:
parent
99f493dec3
commit
acd02aea20
|
@ -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.
|
||||||
|
|
31
source/app.d
31
source/app.d
|
@ -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");
|
||||||
});
|
});
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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 = "© Chris Josten, 2020";
|
public static immutable string COPYRIGHT = "© Chris Josten, 2020";
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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/";
|
||||||
|
|
|
@ -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) {
|
||||||
|
try {
|
||||||
return node[key].get!T;
|
return node[key].get!T;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return or;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return or;
|
return or;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Reference in a new issue