diff --git a/articles/hello-world.yamd b/articles/hello-world.yamd new file mode 100644 index 0000000..0c33e8e --- /dev/null +++ b/articles/hello-world.yamd @@ -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 +> + +` +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} + + + + This is supposed to be such a large title that the page has to scroll + + +``` diff --git a/articles/hi.yamd b/articles/hi.yamd new file mode 100644 index 0000000..83a65b6 --- /dev/null +++ b/articles/hi.yamd @@ -0,0 +1,3 @@ +title: "chris" +--- +Yet another article. How boring. diff --git a/articles/second.yamd b/articles/second.yamd new file mode 100644 index 0000000..49b90d7 --- /dev/null +++ b/articles/second.yamd @@ -0,0 +1,8 @@ +title: Second! +author: Chris Josten +slug: second +--- +Hi there, lovely people! + +# Test +![Foo bar](/static/img/logo.png) diff --git a/pages/contact.yamd b/pages/contact.yamd new file mode 100644 index 0000000..7d79043 --- /dev/null +++ b/pages/contact.yamd @@ -0,0 +1,5 @@ +title: Contact +slug: contact +--- +If you want to contact me, you are able to reach me at . +Hopefully that obfuscated address will diff --git a/pages/foo/bar b/pages/foo/bar new file mode 100644 index 0000000..b14df64 --- /dev/null +++ b/pages/foo/bar @@ -0,0 +1 @@ +Hi diff --git a/pages/index.yamd b/pages/index.yamd new file mode 100644 index 0000000..106a6da --- /dev/null +++ b/pages/index.yamd @@ -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. diff --git a/pages/test.yamd b/pages/test.yamd new file mode 100644 index 0000000..47c19f3 --- /dev/null +++ b/pages/test.yamd @@ -0,0 +1,4 @@ +title: Test page +slug: test +--- +This is a test page. diff --git a/projects/harbour-audio-output.md b/projects/harbour-audio-output.md new file mode 100644 index 0000000..8c1cdc9 --- /dev/null +++ b/projects/harbour-audio-output.md @@ -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. + diff --git a/projects/thiswebsite.yamd b/projects/thiswebsite.yamd new file mode 100644 index 0000000..0dbcf52 --- /dev/null +++ b/projects/thiswebsite.yamd @@ -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! diff --git a/public/static/img/projects/icons/harbour-audio-output.png b/public/static/img/projects/icons/harbour-audio-output.png new file mode 100644 index 0000000..e6fb5f3 Binary files /dev/null and b/public/static/img/projects/icons/harbour-audio-output.png differ diff --git a/public/static/img/projects/icons/this-website.png b/public/static/img/projects/icons/this-website.png new file mode 100644 index 0000000..f54657c Binary files /dev/null and b/public/static/img/projects/icons/this-website.png differ diff --git a/public/static/img/projects/images/harbour-audio-output-1.jpg b/public/static/img/projects/images/harbour-audio-output-1.jpg new file mode 100644 index 0000000..6621985 Binary files /dev/null and b/public/static/img/projects/images/harbour-audio-output-1.jpg differ diff --git a/public/static/style/base.css b/public/static/style/base.css index 59ba300..5edf08c 100644 --- a/public/static/style/base.css +++ b/public/static/style/base.css @@ -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 { diff --git a/public/static/style/old.css b/public/static/style/old.css index aa1e938..57f7e54 100644 --- a/public/static/style/old.css +++ b/public/static/style/old.css @@ -34,7 +34,7 @@ pre { background-color: blue; } -blockquote { +blockquote, .screenshots, code{ background: #0000ff; border-left: #0000cc 6px solid; } diff --git a/source/app.d b/source/app.d index ec386fe..840999e 100644 --- a/source/app.d +++ b/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(); } diff --git a/source/project.d b/source/project.d index f72aa55..b22dd66 100644 --- a/source/project.d +++ b/source/project.d @@ -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", ""); } @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; } } diff --git a/source/staticpaths.d b/source/staticpaths.d new file mode 100644 index 0000000..2d068b4 --- /dev/null +++ b/source/staticpaths.d @@ -0,0 +1,2 @@ +immutable string STATIC_DIR = "/static/"; +immutable string IMG_DIR = STATIC_DIR ~ "img/"; diff --git a/source/utils.d b/source/utils.d index 101b592..174a637 100644 --- a/source/utils.d +++ b/source/utils.d @@ -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; + } +} diff --git a/views/pages/error.dt b/views/pages/error.dt index d3acbaa..9aa5ae5 100644 --- a/views/pages/error.dt +++ b/views/pages/error.dt @@ -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} diff --git a/views/pages/page.dt b/views/pages/page.dt index 5619445..1b102c0 100644 --- a/views/pages/page.dt +++ b/views/pages/page.dt @@ -9,4 +9,4 @@ block sidebar block content header h1.title #{content.title} - | !{content.content} + section !{content.content} diff --git a/views/pages/project-list.dt b/views/pages/project-list.dt index d01c28c..cdbe170 100644 --- a/views/pages/project-list.dt +++ b/views/pages/project-list.dt @@ -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} diff --git a/views/pages/project.dt b/views/pages/project.dt new file mode 100644 index 0000000..009ae36 --- /dev/null +++ b/views/pages/project.dt @@ -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} diff --git a/views/parts/menu.dt b/views/parts/menu.dt index 147563d..695bd47 100644 --- a/views/parts/menu.dt +++ b/views/parts/menu.dt @@ -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", "/");