Skip to content

Commit 763fd19

Browse files
committed
Updated blog
1 parent 29edefd commit 763fd19

19 files changed

Lines changed: 1002 additions & 763 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ _site/
33
.jekyll-metadata
44
.DS_Store
55
*.swp
6+
7+
# local dev
8+
vendor/
9+
.bundle/

.tool-versions

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Matches the Ruby that GitHub Pages builds this site with.
2+
# Sourced from https://pages.github.com/versions.json (github-pages 232 -> ruby 3.3.4).
3+
# If you bump github-pages, re-check that endpoint and update this to match.
4+
#
5+
# This is not cosmetic: github-pages 232 depends on commonmarker, which requires
6+
# Ruby >= 2.6, < 4.0. On Ruby 4.x `bundle install` fails to resolve at all.
7+
#
8+
# Works with asdf and mise.
9+
ruby 3.3.4

Gemfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@ require 'open-uri'
77
versions = JSON.parse(::URI.open('https://pages.github.com/versions.json').read)
88
gem 'github-pages', versions['github-pages']
99

10-
# addons
11-
gem 'jekyll-paginate'
1210

Gemfile.lock

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ PLATFORMS
275275

276276
DEPENDENCIES
277277
github-pages (= 232)
278-
jekyll-paginate
279278

280279
BUNDLED WITH
281-
2.2.16
280+
2.5.23

README.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,47 @@
11
# databyte #
22

