Added content, projects and dark mode
This commit is contained in:
parent
4a9cfda0bd
commit
e1b43bc4c3
42
articles/hello-world.yamd
Normal file
42
articles/hello-world.yamd
Normal 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
3
articles/hi.yamd
Normal file
|
@ -0,0 +1,3 @@
|
|||
title: "chris"
|
||||
---
|
||||
Yet another article. How boring.
|
8
articles/second.yamd
Normal file
8
articles/second.yamd
Normal 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
5
pages/contact.yamd
Normal 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
1
pages/foo/bar
Normal file
|
@ -0,0 +1 @@
|
|||
Hi
|
12
pages/index.yamd
Normal file
12
pages/index.yamd
Normal file
|
@ -0,0 +1,12 @@
|
|||
title: Home
|
||||
slug: index
|
||||
---
|
||||
I am Chris Josten — you might have guessed it from the url — 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
4
pages/test.yamd
Normal file
|
@ -0,0 +1,4 @@
|
|||
title: Test page
|
||||
slug: test
|
||||
---
|
||||
This is a test page.
|
14
projects/harbour-audio-output.md
Normal file
14
projects/harbour-audio-output.md
Normal 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
12
projects/thiswebsite.yamd
Normal 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!
|
BIN
public/static/img/projects/icons/harbour-audio-output.png
Normal file
BIN
public/static/img/projects/icons/harbour-audio-output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5 KiB |
BIN
public/static/img/projects/icons/this-website.png
Normal file
BIN
public/static/img/projects/icons/this-website.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
public/static/img/projects/images/harbour-audio-output-1.jpg
Normal file
BIN
public/static/img/projects/images/harbour-audio-output-1.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
|
@ -21,12 +21,23 @@
|
|||
--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 {
|
||||
background-color: var(--colour-bg);
|
||||
margin: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
color: var(--colour-fg);
|
||||
}
|
||||
|
||||
body > nav {
|
||||
|
@ -67,14 +78,19 @@ h1, .title {
|
|||
}
|
||||
|
||||
header {
|
||||
border-bottom: 1px dotted black;
|
||||
border-bottom: 1px dotted var(--colour-fg);
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px dotted var(--colour-fg);
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top: 1px dotted black;
|
||||
border-top: 1px dotted var(--colour-fg);
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
|
@ -85,6 +101,69 @@ nav ul {
|
|||
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 */
|
||||
|
||||
:not(pre) > code {
|
||||
|
@ -92,9 +171,9 @@ nav ul {
|
|||
padding: 0.2em 0.4em;
|
||||
}
|
||||
|
||||
div.sourceCode, blockquote {
|
||||
scrollbar-color: var(--colour-fg) var(--colour-bg-code);
|
||||
scrollbar-width: thin;
|
||||
div.sourceCode, blockquote, .screenshots {
|
||||
scrollbar-color: var(--colour-fg-highlight) var(--colour-bg-code);
|
||||
/*scrollbar-width: thin;*/
|
||||
background-color: var(--colour-bg-code);
|
||||
}
|
||||
|
||||
|
@ -112,6 +191,7 @@ pre, blockquote {
|
|||
blockquote footer {
|
||||
text-align: right;
|
||||
font-style: italic;
|
||||
border: none;
|
||||
}
|
||||
|
||||
figure {
|
||||
|
|
|
@ -34,7 +34,7 @@ pre {
|
|||
background-color: blue;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
blockquote, .screenshots, code{
|
||||
background: #0000ff;
|
||||
border-left: #0000cc 6px solid;
|
||||
}
|
||||
|
|
24
source/app.d
24
source/app.d
|
@ -20,9 +20,12 @@ Project[string] projects;
|
|||
|
||||
immutable string articleSortPred = "a.firstPublished > b.firstPublished";
|
||||
Article*[] articleList;
|
||||
immutable string pageSortedPred = "a.title < b.title";
|
||||
|
||||
immutable string pageSortPred = "a.title < b.title";
|
||||
Page*[] pageList;
|
||||
Project[] projectList;
|
||||
|
||||
immutable string projectSortPred = "a.title < b.title";
|
||||
Project*[] projectList;
|
||||
|
||||
enum OutputType {
|
||||
HTML,
|
||||
|
@ -95,12 +98,21 @@ void projectGetOverview(HTTPServerRequest req, HTTPServerResponse res) {
|
|||
* Generate response for a page
|
||||
*/
|
||||
void pageGet(HTTPServerRequest req, HTTPServerResponse res) {
|
||||
// If no slug is supplied, it will be adjusted to "index"
|
||||
if (("slug" in req.params) is null) {
|
||||
req.params.addField("slug", "index");
|
||||
}
|
||||
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.
|
||||
*/
|
||||
|
@ -128,17 +140,21 @@ void main() {
|
|||
router.get("/posts/", &articleGetOverview);
|
||||
router.get("/palen/", &articleGetOverview);
|
||||
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("/:slug", &pageGet);
|
||||
router.get("/", &pageGet);
|
||||
|
||||
listenHTTP(settings, router);
|
||||
runTask({
|
||||
initPages!(Page, pageSortedPred)(pages, pageList, "pages");
|
||||
initPages!(Page, pageSortPred)(pages, pageList, "pages");
|
||||
});
|
||||
runTask({
|
||||
initPages!(Article, articleSortPred)(articles, articleList, "articles");
|
||||
});
|
||||
runTask({
|
||||
initPages!(Project, projectSortPred)(projects, projectList, "projects");
|
||||
});
|
||||
runApplication();
|
||||
}
|
||||
|
|
|
@ -5,17 +5,21 @@ import dyaml;
|
|||
import vibe.vibe;
|
||||
|
||||
import page;
|
||||
import staticpaths;
|
||||
import utils;
|
||||
|
||||
/**
|
||||
* Represents a project, like an unfinished application
|
||||
*/
|
||||
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_platforms;
|
||||
protected string[] m_technologies;
|
||||
protected string m_icon;
|
||||
protected string[] m_images;
|
||||
protected string m_description;
|
||||
|
||||
/**
|
||||
* Creates a project from a file
|
||||
|
@ -28,13 +32,12 @@ class Project : Page {
|
|||
override protected void loadHeader(Node headerNode) {
|
||||
super.loadHeader(headerNode);
|
||||
this.m_state = headerNode.getOr!string("state", "unknown");
|
||||
this.m_platforms = headerNode.getOr!(Node[])("platforms", [])
|
||||
.map!(x => x.get!string).array;
|
||||
this.m_technologies = headerNode.getOr!(Node[])("technologies", [])
|
||||
.map!(x => x.get!string).array;
|
||||
this.m_icon = headerNode.getOr!string("icon", "");
|
||||
this.m_images = headerNode.getOr!(Node[])("images", [])
|
||||
.map!(x => x.get!string).array;
|
||||
this.m_platforms = headerNode.getArray!string("platforms", []);
|
||||
this.m_technologies = headerNode.getArray!string("technologies", []);
|
||||
this.m_icon = PROJECT_ICON_DIR ~ headerNode.getOr!string("icon", "");
|
||||
this.m_images = headerNode.getArray!string("images", [])
|
||||
.map!(x => PROJECT_IMAGE_DIR ~ x).array;
|
||||
this.m_description = headerNode.getOr!string("description", "<no description>");
|
||||
}
|
||||
|
||||
@property string state() { return m_state; }
|
||||
|
@ -42,5 +45,6 @@ class Project : Page {
|
|||
@property string[] technologies() { return m_technologies; }
|
||||
@property string icon() { return m_icon; }
|
||||
@property string[] images() { return m_images; }
|
||||
@property string description() { return m_description; }
|
||||
|
||||
}
|
||||
|
|
2
source/staticpaths.d
Normal file
2
source/staticpaths.d
Normal file
|
@ -0,0 +1,2 @@
|
|||
immutable string STATIC_DIR = "/static/";
|
||||
immutable string IMG_DIR = STATIC_DIR ~ "img/";
|
|
@ -1,3 +1,5 @@
|
|||
import std.algorithm;
|
||||
import std.array;
|
||||
import std.conv;
|
||||
import std.datetime;
|
||||
|
||||
|
@ -14,3 +16,12 @@ T getOr(T)(Node node, string key, T 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,5 @@ block sidebar
|
|||
|
||||
block content
|
||||
header
|
||||
h1.title #{error.message}
|
||||
p #{error.debugMessage}
|
||||
h1.title #{error.message} (#{error.code})
|
||||
pre #{error.debugMessage}
|
||||
|
|
|
@ -9,4 +9,4 @@ block sidebar
|
|||
block content
|
||||
header
|
||||
h1.title #{content.title}
|
||||
| !{content.content}
|
||||
section !{content.content}
|
||||
|
|
|
@ -9,17 +9,20 @@ block sidebar
|
|||
block content
|
||||
header
|
||||
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)
|
||||
p No projects found
|
||||
- foreach(project; projectList)
|
||||
div.project
|
||||
img(src="#{project.icon}")
|
||||
h2 #{project.title}
|
||||
p.platforms
|
||||
- foreach(platform; project.platforms)
|
||||
span.platform #{platform}
|
||||
p.technologies
|
||||
- foreach(technology; project.technologies)
|
||||
span.platform #{technology}
|
||||
section.project-header
|
||||
img.project-icon(src="#{project.icon}", alt="Icon of #{project.title}")
|
||||
div
|
||||
a(href="/projects/#{project.slug}", rel="bookmark")
|
||||
h2.title #{project.title}
|
||||
div.platforms-technologies
|
||||
- foreach(platform; project.platforms)
|
||||
span.tag #{platform}
|
||||
| |
|
||||
- foreach(technology; project.technologies)
|
||||
span.tag #{technology}
|
||||
p.project-description #{project.description}
|
||||
|
||||
|
|
32
views/pages/project.dt
Normal file
32
views/pages/project.dt
Normal 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}
|
|
@ -3,7 +3,7 @@
|
|||
a(href="#{link}") #{text}
|
||||
|
||||
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
|
||||
ul
|
||||
- menuItem("home", "/");
|
||||
|
|
Loading…
Reference in a new issue