diff options
Diffstat (limited to 'web/homepage')
-rw-r--r-- | web/homepage/default.nix | 76 | ||||
-rw-r--r-- | web/homepage/entries.nix | 47 | ||||
-rw-r--r-- | web/homepage/footer.html | 2 | ||||
-rw-r--r-- | web/homepage/header.html | 35 | ||||
-rw-r--r-- | web/homepage/nginx.nix | 79 | ||||
-rw-r--r-- | web/homepage/static/favicon.webp | bin | 0 -> 11554 bytes | |||
-rw-r--r-- | web/homepage/static/jetbrains-mono-bold-italic.woff2 | bin | 0 -> 53364 bytes | |||
-rw-r--r-- | web/homepage/static/jetbrains-mono-bold.woff2 | bin | 0 -> 49892 bytes | |||
-rw-r--r-- | web/homepage/static/jetbrains-mono-italic.woff2 | bin | 0 -> 50936 bytes | |||
-rw-r--r-- | web/homepage/static/jetbrains-mono.woff2 | bin | 0 -> 48700 bytes | |||
-rw-r--r-- | web/homepage/static/tazjin.css | 142 |
11 files changed, 381 insertions, 0 deletions
diff --git a/web/homepage/default.nix b/web/homepage/default.nix new file mode 100644 index 000000000000..d2905a7eb6ca --- /dev/null +++ b/web/homepage/default.nix @@ -0,0 +1,76 @@ +# Assembles the website index and configures an nginx instance to +# serve it. +# +# The website is made up of a simple header&footer and content +# elements for things such as blog posts and projects. +# +# Content for the blog is in //web/blog instead of here. +{ pkgs, lib, ... }: + +with pkgs; +with nix.yants; + +let + inherit (builtins) readFile replaceStrings sort; + inherit (third_party) writeFile runCommandNoCC; + + # The different types of entries on the homepage. + entryClass = enum "entryClass" [ "blog" "project" "misc" ]; + + # The definition of a single entry. + entry = struct "entry" { + class = entryClass; + title = string; + url = string; + date = int; # epoch + description = option string; + }; + + escape = replaceStrings [ "<" ">" "&" "'" ] [ "<" ">" "&" "'" ]; + + postToEntry = defun [ web.blog.post entry ] (post: { + class = "blog"; + title = post.title; + url = "/blog/${post.key}"; + date = post.date; + }); + + formatDate = defun [ int string ] (date: readFile (runCommandNoCC "date" {} '' + date --date='@${toString date}' '+%Y-%m-%d' > $out + '')); + + formatEntryDate = defun [ entry string ] (entry: entryClass.match entry.class { + blog = "Blog post from ${formatDate entry.date}"; + project = "Project from ${formatDate entry.date}"; + misc = "Posted on ${formatDate entry.date}"; + }); + + entryToDiv = defun [ entry string ] (entry: '' + <a href="${entry.url}" class="entry ${entry.class}"> + <div> + <p class="entry-title">${escape entry.title}</p> + ${ + lib.optionalString ((entry ? description) && (entry.description != null)) + "<p class=\"entry-description\">${escape entry.description}</p>" + } + <p class="entry-date">${formatEntryDate entry}</p> + </div> + </a> + ''); + + index = entries: third_party.writeText "index.html" (lib.concatStrings ( + [ (builtins.readFile ./header.html) ] + ++ (map entryToDiv (sort (a: b: a.date > b.date) entries)) + ++ [ (builtins.readFile ./footer.html) ] + )); + + homepage = index ((map postToEntry web.blog.posts) ++ (import ./entries.nix)); + website = runCommandNoCC "website" {} '' + mkdir $out + cp ${homepage} $out/index.html + cp -r ${./static} $out/static + ''; +in third_party.callPackage ./nginx.nix { + inherit website; + blog = web.blog; +} diff --git a/web/homepage/entries.nix b/web/homepage/entries.nix new file mode 100644 index 000000000000..d204090330ef --- /dev/null +++ b/web/homepage/entries.nix @@ -0,0 +1,47 @@ +[ + { + class = "project"; + title = "depot"; + url = "https://git.tazj.in/about"; + date = 1576800000; + description = "Merging all of my projects into a single, Nix-based monorepo"; + } + { + class = "project"; + title = "Nixery"; + url = "https://github.com/google/nixery"; + date = 1565132400; + description = "A Nix-backed container registry that builds container images on demand"; + } + { + class = "project"; + title = "kontemplate"; + url = "https://git.tazj.in/about/ops/kontemplate"; + date = 1486550940; + description = "Simple file templating tool built for Kubernetes resources"; + } + { + class = "misc"; + title = "dottime"; + url = "https://dotti.me/"; + date = 1560898800; + description = "A universal convention for conveying time (by edef <3)"; + } + { + class = "project"; + title = "journaldriver"; + url = "https://git.tazj.in/about/ops/journaldriver"; + date = 1527375600; + description = "Small daemon to forward logs from journald to Stackdriver Logging"; + } + { + class = "misc"; + title = "Principia Discordia"; + url = "https://principiadiscordia.com/book/1.php"; + date = 1495494000; + description = '' + The Principia is a short book I read as a child, and didn't + understand until much later. It shaped much of my world view. + ''; + } +] diff --git a/web/homepage/footer.html b/web/homepage/footer.html new file mode 100644 index 000000000000..2f17135066e8 --- /dev/null +++ b/web/homepage/footer.html @@ -0,0 +1,2 @@ + </div> +</body> diff --git a/web/homepage/header.html b/web/homepage/header.html new file mode 100644 index 000000000000..ec81fa04dc05 --- /dev/null +++ b/web/homepage/header.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<head><meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="description" content="tazjin's blog"> + <link rel="stylesheet" type="text/css" href="static/tazjin.css" media="all"> + <link rel="icon" type="image/webp" href="/static/favicon.webp"> + <title>tazjin's interblag</title> +</head> +<body class="dark"> + <header> + <h1> + <a class="interblag-title" href="/">tazjin's interblag</a> + </h1> + <hr> + </header> + <div class="introduction"> + <p>Hello, illuminated visitor.</p> + <p> + I'm tazjin. Usually you can find + me <a class="dark-link" href="https://git.tazj.in/about">programming computers</a> + using tools such as <a class="dark-link" href="https://nixos.org/nix">Nix</a> + and <a class="dark-link" href="https://www.gnu.org/software/emacs/">Emacs</a>, + cuddling <a class="dark-link" href="https://twitter.com/edefic">people I love</a> + or posting nonsense <a class="dark-link" href="https://twitter.com/tazjin">on the + internet</a>. + </p> + <p> + Below is a collection of + my <span class="project">projects</span>, <span class="blog">blog + posts</span> and some <span class="misc">random things</span> by + me or others. If you'd like to get in touch about anything, send + me a mail at mail@[this domain] or ping me on IRC or Twitter. + </p> + </div> + <div class="entry-container"> diff --git a/web/homepage/nginx.nix b/web/homepage/nginx.nix new file mode 100644 index 000000000000..100c0cc9ee3a --- /dev/null +++ b/web/homepage/nginx.nix @@ -0,0 +1,79 @@ +# This file creates an nginx server that serves the blog on port 8080. +# +# It's not intended to be the user-facing nginx. +{ + # third_party attributes supplied by callPackage + writeText, writeShellScriptBin, nginx, lib, + + # website content + blog, website +}: + +let + inherit (builtins) hasAttr filter map; + inherit (pkgs.third_party) ; + + oldRedirects = lib.concatStringsSep "\n" (map (post: '' + location ~* ^(/en)?/${post.oldKey} { + # TODO(tazjin): 301 once this works + return 302 https://tazj.in/blog/${post.key}; + } + '') (filter (hasAttr "oldKey") blog.posts)); + + config = writeText "homepage-nginx.conf" '' + daemon off; + worker_processes 1; + error_log stderr; + pid /tmp/nginx-homepage.pid; + + events { + worker_connections 1024; + } + + http { + include ${nginx}/conf/mime.types; + fastcgi_temp_path /tmp/nginx-homepage; + uwsgi_temp_path /tmp/nginx-homepage; + scgi_temp_path /tmp/nginx-homepage; + client_body_temp_path /tmp/nginx-homepage; + proxy_temp_path /tmp/nginx-homepage; + sendfile on; + + # Logging is handled by the primary nginx server + access_log off; + + server { + listen 8080 default_server; + server_name tazj.in; + root ${website}; + + ${oldRedirects} + + location /blog { + alias ${blog.rendered}; + + if ($request_uri ~ ^/(.*)\.html$) { + return 302 /$1; + } + + try_files $uri $uri.html $uri/ =404; + } + } + + server { + listen 8080; + server_name www.tazj.in; + return 301 https://tazj.in$request_uri; + } + } + ''; +in writeShellScriptBin "homepage" '' + if [[ -v CONTAINER_SETUP ]]; then + cd /run + echo 'nogroup:x:30000:nobody' >> /etc/group + echo 'nobody:x:30000:30000:nobody:/tmp:/bin/bash' >> /etc/passwd + fi + + mkdir -p /tmp/nginx-homepage + exec ${nginx}/bin/nginx -c ${config} +'' diff --git a/web/homepage/static/favicon.webp b/web/homepage/static/favicon.webp new file mode 100644 index 000000000000..f99c9085340b --- /dev/null +++ b/web/homepage/static/favicon.webp Binary files differdiff --git a/web/homepage/static/jetbrains-mono-bold-italic.woff2 b/web/homepage/static/jetbrains-mono-bold-italic.woff2 new file mode 100644 index 000000000000..34b5c69ae1cf --- /dev/null +++ b/web/homepage/static/jetbrains-mono-bold-italic.woff2 Binary files differdiff --git a/web/homepage/static/jetbrains-mono-bold.woff2 b/web/homepage/static/jetbrains-mono-bold.woff2 new file mode 100644 index 000000000000..84a008af7edb --- /dev/null +++ b/web/homepage/static/jetbrains-mono-bold.woff2 Binary files differdiff --git a/web/homepage/static/jetbrains-mono-italic.woff2 b/web/homepage/static/jetbrains-mono-italic.woff2 new file mode 100644 index 000000000000..85fd4687891e --- /dev/null +++ b/web/homepage/static/jetbrains-mono-italic.woff2 Binary files differdiff --git a/web/homepage/static/jetbrains-mono.woff2 b/web/homepage/static/jetbrains-mono.woff2 new file mode 100644 index 000000000000..d5b94cb9e7db --- /dev/null +++ b/web/homepage/static/jetbrains-mono.woff2 Binary files differdiff --git a/web/homepage/static/tazjin.css b/web/homepage/static/tazjin.css new file mode 100644 index 000000000000..68e72577c37a --- /dev/null +++ b/web/homepage/static/tazjin.css @@ -0,0 +1,142 @@ +/* Jetbrains Mono font from https://www.jetbrains.com/lp/mono/ + licensed under Apache 2.0. Thanks, Jetbrains! */ +@font-face { + font-family: jetbrains-mono; + src: url(jetbrains-mono.woff2); +} + +@font-face { + font-family: jetbrains-mono; + font-weight: bold; + src: url(jetbrains-mono-bold.woff2); +} + +@font-face { + font-family: jetbrains-mono; + font-style: italic; + src: url(jetbrains-mono-italic.woff2); +} + +@font-face { + font-family: jetbrains-mono; + font-weight: bold; + font-style: italic; + src: url(jetbrains-mono-bold-italic.woff2); +} + +/* Generic-purpose styling */ + +body { + margin: 40px auto; + line-height: 1.6; + font-size: 18px; + padding: 0 10px; + font-family: jetbrains-mono, monospace; +} + +p, a :not(.uncoloured-link) { + color: inherit; +} + +h1, h2, h3 { + line-height: 1.2 +} + +/* Homepage styling */ + +.dark { + max-width: 800px; + background-color: #181818; + color: #e4e4ef; +} + +.dark-link, .interblag-title { + color: #96a6c8; +} + +.entry-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; +} + +.interblag-title { + text-decoration: none; +} + +.entry { + width: 42%; + margin: 5px; + padding-left: 7px; + padding-right: 5px; + border: 2px solid; + border-radius: 5px; + flex-grow: 1; + text-decoration: none; +} + +.misc { + color: #268bd2; + border-color: #268bd2; +} + +.project { + color: #9e95c7; + border-color: #9e95c7; +} + +.blog { + color: #95a99f; + border-color: #95a99f; +} + +.entry-title { + color: inherit !important; + font-weight: bold; + text-decoration: none; +} + +.entry-date { + font-style: italic; +} + +/* Blog styling */ + +.light { + max-width: 650px; + color: #383838; +} + +.blog-title { + color: inherit; + text-decoration: none; +} + +.footer { + text-align: right; +} + +.date { + text-align: right; + font-style: italic; + float: right; +} + +.inline { + display: inline; +} + +.lod { + text-align: center; +} + +pre { + min-width: 100%; + /* some code snippets escape to the side, but I don't want to wrap them */ + width: max-content; +} + +img { + max-width: 100%; +} |