diff --git a/_data/metadata.js b/_data/metadata.js index aeca8f6..6b24800 100644 --- a/_data/metadata.js +++ b/_data/metadata.js @@ -4,15 +4,16 @@ module.exports = { url: "https://nathanupchurch.com/", language: "en", description: "The personal website and blog of Nathan Upchurch.", - pgpkey: "", author: { name: "Nathan Upchurch", email: "blog@upchur.ch", url: "https://nathanupchurch.com/me", profilePic: "/img/CN20191025_301_Srt_SQUARE.jpg" }, + copyrightNotice: "© Nathan Upchurch 2022 - 2024", defaultPostImageURL: "/img/vasilina-sirotina-1NMPvajSt9Q-unsplash_copy.avif", defaultPostImageAlt: "The default post image: a close picture of the dark green leaves of a plant.", + postlistHeaderText: "Latest Posts", socialLinks: [ { title: "My Blog", @@ -69,5 +70,19 @@ module.exports = { linkDisplay: "Keyoxide Identity Profile", iconURL: "/img/keyoxide.svg" } + ], + webrings: [ + { + name: "Fediring", + ringURL: "https://fediring.net/", + previousURL: "https://fediring.net/previous?host=nathanupchurch.com", + nextURL: "https://fediring.net/next?host=nathanupchurch.com" + }, + { + name: "Geekring", + ringURL: "https://geekring.net/", + previousURL: "", + nextURL: "" + } ] } diff --git a/_includes/footer.njk b/_includes/footer.njk new file mode 100644 index 0000000..ec14a44 --- /dev/null +++ b/_includes/footer.njk @@ -0,0 +1,12 @@ +<footer> + {% if metadata.copyrightNotice %}<p>{{ metadata.copyrightNotice }}</p>{% endif %}<br> + + {% if metadata.webrings %} + {% for webring in metadata.webrings %} + {% if webring.previousURL %}<a href="{{ webring.previousURL }}">←</a>{% endif %} + {% if webring.ringURL %}<a href="{{ webring.ringURL }}">{{ webring.name }}</a>{% endif %} + {% if webring.nextURL %}<a href="{{ webring.nextURL }}">→</a>{% endif %} + <br> + {% endfor %} + {% endif %} +</footer> diff --git a/_includes/header.njk b/_includes/header.njk new file mode 100644 index 0000000..a4b88d1 --- /dev/null +++ b/_includes/header.njk @@ -0,0 +1,5 @@ +<a href="#skip" class="visually-hidden">Skip to main content</a> +<header> + <a href="/" class="home-link"><img class="logo" src="{{ metadata.logo }}" alt="{{ metadata.title }}"></a> + {% if not hideNav %}{% include "nav.njk" %}{% endif %} +</header> diff --git a/_includes/layouts/403.njk b/_includes/layouts/403.njk index 4751e2d..6466cb7 100644 --- a/_includes/layouts/403.njk +++ b/_includes/layouts/403.njk @@ -1,6 +1,5 @@ --- layout: layouts/base.njk -showPostListHeader: yep --- <h1>403 Forbidden</h1> <p class="nodropcap page-block">*Ahem* <a href="/">Go to the home page</a>.</p> diff --git a/_includes/layouts/404.njk b/_includes/layouts/404.njk index d7a6205..f20459d 100644 --- a/_includes/layouts/404.njk +++ b/_includes/layouts/404.njk @@ -1,6 +1,5 @@ --- layout: layouts/base.njk -showPostListHeader: yep --- <h1>404</h1> <p class="nodropcap page-block">Sorry, it looks like that link is broken. <a href="/">Go to the home page</a>.</p> diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 136f7bb..ba0ac71 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -1,103 +1,20 @@ <!doctype html> <html lang="{{ metadata.language }}"> <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>{{ title or metadata.title }}</title> - <link rel="icon" type="image/x-icon" href="/img/logo_favicon.svg"> - <meta name="description" content="{{ description or metadata.description }}"> - <meta name="robots" content="noai, noimageai"> - - <link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}"> - <link rel="alternate" href="/feed/feed.json" type="application/json" title="{{ metadata.title }}"> - {% if metadata.pgpkey %}<link rel="pgpkey" href="{{ metadata.pgpkey | safe }}">{% endif %} - - <meta name="generator" content="{{ eleventy.generator }}"> + {% include "metadata.njk" %} {#- Bundle CSS #} {%- css %}{% include "public/css/index.css" %}{% endcss %} {%- css %}{% include "public/css/webfonts/webfonts.css" %}{% endcss %} {%- css %}{% include "public/css/dropcap.css" %}{% endcss %} <style>{% getBundle "css" %}</style> - {% if title %} - <!-- Structured Data --> - <script type="application/ld+json"> - { - "@context": "https://schema.org/", - "@type": "Article", - "headline": "{{ title }}", - "author": { - "@type": "Person", - "name": "{{ metadata.author.name }}" - }, - "datePublished": "{{ date }}", - "description": "{% if synopsis %}{{ synopsis}}{% endif %}", - "image": "{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}", - "url": "{{ page.url | htmlBaseUrl(metadata.url) }}", - "articleBody": "{{ content | striptags }}" - } - </script> - - <!-- Open Graph --> - <meta property="og:type" content="article" /> - <meta property="og:title" content="{{ title }}" /> - <meta property="og:description" content="{{ synopsis}}" /> - <meta property="og:url" content="{{ page.url | htmlBaseUrl(metadata.url) }}" /> - <meta property="og:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" /> - - <!-- Twitter card --> - <meta name="twitter:card" content="summary_large_image" /> - <meta name="twitter:title" content="{{ title }}" /> - <meta name="twitter:description" content="{{ synopsis}}" /> - <meta name="twitter:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" /> - {% endif %} - + {% include "structuredData.njk" %} {% include "umami.html" %} </head> <body> - <a href="#skip" class="visually-hidden">Skip to main content</a> - - <header> - <a href="/" class="home-link"><img class="logo" src="{{ metadata.logo }}" alt="{{ metadata.title }}"></a> - - <nav> - <h2 class="visually-hidden">Top level navigation menu</h2> - <ul class="nav"> - {%- for entry in collections.all | eleventyNavigation %} - <a class="nav-item" href="{{ entry.url }}"{% if entry.url == page.url %} aria-current="page"{% endif %}><li {% if entry.url == page.url %} data-currentpage="true"{% endif %}>{{ entry.title }}</li></a> - {%- endfor %} - <a class="nav-item" href="/feed/feed.xml"> - <li class="subscribe"> - <!-- RSS Logo --> - <svg class="nav-icon" viewBox="0 0 155 155" width="153.349" height="152.909" version="1.0" xmlns="http://www.w3.org/2000/svg"> - <g transform="translate(-427.323 -373.814)"> - <ellipse - style="opacity:1;fill-opacity:1;fill-rule:nonzero;" - transform="matrix(.86996 0 0 .86996 135.156 330.529)" - cx="360.357" cy="200.643" rx="24.643" ry="23.929" - /> - <path - style="fill-opacity:1;fill-rule:evenodd;" - d="m427.835 455.057-.073-30.273c64.706 3.375 100.619 49.673 101.5 101.94h-30.318c-.503-45.942-31.74-69.996-71.11-71.667z" - /> - <path - style="fill-opacity:1;fill-rule:evenodd;" - d="m428.201 404.571-.878-30.757C526.75 378.43 580 450.582 580.67 526.724l-31.197-.44c1.365-48.704-34.665-120.267-121.273-121.713Z" - /> - </g> - </svg>Feed - </li> - </a> - </ul> - </nav> - </header> - + {% include "header.njk" %} <main id="skip"> {{ content | safe }} </main> - <footer><p>© Nathan Upchurch 2022 - 2024<br> - <a href="https://fediring.net/previous?host=nathanupchurch.com">←</a> - <a href="https://fediring.net/">Fediring</a> - <a href="https://fediring.net/next?host=nathanupchurch.com">→</a> - </p></footer> + {% include "footer.njk" %} </body> </html> diff --git a/_includes/layouts/baseBareBones.njk b/_includes/layouts/baseBareBones.njk index 14f9af4..cd31b50 100644 --- a/_includes/layouts/baseBareBones.njk +++ b/_includes/layouts/baseBareBones.njk @@ -1,35 +1,17 @@ <!doctype html> <html lang="{{ metadata.language }}" class="barebones"> <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>{{ title or metadata.title }}</title> - <link rel="icon" type="image/x-icon" href="/img/logo_favicon.svg"> - <meta name="description" content="{{ description or metadata.description }}"> - - <meta name="generator" content="{{ eleventy.generator }}"> - + {% include "metadata.njk" %} {#- Bundle CSS #} {%- css %}{% include "public/css/index.css" %}{% endcss %} {%- css %}{% include "public/css/webfonts/webfonts.css" %}{% endcss %} - {%- css %}{% include "public/css/dropcap.css" %}{% endcss %} <style>{% getBundle "css" %}</style> - {% include "umami.html" %} </head> <body class="barebones"> - <a href="#skip" class="visually-hidden">Skip to main content</a> - - <header> - <a href="/" class="home-link"><img class="logo" src="{{ metadata.logo }}" alt="{{ metadata.title }}"></a> - </header> - + {% include "header.njk" %} <main id="skip"> {{ content | safe }} </main> - - <footer></footer> - - <!-- Current page: {{ page.url | htmlBaseUrl }} --> </body> </html> diff --git a/_includes/layouts/links.njk b/_includes/layouts/links.njk index ca7de20..5cf0adc 100644 --- a/_includes/layouts/links.njk +++ b/_includes/layouts/links.njk @@ -1,5 +1,6 @@ --- layout: layouts/baseBareBones.njk +hideNav: please --- {%- css %}{% include "public/css/links.css" %}{% endcss %} <img class="profilePic" src="{{ metadata.author.profilePic }}"> diff --git a/_includes/metadata.njk b/_includes/metadata.njk new file mode 100644 index 0000000..d7c47b9 --- /dev/null +++ b/_includes/metadata.njk @@ -0,0 +1,9 @@ +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<title>{{ title or metadata.title }}</title> +<link rel="icon" type="image/x-icon" href="/img/logo_favicon.svg"> +<meta name="description" content="{{ description or metadata.description }}"> +<meta name="robots" content="noai, noimageai"> +<link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}"> +<link rel="alternate" href="/feed/feed.json" type="application/json" title="{{ metadata.title }}"> +<meta name="generator" content="{{ eleventy.generator }}"> diff --git a/_includes/nav.njk b/_includes/nav.njk new file mode 100644 index 0000000..6c32415 --- /dev/null +++ b/_includes/nav.njk @@ -0,0 +1,13 @@ +<nav> + <h2 class="visually-hidden">Top level navigation menu</h2> + <ul class="nav"> + {%- for entry in collections.all | eleventyNavigation %} + <a class="nav-item" href="{{ entry.url }}"{% if entry.url == page.url %} aria-current="page"{% endif %}><li {% if entry.url == page.url %} data-currentpage="true"{% endif %}>{{ entry.title }}</li></a> + {%- endfor %} + <a class="nav-item" href="/feed/feed.xml"> + <li class="subscribe"> + {% include "rssLogo.njk" %}Feed + </li> + </a> + </ul> +</nav> diff --git a/_includes/postslist.njk b/_includes/postslist.njk index 3de1e1f..a101256 100644 --- a/_includes/postslist.njk +++ b/_includes/postslist.njk @@ -1,5 +1,5 @@ <section class="postlist"> -{% if showPostListHeader %}<h2>Latest Posts</h2>{% endif %} +{% if showPostListHeader %}<h2>{{ metadata.postlistHeaderText }}</h2>{% endif %} <div class="postlist-item-container"> {% for post in postslist | reverse %} <article class="postlist-item{% if post.url == url %} postlist-item-active{% endif %}"> diff --git a/_includes/rssLogo.njk b/_includes/rssLogo.njk new file mode 100644 index 0000000..a5c141c --- /dev/null +++ b/_includes/rssLogo.njk @@ -0,0 +1,19 @@ +<!-- RSS Logo --> +<svg class="nav-icon" viewBox="0 0 155 155" width="153.349" height="152.909" version="1.0" xmlns="http://www.w3.org/2000/svg"> + <g transform="translate(-427.323 -373.814)"> + <ellipse + style="opacity:1;fill-opacity:1;fill-rule:nonzero;" + transform="matrix(.86996 0 0 .86996 135.156 330.529)" + cx="360.357" cy="200.643" rx="24.643" ry="23.929" + /> + <path + style="fill-opacity:1;fill-rule:evenodd;" + d="m427.835 455.057-.073-30.273c64.706 3.375 100.619 49.673 101.5 101.94h-30.318c-.503-45.942-31.74-69.996-71.11-71.667z" + /> + <path + style="fill-opacity:1;fill-rule:evenodd;" + d="m428.201 404.571-.878-30.757C526.75 378.43 580 450.582 580.67 526.724l-31.197-.44c1.365-48.704-34.665-120.267-121.273-121.713Z" + /> + </g> +</svg> +<!-- /RSS Logo --> diff --git a/_includes/structuredData.njk b/_includes/structuredData.njk new file mode 100644 index 0000000..fa4ae77 --- /dev/null +++ b/_includes/structuredData.njk @@ -0,0 +1,30 @@ +{% if title %} +<!-- Structured Data --> +<script type="application/ld+json"> +{ + "@context": "https://schema.org/", + "@type": "Article", + "headline": "{{ title }}", + "author": { + "@type": "Person", + "name": "{{ metadata.author.name }}" + }, + "datePublished": "{{ date }}", + "description": "{% if synopsis %}{{ synopsis}}{% endif %}", + "image": "{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}", + "url": "{{ page.url | htmlBaseUrl(metadata.url) }}", + "articleBody": "{{ content | striptags }}" +} +</script> +<!-- Open Graph --> +<meta property="og:type" content="article" /> +<meta property="og:title" content="{{ title }}" /> +<meta property="og:description" content="{{ synopsis}}" /> +<meta property="og:url" content="{{ page.url | htmlBaseUrl(metadata.url) }}" /> +<meta property="og:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" /> +<!-- Twitter card --> +<meta name="twitter:card" content="summary_large_image" /> +<meta name="twitter:title" content="{{ title }}" /> +<meta name="twitter:description" content="{{ synopsis}}" /> +<meta name="twitter:image" content="{% if imageURL %}{{ imageURL | htmlBaseUrl(metadata.url) }}{% else %}{{ metadata.defaultPostImageURL | htmlBaseUrl(metadata.url) }}{% endif %}" /> +{% endif %}