Added content, projects and dark mode

This commit is contained in:
Chris Josten 2020-06-24 15:53:18 +02:00
parent 4a9cfda0bd
commit e1b43bc4c3
23 changed files with 280 additions and 31 deletions

42
articles/hello-world.yamd Normal file
View file

@ -0,0 +1,42 @@
title: Hello World
slug: hello-world
firstPublished: 2019-06-30 14:31:45
updated: 2020-06-23 23:05:00
author: Chris
tags:
- test
- test2
- test3
---
Hello, world! This is the first article ever written on this site! It
mainly consists of tests to check out the features of this website.
# Second paragraph
[test](https://example.com)
> Lololo
> <footer>Very wise man</footer>
`
code.execute();
`
Quibusdam laborum reprehenderit voluptate labore perferendis consequatur odit laboriosam. Perspiciatis saepe consequuntur voluptas. Deserunt et totam asperiores natus nulla illum.
Laborum quibusdam commodi corporis debitis velit eum autem. Quo labore numquam ipsa quo corrupti maxime ratione cupiditate. Ab impedit et et quo et sed.
Eaque officiis ut minus. Repellat commodi illum qui voluptas quos. Ut labore quod adipisci enim. Dolor pariatur ut earum id quia eum non. Consequatur assumenda nihil neque nihil cupiditate corrupti eaque sint.
Est at a quo atque vel est itaque quis. Illo enim omnis maiores quia dolorum cumque aspernatur. Rem debitis delectus eius et possimus nihil sed veniam.
Saepe non quidem id ab dicta aliquid. Ut consequatur sint non. Enim veritatis dolor asperiores consequatur itaque aliquid dolorem. Perspiciatis rem quidem voluptas qui esse recusandae.
```{.html .numberSource .literate}
<!doctype html>
<html lang="en">
<head>
<title>This is supposed to be such a large title that the page has to scroll</title>
</head>
</html>
```

3
articles/hi.yamd Normal file
View file

@ -0,0 +1,3 @@
title: "chris"
---
Yet another article. How boring.

8
articles/second.yamd Normal file
View file

@ -0,0 +1,8 @@
title: Second!
author: Chris Josten
slug: second
---
Hi there, lovely people!
# Test
![Foo bar](/static/img/logo.png)

5
pages/contact.yamd Normal file
View file

@ -0,0 +1,5 @@
title: Contact
slug: contact
---
If you want to contact me, you are able to reach me at <chrNOTTHISPARTis+website at netsoj.nl>.
Hopefully that obfuscated address will

1
pages/foo/bar Normal file
View file

@ -0,0 +1 @@
Hi

12
pages/index.yamd Normal file
View file

@ -0,0 +1,12 @@
title: Home
slug: index
---
I am Chris Josten &mdash; you might have guessed it from the url &mdash; and I am shaping the future of this
world by handcrafting influential software that will be etched into the very fibers of history!
Well, actually, I sometimes
use my computer and type some letters and code with it that will be forgotten within a month.
I have not made any substantial (yet), but [I have written some hobby projects](/projects/).
I also would like to take this opportunity to mention that the number one is not a prime number and
it never will be one.

4
pages/test.yamd Normal file
View file

@ -0,0 +1,4 @@
title: Test page
slug: test
---
This is a test page.

View file

@ -0,0 +1,14 @@
title: Audio output chooser
slug: harbour-audio-output
images:
- harbour-audio-output-1.jpg
platforms:
- Sailfish OS
technologies:
- QML
- pulseaudio
icon: harbour-audio-output.png
description: A simple application to choose the audio output of the system.
---
A simple application to choose the audio output of the system.

12
projects/thiswebsite.yamd Normal file
View file

@ -0,0 +1,12 @@
title: This website
slug: this-website
icon: this-website.png
platforms:
- www
technologies:
- D
- diet
- vibe.d
description: My presence on the interwebs!
---
I made a website! And you're looking at it right now!

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

View file

@ -21,12 +21,23 @@
--colour-fg-highlight: #7f0602; --colour-fg-highlight: #7f0602;
} }
@media (prefers-color-scheme: dark) {
:root {
--colour-bg: #101010;
--colour-bg-main: #333;
--colour-bg-code: #222;
--colour-fg: #ffffff;
--colour-fg-highlight: #fc918d;
}
}
body { body {
background-color: var(--colour-bg); background-color: var(--colour-bg);
margin: 0; margin: 0;
display: flex; display: flex;
justify-content: center; justify-content: center;
min-height: 100vh; min-height: 100vh;
color: var(--colour-fg);
} }
body > nav { body > nav {
@ -67,14 +78,19 @@ h1, .title {
} }
header { header {
border-bottom: 1px dotted black; border-bottom: 1px dotted var(--colour-fg);
padding-top: 0.5em; padding-top: 0.5em;
padding-bottom: 0.5em; padding-bottom: 0.5em;
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
hr {
border: none;
border-top: 1px dotted var(--colour-fg);
}
footer { footer {
border-top: 1px dotted black; border-top: 1px dotted var(--colour-fg);
padding-top: 0.5em; padding-top: 0.5em;
padding-bottom: 0.5em; padding-bottom: 0.5em;
margin-top: 0.5em; margin-top: 0.5em;
@ -85,6 +101,69 @@ nav ul {
list-style: none; list-style: none;
} }
/* PROJECT LIST */
.project-header {
display: flex;
align-items: center;
}
.project-header > div {
flex: 1 1;
}
.project-header > .project-icon {
margin: 0;
margin-right: 0.5em;
}
.project-icon {
width: 4.5em;
height: 4.5em;
float: left;
margin: 0.5em;
margin-left: 0;
}
.platforms-technologies {
margin: 0.5em 0;
}
dl.project-platforms-technologies {
padding: 0.5em 0;
border-top: 1px dotted var(--colour-fg);
border-bottom: 1px dotted var(--colour-fg);
}
.tag {
display: inline-block;
background-color: var(--colour-bg-code);
border-radius: 1em;
font-size: 0.75em;
padding: 0.5em;
margin: 0.25em;
}
.screenshots {
height: 400px;
width: auto;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
@media (max-height: 800px) {
.screenshots {
height: 240px;
}
}
.screenshot {
display: inline-block;
height: 100%;
}
/* MARKDOWN */ /* MARKDOWN */
:not(pre) > code { :not(pre) > code {
@ -92,9 +171,9 @@ nav ul {
padding: 0.2em 0.4em; padding: 0.2em 0.4em;
} }
div.sourceCode, blockquote { div.sourceCode, blockquote, .screenshots {
scrollbar-color: var(--colour-fg) var(--colour-bg-code); scrollbar-color: var(--colour-fg-highlight) var(--colour-bg-code);
scrollbar-width: thin; /*scrollbar-width: thin;*/
background-color: var(--colour-bg-code); background-color: var(--colour-bg-code);
} }
@ -112,6 +191,7 @@ pre, blockquote {
blockquote footer { blockquote footer {
text-align: right; text-align: right;
font-style: italic; font-style: italic;
border: none;
} }
figure { figure {

View file

@ -34,7 +34,7 @@ pre {
background-color: blue; background-color: blue;
} }
blockquote { blockquote, .screenshots, code{
background: #0000ff; background: #0000ff;
border-left: #0000cc 6px solid; border-left: #0000cc 6px solid;
} }

View file

@ -20,9 +20,12 @@ Project[string] projects;
immutable string articleSortPred = "a.firstPublished > b.firstPublished"; immutable string articleSortPred = "a.firstPublished > b.firstPublished";
Article*[] articleList; Article*[] articleList;
immutable string pageSortedPred = "a.title < b.title";
immutable string pageSortPred = "a.title < b.title";
Page*[] pageList; Page*[] pageList;
Project[] projectList;
immutable string projectSortPred = "a.title < b.title";
Project*[] projectList;
enum OutputType { enum OutputType {
HTML, HTML,
@ -95,12 +98,21 @@ void projectGetOverview(HTTPServerRequest req, HTTPServerResponse res) {
* Generate response for a page * Generate response for a page
*/ */
void pageGet(HTTPServerRequest req, HTTPServerResponse res) { void pageGet(HTTPServerRequest req, HTTPServerResponse res) {
// If no slug is supplied, it will be adjusted to "index"
if (("slug" in req.params) is null) { if (("slug" in req.params) is null) {
req.params.addField("slug", "index"); req.params.addField("slug", "index");
} }
getSingle!(Page, "pages/page.dt")(pages, req, res); getSingle!(Page, "pages/page.dt")(pages, req, res);
} }
/**
* Generate response for a project page
*/
void projectGet(HTTPServerRequest req, HTTPServerResponse res) {
res.headers["Cache-Control"] = "public";
getSingle!(Project, "pages/project.dt")(projects, req, res);
}
/** /**
* Generates response whenever an error occurs. * Generates response whenever an error occurs.
*/ */
@ -128,17 +140,21 @@ void main() {
router.get("/posts/", &articleGetOverview); router.get("/posts/", &articleGetOverview);
router.get("/palen/", &articleGetOverview); router.get("/palen/", &articleGetOverview);
router.get("/projects/", &projectGetOverview); router.get("/projects/", &projectGetOverview);
router.get("/projecten/", &projectGetOverview); router.get("/projects/:slug", &projectGet);
router.get("/projecten/:slug", &projectGet);
router.get("/static/*", serveStaticFiles("./public/")); router.get("/static/*", serveStaticFiles("./public/"));
router.get("/:slug", &pageGet); router.get("/:slug", &pageGet);
router.get("/", &pageGet); router.get("/", &pageGet);
listenHTTP(settings, router); listenHTTP(settings, router);
runTask({ runTask({
initPages!(Page, pageSortedPred)(pages, pageList, "pages"); initPages!(Page, pageSortPred)(pages, pageList, "pages");
}); });
runTask({ runTask({
initPages!(Article, articleSortPred)(articles, articleList, "articles"); initPages!(Article, articleSortPred)(articles, articleList, "articles");
}); });
runTask({
initPages!(Project, projectSortPred)(projects, projectList, "projects");
});
runApplication(); runApplication();
} }

View file

@ -5,17 +5,21 @@ import dyaml;
import vibe.vibe; import vibe.vibe;
import page; import page;
import staticpaths;
import utils; import utils;
/** /**
* Represents a project, like an unfinished application * Represents a project, like an unfinished application
*/ */
class Project : Page { class Project : Page {
protected immutable string PROJECT_ICON_DIR = IMG_DIR ~ "projects/icons/";
protected immutable string PROJECT_IMAGE_DIR = IMG_DIR ~ "projects/images/";
protected string m_state; protected string m_state;
protected string[] m_platforms; protected string[] m_platforms;
protected string[] m_technologies; protected string[] m_technologies;
protected string m_icon; protected string m_icon;
protected string[] m_images; protected string[] m_images;
protected string m_description;
/** /**
* Creates a project from a file * Creates a project from a file
@ -28,13 +32,12 @@ class Project : Page {
override protected void loadHeader(Node headerNode) { override protected void loadHeader(Node headerNode) {
super.loadHeader(headerNode); super.loadHeader(headerNode);
this.m_state = headerNode.getOr!string("state", "unknown"); this.m_state = headerNode.getOr!string("state", "unknown");
this.m_platforms = headerNode.getOr!(Node[])("platforms", []) this.m_platforms = headerNode.getArray!string("platforms", []);
.map!(x => x.get!string).array; this.m_technologies = headerNode.getArray!string("technologies", []);
this.m_technologies = headerNode.getOr!(Node[])("technologies", []) this.m_icon = PROJECT_ICON_DIR ~ headerNode.getOr!string("icon", "");
.map!(x => x.get!string).array; this.m_images = headerNode.getArray!string("images", [])
this.m_icon = headerNode.getOr!string("icon", ""); .map!(x => PROJECT_IMAGE_DIR ~ x).array;
this.m_images = headerNode.getOr!(Node[])("images", []) this.m_description = headerNode.getOr!string("description", "<no description>");
.map!(x => x.get!string).array;
} }
@property string state() { return m_state; } @property string state() { return m_state; }
@ -42,5 +45,6 @@ class Project : Page {
@property string[] technologies() { return m_technologies; } @property string[] technologies() { return m_technologies; }
@property string icon() { return m_icon; } @property string icon() { return m_icon; }
@property string[] images() { return m_images; } @property string[] images() { return m_images; }
@property string description() { return m_description; }
} }

2
source/staticpaths.d Normal file
View file

@ -0,0 +1,2 @@
immutable string STATIC_DIR = "/static/";
immutable string IMG_DIR = STATIC_DIR ~ "img/";

View file

@ -1,3 +1,5 @@
import std.algorithm;
import std.array;
import std.conv; import std.conv;
import std.datetime; import std.datetime;
@ -14,3 +16,12 @@ T getOr(T)(Node node, string key, T or) {
return or; return or;
} }
} }
T[] getArray(T)(Node node, string key, T[] or = []) {
try {
return node.getOr!(Node[])(key, [])
.map!(x => x.as!T).array;
} catch (NodeException e) {
return or;
}
}

View file

@ -8,5 +8,5 @@ block sidebar
block content block content
header header
h1.title #{error.message} h1.title #{error.message} (#{error.code})
p #{error.debugMessage} pre #{error.debugMessage}

View file

@ -9,4 +9,4 @@ block sidebar
block content block content
header header
h1.title #{content.title} h1.title #{content.title}
| !{content.content} section !{content.content}

View file

@ -9,17 +9,20 @@ block sidebar
block content block content
header header
h1.title Projects h1.title Projects
p Note: I'm not a graphic designer, so please ignore the icons. p Since I'm not a graphic designer, I'd like you to pretend the abominations are actually icons.
- if (projectList.length == 0) - if (projectList.length == 0)
p No projects found p No projects found
- foreach(project; projectList) - foreach(project; projectList)
div.project section.project-header
img(src="#{project.icon}") img.project-icon(src="#{project.icon}", alt="Icon of #{project.title}")
h2 #{project.title} div
p.platforms a(href="/projects/#{project.slug}", rel="bookmark")
h2.title #{project.title}
div.platforms-technologies
- foreach(platform; project.platforms) - foreach(platform; project.platforms)
span.platform #{platform} span.tag #{platform}
p.technologies | |
- foreach(technology; project.technologies) - foreach(technology; project.technologies)
span.platform #{technology} span.tag #{technology}
p.project-description #{project.description}

32
views/pages/project.dt Normal file
View file

@ -0,0 +1,32 @@
extends /parts/page
block header
title #{content.title} - Netsoj.nl
block sidebar
include /parts/menu.dt
block content
section
header.project-header
img.project-icon(src="#{content.icon}", alt="Icon of #{content.title}")
div
h1.title #{content.title}
span.project-description #{content.description}
- if (content.images.length > 0)
div.screenshots
- foreach(image; content.images)
a(href="#{image}")
img.screenshot(src="#{image}", alt="Image of #{content.title}")
p
i To easily scroll horizontally on a desktop, hold shift while using the scroll wheel
- else
p
i This project has no images.
dl.project-platforms-technologies
dt Platforms
- foreach(platform; content.platforms)
dd.tag #{platform}
dt Technologies
- foreach(technology; content.technologies)
dd.tag #{technology}
| !{content.content}

View file

@ -3,7 +3,7 @@
a(href="#{link}") #{text} a(href="#{link}") #{text}
header header
img.logo(src="/static/img/logo.png") img.logo(src="/static/img/logo.png", alt="The logo of the website: the letter C drawn in an inprofessional manner with wobbley eyes on top")
p Chris's webstekkie p Chris's webstekkie
ul ul
- menuItem("home", "/"); - menuItem("home", "/");