3+
Source for [davidsommers.com](https://davidsommers.com), built with Jekyll and
4+
published by GitHub Pages.
5+
36
## Setup
47

8+
Ruby is pinned in [`.tool-versions`](.tool-versions) to match the version
9+
GitHub Pages builds with. With [mise](https://mise.jdx.dev) or
10+
[asdf](https://asdf-vm.com) installed, `cd` into this repo and:
11+
512
````
6-
bundle
7-
jekyll serve
13+
mise install # or: asdf install
14+
bundle install
15+
bundle exec jekyll serve
816
````
917

18+
Then open <http://localhost:4000>. Edits to `_posts/`, `_layouts/`, `css/`, and
19+
`index.html` rebuild automatically.
20+
21+
The pin is load-bearing: `github-pages` depends on `commonmarker`, which
22+
requires Ruby `< 4.0`. On a newer Ruby, `bundle install` fails to resolve at
23+
all. Use `bundle exec` rather than a bare `jekyll`, so you get the pinned
24+
version rather than whatever is on `PATH`.
25+
26+
## Layout
27+
28+
| Path | What |
29+
|---|---|
30+
| `_posts/` | Posts. `YYYY-MM-DD-slug.md` (or `.html` for the older ones). |
31+
| `_layouts/` | `default.html` is the shell; `post.html` wraps a single post. |
32+
| `css/main.css` | The whole stylesheet, including both themes and syntax highlighting. |
33+
| `index.html` | The archive, grouped by year. |
34+
35+
## Theming
36+
37+
Light and dark are both defined in `css/main.css` as custom properties. Dark
38+
follows the reader's OS by default; the header toggle overrides it and stores
39+
the choice in `localStorage`. An inline script in `_layouts/default.html` applies
40+
the stored theme before first paint — keep it inline and above the stylesheet, or
41+
dark-mode readers get a white flash on every page load.
42+
1043
## Links
1144

1245
* [Jekyll](https://jekyllrb.com/)
46+
* [GitHub Pages dependency versions](https://pages.github.com/versions.json)
47+
the source of truth for the Ruby pin.

_config.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ kramdown:
99
permalink: /:year/:month/:day/:title.html
1010
excerpt_separator: ""
1111

12-
google_analytics_id: UA-12936734-2
1312
#google_site_verification: google96ddd296d137fe13
1413

1514
timezone: America/New_York
@@ -19,13 +18,12 @@ collections:
1918
output: true
2019

2120
name: David Sommers Blog
22-
description: My blog
23-
url: http://davidsommers.com
24-
25-
paginate: 3
21+
description: >-
22+
David Sommers on software engineering, web performance, and the occasional
23+
yak shave.
24+
url: https://davidsommers.com
2625

2726
plugins:
28-
- jekyll-paginate
2927
- jekyll-mentions
3028
- jemoji
3129
- jekyll-redirect-from

_layouts/default.html

Lines changed: 90 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,104 @@
11
<!DOCTYPE html>
2-
<html>
2+
<html lang="en">
33
<head>
4-
<meta charset='utf-8'>
5-
<meta http-equiv="X-UA-Compatible" content="chrome=1">
6-
<link href='https://fonts.googleapis.com/css?family=Chivo:900' rel='stylesheet' type='text/css'>
7-
<link rel="stylesheet" type="text/css" href="/css/stylesheet.css" media="screen" />
8-
<link rel="stylesheet" type="text/css" href="/css/github.css" media="screen" />
9-
<link rel="stylesheet" type="text/css" href="/css/custom.css" media="screen" />
10-
<link rel="stylesheet" type="text/css" href="/css/print.css" media="print" />
11-
<!--[if lt IE 9]>
12-
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13-
<![endif]-->
14-
<title>./databyte / {{ page.title }}</title>
4+
<meta charset="utf-8">
5+
<!-- Without this, phones fall back to a 980px layout viewport, the
6+
max-width:767px breakpoint never fires, and the page renders at ~38%. -->
7+
<meta name="viewport" content="width=device-width, initial-scale=1">
8+
9+
{% assign has_title = false %}
10+
{% if page.title and page.title != '' %}{% assign has_title = true %}{% endif %}
11+
{% if has_title %}
12+
<title>{{ page.title | strip_html }} · ./databyte</title>
13+
{% else %}
14+
<title>./databyte · David Sommers</title>
15+
{% endif %}
16+
17+
{% assign desc = page.description | default: site.description %}
18+
<meta name="description" content="{{ desc | strip_html | strip_newlines | truncate: 160 }}">
19+
<link rel="canonical" href="{{ page.url | absolute_url }}">
20+
21+
<meta property="og:type" content="{% if page.date %}article{% else %}website{% endif %}">
22+
<meta property="og:title" content="{% if has_title %}{{ page.title | strip_html }}{% else %}./databyte{% endif %}">
23+
<meta property="og:description" content="{{ desc | strip_html | strip_newlines | truncate: 160 }}">
24+
<meta property="og:url" content="{{ page.url | absolute_url }}">
25+
<meta property="og:site_name" content="./databyte">
26+
<meta name="twitter:card" content="summary">
27+
<meta name="twitter:creator" content="@databyte">
28+
29+
<!-- Set the theme before first paint so a dark-mode reader never sees a
30+
white flash. Must stay inline and above the stylesheet. -->
31+
<script>
32+
(function () {
33+
try {
34+
var t = localStorage.getItem('theme');
35+
if (t === 'light' || t === 'dark') {
36+
document.documentElement.setAttribute('data-theme', t);
37+
}
38+
} catch (e) {}
39+
})();
40+
</script>
41+
42+
<link rel="preconnect" href="https://fonts.googleapis.com">
43+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
44+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Chivo:wght@700;900&display=swap">
45+
<link rel="stylesheet" href="{{ '/css/main.css' | relative_url }}">
46+
47+
<link rel="icon" href="{{ '/favicon.svg' | relative_url }}" type="image/svg+xml">
48+
{% feed_meta %}
1549
</head>
1650

1751
<body>
18-
<div id="container">
19-
<div class="inner">
20-
<header>
21-
<h1><a href="/">./databyte</a></h1>
22-
<h2></h2>
23-
</header>
52+
<a class="skip-link" href="#main">Skip to content</a>
2453

25-
<hr/>
54+
<div class="wrap">
55+
<header class="site-header">
56+
<a class="wordmark" href="{{ '/' | relative_url }}">./databyte</a>
2657

27-
<section id="main_content">
28-
<h3>{{ page.title }}</h3>
58+
<button class="theme-toggle" type="button" id="theme-toggle"
59+
aria-label="Switch between light and dark theme">
60+
<svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
61+
fill="none" stroke="currentColor" stroke-width="2"
62+
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
63+
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z"/>
64+
</svg>
65+
<svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
66+
fill="none" stroke="currentColor" stroke-width="2"
67+
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
68+
<circle cx="12" cy="12" r="4"/>
69+
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/>
70+
</svg>
71+
</button>
72+
</header>
2973

30-
{{ content }}
31-
</section>
74+
<main class="site-main" id="main">
75+
{{ content }}
76+
</main>
3277

33-
<footer>
34-
by David Sommers. Tweet me <a href="https://twitter.com/databyte">@databyte</a>. Tactile theme by <a href="http://twitter.com/jasonlong">Jason Long</a>.
35-
</footer>
36-
</div>
78+
<footer class="site-footer">
79+
<span>by David Sommers · <a href="https://twitter.com/databyte">@databyte</a></span>
80+
<a href="{{ '/feed.xml' | relative_url }}">RSS</a>
81+
</footer>
3782
</div>
3883

39-
<script type="text/javascript">
40-
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
41-
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
42-
</script>
43-
<script type="text/javascript">
44-
try {
45-
var pageTracker = _gat._getTracker("UA-12936734-2");
46-
pageTracker._trackPageview();
47-
} catch(err) {}
84+
<script>
85+
(function () {
86+
var btn = document.getElementById('theme-toggle');
87+
if (!btn) return;
88+
var root = document.documentElement;
89+
btn.addEventListener('click', function () {
90+
// Resolve what's on screen now: an explicit override if one is set,
91+
// otherwise whatever the OS is currently giving us.
92+
var current = root.getAttribute('data-theme');
93+
if (!current) {
94+
current = window.matchMedia('(prefers-color-scheme: dark)').matches
95+
? 'dark' : 'light';
96+
}
97+
var next = current === 'dark' ? 'light' : 'dark';
98+
root.setAttribute('data-theme', next);
99+
try { localStorage.setItem('theme', next); } catch (e) {}
100+
});
101+
})();
48102
</script>
49103
</body>
50104
</html>

_layouts/post.html

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,38 @@
11
---
22
layout: default
33
---
4-
<div id="post">
5-
{{ content }}
6-
</div>
4+
<article class="post">
5+
<header class="post-header">
6+
<h1>{{ page.title }}</h1>
7+
<div class="post-meta">
8+
<time datetime="{{ page.date | date_to_xmlschema }}">
9+
{{ page.date | date: "%B %-d, %Y" }}
10+
</time>
11+
</div>
12+
</header>
713

8-
<hr/>
14+
<div class="prose">
15+
{{ content }}
16+
</div>
17+
</article>
918

10-
<div id="related">
11-
<h2>Related Posts</h2>
12-
<ul class="posts">
13-
{% for post in site.related_posts limit:3 %}
14-
<li><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{ post.url }}">{{ post.title }}</a></li>
19+
{% comment %}
20+
site.related_posts is the most recent posts, not semantically related ones,
21+
unless LSI is enabled (it isn't — it's slow and GitHub Pages won't run it).
22+
Labelled for what it actually is.
23+
{% endcomment %}
24+
<nav class="related" aria-labelledby="related-heading">
25+
<h2 id="related-heading">MORE POSTS</h2>
26+
<ul class="post-list">
27+
{% for post in site.related_posts limit: 3 %}
28+
{% if post.url != page.url %}
29+
<li class="post-item">
30+
<a class="post-link" href="{{ post.url | relative_url }}">
31+
<span class="post-date">{{ post.date | date: "%Y" }}</span>
32+
<span class="post-title">{{ post.title }}</span>
33+
</a>
34+
</li>
35+
{% endif %}
1536
{% endfor %}
1637
</ul>
17-
</div>
38+
</nav>

0 commit comments

Comments
 (0)