Compare commits
4 Commits
5290772bce
...
18c2c898aa
Author | SHA1 | Date | |
---|---|---|---|
18c2c898aa | |||
451e860697 | |||
b89373b478 | |||
b6f74485a4 |
51
README.md
51
README.md
@ -8,6 +8,57 @@ Developed in Hugo.
|
||||
|
||||
Navigate to the project directory and:
|
||||
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
Then, to serve the site locally:
|
||||
|
||||
```
|
||||
hugo server
|
||||
```
|
||||
|
||||
## Articles
|
||||
|
||||
see `/archetypes/article.md` for the article template. You can create a new article with:
|
||||
|
||||
```
|
||||
hugo new articles/2023-01-01-my-new-article.md
|
||||
```
|
||||
This will create a new article in the `content/articles` directory with the current date and the title you provide. You can then edit the file to add your content.
|
||||
|
||||
### Head shots
|
||||
|
||||
Optionally you can add a headshot photo to your article. To do this:
|
||||
|
||||
1. Place your image file in the `/assets/headshots/` directory
|
||||
2. Add a `headshot` field to your article's front matter with just the filename. For example:
|
||||
|
||||
```yaml
|
||||
headshot: "firstname-lastname.jpg"
|
||||
```
|
||||
|
||||
*Note: Name is case sensitive, might as well use lowercase letters and hyphens in your filename.*
|
||||
|
||||
### Narrator links
|
||||
|
||||
You can add links to an article that relate to the narrator. To do this, add a `links` field to the front matter of the article. The value should be a list of objects, each with a `text` and `url` field. For example:
|
||||
|
||||
```
|
||||
links:
|
||||
- text: "My Website"
|
||||
url: "https://example.com"
|
||||
- text: "My Twitter"
|
||||
url: "https://twitter.com/example"
|
||||
```
|
||||
This will include the links in the article page. The links will be displayed as a list with the text as the link text and the URL as the link target.
|
||||
|
||||
### Open Graph Image
|
||||
|
||||
You can add Open Graph image (for social media sharing) to an article. To do this, add a `ogImage` field to the front matter of the article. The value should be the path to the image file. For example:
|
||||
|
||||
```yaml
|
||||
ogImage: "/images/my-image.jpg"
|
||||
```
|
||||
|
||||
*Note: The image should be at least 1200x630 pixels for best results. Make sure to place the image in `/static/images/` directory so it can be served correctly. The path should be relative to the static directory.*
|
14
archetypes/articles.md
Normal file
14
archetypes/articles.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
narrator: ""
|
||||
subject: ""
|
||||
facilitator: ""
|
||||
date: {{ dateFormat "2006-01-02" .Date }} # YYYY-MM-DD
|
||||
approved: "" # YYYY-MM-DD
|
||||
summary: ""
|
||||
location: ""
|
||||
topics: []
|
||||
headshot: "placeholder-headshot.png"
|
||||
links:
|
||||
- text: ""
|
||||
url: ""
|
||||
---
|
@ -1,6 +0,0 @@
|
||||
---
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
---
|
||||
|
44
assets/css/article.css
Normal file
44
assets/css/article.css
Normal file
@ -0,0 +1,44 @@
|
||||
.interviewer-question {
|
||||
font-style: italic;
|
||||
color: #444;
|
||||
margin-left: -1rem;
|
||||
}
|
||||
|
||||
.article-title--single .article-title__narrator {
|
||||
@apply mb-2 block font-light;
|
||||
}
|
||||
|
||||
.article-title--single .article-title__subject {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.article-title--list .article-title__narrator::after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
.article-title--list .article-title__subject {
|
||||
@apply font-light;
|
||||
}
|
||||
|
||||
.wompum-radial-grid {
|
||||
@apply absolute w-full h-full top-0 left-0;
|
||||
}
|
||||
|
||||
/* Narrator headshot */
|
||||
|
||||
.narrator__container {
|
||||
@apply relative w-48 mb-2 mx-auto md:mx-0 bg-white rounded-full border-4 border-white;
|
||||
}
|
||||
|
||||
.narrator__frame {
|
||||
@apply relative p-4;
|
||||
}
|
||||
|
||||
.narrator__frame img {
|
||||
@apply w-full rounded-full object-cover relative z-10 bg-white text-center border-4 border-white grid place-items-center;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.narrator__wompum {
|
||||
@apply absolute inset-0 w-full h-full;
|
||||
}
|
@ -6,49 +6,6 @@ a:hover {
|
||||
@apply text-pine-900;
|
||||
}
|
||||
|
||||
.interviewer-question {
|
||||
font-style: italic;
|
||||
color: #444;
|
||||
margin-left: -1rem;
|
||||
}
|
||||
|
||||
.article-title--single .article-title__narrator {
|
||||
@apply mb-2 block font-light;
|
||||
}
|
||||
|
||||
.article-title--single .article-title__subject {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.article-title--list .article-title__narrator::after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
.article-title--list .article-title__subject {
|
||||
@apply font-light;
|
||||
}
|
||||
|
||||
.wompum-radial-grid {
|
||||
@apply absolute w-full h-full top-0 left-0;
|
||||
}
|
||||
|
||||
.narrator__container {
|
||||
@apply relative;
|
||||
}
|
||||
|
||||
.narrator__frame {
|
||||
@apply relative p-4;
|
||||
}
|
||||
|
||||
.narrator__image {
|
||||
@apply w-full rounded-full object-cover relative z-10 bg-white text-center border-4 border-white grid place-items-center;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
.narrator__wompum {
|
||||
@apply absolute inset-0 w-full h-full;
|
||||
}
|
||||
|
||||
.tag {
|
||||
@apply p-2 bg-sand-100 border border-transparent hover:border-sand-500 rounded-lg whitespace-nowrap hover:text-gray-900 hover:opacity-100 no-underline;
|
||||
}
|
||||
|
@ -45,3 +45,4 @@ body {
|
||||
|
||||
@import "components/wompum.css";
|
||||
@import "main.css";
|
||||
@import "article.css";
|
||||
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
@ -12,7 +12,7 @@ title = 'Protocol Oral History Project'
|
||||
|
||||
[params]
|
||||
description = "The Protocol Oral History Project chronicles the development of internet protocols and standards through interviews with key contributors."
|
||||
images = ["/images/default-og.jpg"] # Will be replaced by wompum generation
|
||||
openGraphImage = "/images/og-default.jpg"
|
||||
twitterSite = ""
|
||||
facebookAppID = ""
|
||||
footer = """
|
||||
|
@ -7,7 +7,7 @@ approved: 2025-03-20
|
||||
summary: "Drawing on many ancestral traditions and the experience of her own body, Asia Dorsey learns and teaches the pattern language of a healthy gut."
|
||||
location: "Denver CO"
|
||||
topics: [ancestors, food, health, indigeneity]
|
||||
headshot: "/headshots/placeholder-headshot.png"
|
||||
headshot: "placeholder-headshot.png"
|
||||
links:
|
||||
- text: "Bugs Bones & Botany"
|
||||
url: "https://www.bonesbugsandbotany.com"
|
||||
|
@ -6,7 +6,7 @@ date: 2024-10-10
|
||||
approved: 2024-10-11
|
||||
summary: "After widespread resistance to codes of conduct in open-source software communities, Coraline Ada Ehmke's Contributor Covenant became the most popular code of conduct in the ecosystem."
|
||||
location: "Chicago, USA"
|
||||
headshot: "/headshots/placeholder-headshot.png"
|
||||
headshot: "placeholder-headshot.png"
|
||||
topics: [code of conduct, dispute resolution, gender, open source, organizations, software]
|
||||
---
|
||||
|
||||
|
@ -6,7 +6,7 @@ date: 2024-10-29
|
||||
approved: 2024-12-16
|
||||
summary: "Good Market is a digital commons for enterprises that prioritize people and the planet over profit. It enables communities to set and enforce their own standards for doing business."
|
||||
location: "Sri Lanka / United States"
|
||||
headshot: "/headshots/placeholder-headshot.png"
|
||||
headshot: "placeholder-headshot.png"
|
||||
topics: [economics, organizations, ecology, standards]
|
||||
---
|
||||
|
||||
|
@ -6,7 +6,7 @@ date: 2024-12-13
|
||||
approved: 2025-03-04
|
||||
summary: "A diplomat for Bangladesh describes the role of protocol in high-profile international visits and treaty negotiations."
|
||||
location: "Dhaka, Bangladesh"
|
||||
headshot: "/headshots/placeholder-headshot.png"
|
||||
headshot: "placeholder-headshot.png"
|
||||
topics: [diplomacy, government, friendship]
|
||||
---
|
||||
|
||||
|
@ -6,7 +6,7 @@ date: 2024-12-06
|
||||
approved: 2025-04-01
|
||||
summary: "A career-long journey to build online social networks that cannot be controlled by a single company, culminating with the ActivityPub standard."
|
||||
location: "Montreal, Canada"
|
||||
headshot: "/headshots/placeholder-headshot.png"
|
||||
headshot: "placeholder-headshot.png"
|
||||
links:
|
||||
- text: Website
|
||||
url: https://evanp.me/
|
||||
|
@ -6,7 +6,7 @@ date: 2024-11-04
|
||||
approved: 2024-12-02
|
||||
summary: "As a sport often played with no referees, ultimate frisbee has developed a strong set of norms for addressing conflict and self-governing."
|
||||
location: "East Greenbush, NY USA"
|
||||
headshot: "/headshots/placeholder-headshot.png"
|
||||
headshot: "placeholder-headshot.png"
|
||||
topics: [frisbee, sports, organizations, dispute resolution]
|
||||
---
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
{{ end }}
|
||||
|
||||
<!-- Basic SEO -->
|
||||
<title>{{ $title }}</title>
|
||||
<title>{{ $title }}{{ if .Params.narrator }} - {{ .Site.Title }}{{ end }}</title>
|
||||
|
||||
{{/* Generate description from summary, description, or default site description */}}
|
||||
{{ $description := "" }}
|
||||
@ -36,23 +36,21 @@
|
||||
{{ end }}
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:site_name" content="{{ .Site.Title }}" />
|
||||
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}" />
|
||||
<meta property="og:url" content="{{ .Permalink }}" />
|
||||
<meta property="og:title" content="{{ $title }}" />
|
||||
<meta property="og:description" content="{{ $description }}" />
|
||||
{{ with .Params.images | default .Site.Params.images }}
|
||||
<meta property="og:image" content="{{ index . 0 | absURL }}" />
|
||||
{{ end }}
|
||||
{{ with .Site.Params.facebookAppID }}
|
||||
<meta property="fb:app_id" content="{{ . }}" />
|
||||
{{ with .Params.ogImage | default .Site.Params.openGraphImage }}
|
||||
<meta property="og:image" content="{{ . | absURL }}" />
|
||||
{{ end }}
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="{{ $title }}" />
|
||||
<meta name="twitter:description" content="{{ $description }}" />
|
||||
{{ with .Params.images }}
|
||||
<meta name="twitter:image" content="{{ index . 0 | absURL }}" />
|
||||
{{ with .Params.ogImage | default .Site.Params.openGraphImage }}
|
||||
<meta name="twitter:image" content="{{ . | absURL }}" />
|
||||
{{ end }}
|
||||
|
||||
<!-- Article Specific -->
|
||||
@ -64,7 +62,6 @@
|
||||
{{ range . }}
|
||||
<meta property="article:tag" content="{{ . }}" />
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
{{/* Author information using standard meta topics instead of article:author */}}
|
||||
@ -79,9 +76,7 @@
|
||||
<!-- Canonical URL -->
|
||||
<link rel="canonical" href="{{ .Permalink }}" />
|
||||
|
||||
<!-- CSS Variables and Styles -->
|
||||
{{ partial "css-variables.html" . }}
|
||||
|
||||
<!-- CSS Styles -->
|
||||
{{ partial "css.html" . }}
|
||||
</head>
|
||||
<body class="">
|
||||
@ -90,8 +85,13 @@
|
||||
{{ block "main" . }}{{ end }}
|
||||
</div>
|
||||
{{ partial "footer.html" . }}
|
||||
<script src="/js/sigil.js"></script>
|
||||
<script src="/js/colorCalculator.js"></script>
|
||||
<script src="/js/wompum.js"></script>
|
||||
|
||||
{{ $js := resources.Match "js/*.js" | resources.Concat "js/bundle.js" }}
|
||||
{{ if hugo.IsProduction }}
|
||||
{{ $js = $js | minify | fingerprint }}
|
||||
<script src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}" crossorigin="anonymous"></script>
|
||||
{{ else }}
|
||||
<script src="{{ $js.RelPermalink }}"></script>
|
||||
{{ end }}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -5,14 +5,16 @@
|
||||
<header class="mb-4 wompum-container wompum-container--wide-gap aspect-2/1 md:aspect-3/1">{{ partial "article-wompum.html" . }}</header>
|
||||
|
||||
<div class="flex md:flex-row flex-col gap-4 mt-4">
|
||||
<aside class="md:sticky md:top-0 md:h-screen md:overflow-y-auto lg:w-1/3 p-4 font-iosevka
|
||||
{{ if .Params.headshot }}-mt-24{{ end }}
|
||||
">
|
||||
{{ if .Params.headshot }}
|
||||
<div class="narrator__container w-48 mb-2 mx-auto md:mx-0 bg-white rounded-full border-4 border-white" data-text="{{ .Params.narrator }}">
|
||||
<div class="narrator__frame">
|
||||
<img src="{{ .Params.headshot }}" alt="Photo of {{ .Params.narrator }}" class="narrator__image" loading="lazy">
|
||||
</div>
|
||||
<aside class="md:sticky md:top-24 md:h-screen lg:w-1/3 p-4 font-iosevka">
|
||||
{{ $headshot := resources.GetMatch (printf "**/%s" (strings.TrimPrefix "/" .Params.headshot)) }}
|
||||
{{ if and .Params.headshot $headshot }}
|
||||
<div class="narrator__container -mt-24" data-text="{{ .Params.narrator }}">
|
||||
{{ partial "image.html" (dict
|
||||
"resource" $headshot
|
||||
"width" "192"
|
||||
"class" "narrator__frame"
|
||||
"alt" (printf "Photo of %s" .Params.narrator)
|
||||
) }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="md:block hidden">{{ partial "article-metadata.html" . }}</div>
|
||||
|
19
layouts/partials/image.html
Normal file
19
layouts/partials/image.html
Normal file
@ -0,0 +1,19 @@
|
||||
{{ $width := .width }}
|
||||
{{ $height := default $width .height }}
|
||||
{{ $class := .class }}
|
||||
{{ $resource := .resource }}
|
||||
{{ $alt := .alt }}
|
||||
|
||||
{{ with $resource }}
|
||||
{{ $image := .Fit (printf "%dx%d webp" (int $width) (int $height)) }}
|
||||
{{ $fallback := .Fit (printf "%dx%d" (int $width) (int $height)) }}
|
||||
<picture class="{{ $class }} block">
|
||||
<source srcset="{{ $image.RelPermalink }}" type="image/webp">
|
||||
<img
|
||||
src="{{ $fallback.RelPermalink }}"
|
||||
alt="{{ $alt }}"
|
||||
width="{{ $width }}"
|
||||
height="{{ $height }}"
|
||||
loading="lazy">
|
||||
</picture>
|
||||
{{ end }}
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Reference in New Issue
Block a user