Compare commits

33 Commits

Author SHA1 Message Date
mxmehl f0cc94da72 feat: remove stackoverflow 2026-02-23 15:46:06 +01:00
mxmehl ff2ba9741a feat: shorten landing page
Website build and deploy / build (pull_request) Successful in 1m34s
2026-02-22 15:43:32 +01:00
mxmehl 08a517fde5 feat: recent posts on index, CSS and HTML improvements 2026-02-22 15:22:32 +01:00
mxmehl 85dc915744 feat: remove old links page 2026-02-22 11:32:38 +01:00
mxmehl 45b18330b5 feat: improve tag list display 2026-02-22 11:32:38 +01:00
mxmehl 58feb7692d chore: consolidate tags 2026-02-22 11:32:37 +01:00
mxmehl 10097fb4ac feat: convert remaining talks to content 2026-02-21 16:36:04 +01:00
mxmehl f04d279e2b feat: reduce summary length 2026-02-19 23:14:47 +01:00
mxmehl 9db0c696db feat: header image contains alt and title tag 2026-02-19 23:06:12 +01:00
mxmehl d73c68ec79 feat: add first batch of av links 2026-02-14 17:33:58 +01:00
mxmehl 87b15cc116 feat: add recent talks 2026-02-14 16:56:58 +01:00
mxmehl 274323553b feat: convert last 4 articles to proper content 2026-02-14 16:03:24 +01:00
mxmehl 7b2a97533c feat: convert next 5 links to proper content 2026-02-14 15:42:35 +01:00
mxmehl 0c69d9b989 feat: convert next 5 links to proper content 2026-02-14 13:50:58 +01:00
mxmehl b4205a93dc feat: convert 2 more links to proper content 2026-02-14 12:45:03 +01:00
mxmehl 97422901be feat: convert 2 links to proper content 2026-02-14 12:32:04 +01:00
mxmehl 99099e8532 fix: wording on article button 2026-02-14 12:24:39 +01:00
mxmehl 3d5752e591 feat: create archetype for updates 2026-02-14 12:07:30 +01:00
mxmehl 5536456e78 feat: improve new articles and links layout 2026-02-14 11:57:44 +01:00
mxmehl 501e40172f ci: hardcode hugo version to avoid unexpected failures 2026-02-14 11:08:21 +01:00
mxmehl 2b48b1b2ae fix: actually use rendered header images 2026-02-14 11:05:08 +01:00
mxmehl b6f5869092 feat: improve headlines 2026-02-14 11:04:54 +01:00
mxmehl 0722d54cfc feat: improve button styling 2026-02-14 10:25:47 +01:00
mxmehl 87b4976482 feat: simple buttons to show links for media 2026-02-13 00:39:08 +01:00
mxmehl 8b1e08e1f2 fix: margin if not header text is present 2026-02-13 00:11:43 +01:00
mxmehl b4b3a746e5 feat: handle missing header images 2026-02-12 23:59:54 +01:00
mxmehl bc522c6de8 chore: reduce image size 2026-02-12 23:51:39 +01:00
mxmehl 807fd9cdf9 feat: make types and languages selectable 2026-02-12 23:48:38 +01:00
mxmehl e0ac3820dc feat: update meta image and tags 2026-02-12 23:26:11 +01:00
mxmehl 97efeb8af6 feat: add image processing, improvements 2026-02-12 22:57:49 +01:00
mxmehl a213480cd8 feat: support leaf bundles for blog posts, refactor header images 2026-02-12 21:39:21 +01:00
mxmehl 92d46d74bf feat: add three different media as blog types as testing objects, with infos on list 2026-02-12 20:55:29 +01:00
mxmehl 81d72c9576 add OpenRail Day moderation to links 2026-01-20 15:43:50 +01:00
25 changed files with 43 additions and 269 deletions
+8 -16
View File
@@ -28,17 +28,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout with submodules - name: Checkout with submodules
uses: actions/checkout@v7 uses: actions/checkout@v6
with: with:
submodules: recursive # Get submdules submodules: recursive # Get submdules
fetch-depth: 1 # Fetch all history for .GitInfo and .Lastmod fetch-depth: 1 # Fetch all history for .GitInfo and .Lastmod
- name: Setup required tools (Hugo)
uses: https://github.com/jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
with:
cache: false # no cache on gitea
github_token: ${{ secrets.GH_TOKEN }}
- name: Create configuration for Matomo - name: Create configuration for Matomo
run: | run: |
cp themes/hugo-sustain/static/config.php.sample static/config.php cp themes/hugo-sustain/static/config.php.sample static/config.php
@@ -46,19 +40,17 @@ jobs:
sed -i "s|__PROXY_URL__|${{ secrets.MATOMO_PROXY_URL }}|" static/config.php sed -i "s|__PROXY_URL__|${{ secrets.MATOMO_PROXY_URL }}|" static/config.php
sed -i "s|__TOKEN_AUTH__|${{ secrets.MATOMO_TOKEN_AUTH }}|" static/config.php sed -i "s|__TOKEN_AUTH__|${{ secrets.MATOMO_TOKEN_AUTH }}|" static/config.php
- name: Check for broken links - name: Setup Hugo
run: | uses: https://github.com/peaceiris/actions-hugo@v3.0.0
if [ "${{ gitea.ref }}" = "refs/heads/main" ]; then with:
mise linkcheck --offline || true hugo-version: "0.155.3"
else extended: true
mise linkcheck --offline
fi
- name: Build website with Hugo - name: Build website with Hugo
run: mise run build run: hugo
- name: Copy website to host - name: Copy website to host
uses: https://github.com/appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0 uses: https://github.com/appleboy/scp-action@v1.0.0
with: with:
host: mehl.mx host: mehl.mx
username: maxmehl username: maxmehl
+1 -6
View File
@@ -12,14 +12,12 @@ summaryLength = 50
leftDoubleQuote = '“' leftDoubleQuote = '“'
rightDoubleQuote = '”' rightDoubleQuote = '”'
[markup.goldmark.renderHooks.link]
useEmbedded = "fallback"
[permalinks] [permalinks]
blog = "/blog/:year/:slug" blog = "/blog/:year/:slug"
[params] [params]
avatar = "profile.png" avatar = "profile.png"
author = "Max Mehl"
description = "Open Source expert with background in tech and policy. Focused on strategy, governance, and software supply chains. Building sustainable digital environments." description = "Open Source expert with background in tech and policy. Focused on strategy, governance, and software supply chains. Building sustainable digital environments."
keywords = "open source, free software, Deutsche Bahn, DB Systel, FSFE, management, campaign, communication, strategy, konstanz, berlin, munster, IT service, politics, administration, scouts, founder" keywords = "open source, free software, Deutsche Bahn, DB Systel, FSFE, management, campaign, communication, strategy, konstanz, berlin, munster, IT service, politics, administration, scouts, founder"
@@ -27,9 +25,6 @@ summaryLength = 50
custom_css = ["comments/mastodon-comments.css"] custom_css = ["comments/mastodon-comments.css"]
custom_js = ["comments/getcomments.js"] custom_js = ["comments/getcomments.js"]
[params.author]
name = "Max Mehl"
[params.social] [params.social]
Github = "mxmehl" Github = "mxmehl"
Git = "https://src.mehl.mx/mxmehl" Git = "https://src.mehl.mx/mxmehl"
@@ -53,4 +53,4 @@ Any further questions? Do not hesitate [to ask me][3]!
[1]: /2015/naechste-station-tansania [1]: /2015/naechste-station-tansania
[2]: /uploads/tanzania-map.png [2]: /uploads/tanzania-map.png
[3]: /contact [3]: //max.mehl.mx/contact
@@ -10,7 +10,7 @@ tags:
headerimage: headerimage:
src: /blog/system-chaos.jpg src: /blog/system-chaos.jpg
text: Fortunately not how the FSFE's infrastructure looks like text: Fortunately not how the FSFE's infrastructure looks like
mastodon_toot_url: "https://mastodon.social/@mxmehl/103010490628830773"
--- ---
On 10 and 11 October, the FSFE System Hackers met in person to tackle On 10 and 11 October, the FSFE System Hackers met in person to tackle
+1 -1
View File
@@ -11,7 +11,7 @@ tags:
headerimage: headerimage:
src: /blog/hidden-street.jpg src: /blog/hidden-street.jpg
text: The unknown Free Software contributors. Photo by Kaique Rocha text: The unknown Free Software contributors. Photo by Kaique Rocha
mastodon_toot_url: "https://mastodon.social/@mxmehl/103656218613382198"
--- ---
A few days ago I've sent an announcement email for today's [I Love Free Software Day](https://ilovefs.org) to a large bunch of people. Most of the remarkably many replies have been positive and a pure joy to read, but some were a bit sceptical and critical. These came from Free Software contributors who are maintaining and helping projects that they think nobody knows and sees not because these software projects are unused, but because they are small, a building block for other, more popular applications. A few days ago I've sent an announcement email for today's [I Love Free Software Day](https://ilovefs.org) to a large bunch of people. Most of the remarkably many replies have been positive and a pure joy to read, but some were a bit sceptical and critical. These came from Free Software contributors who are maintaining and helping projects that they think nobody knows and sees not because these software projects are unused, but because they are small, a building block for other, more popular applications.
@@ -10,7 +10,7 @@ tags:
headerimage: headerimage:
src: /blog/syshackers-group-hacking.jpg src: /blog/syshackers-group-hacking.jpg
text: Hackers in their natural working environment. For the picture we took off the black ski masks and gloves. text: Hackers in their natural working environment. For the picture we took off the black ski masks and gloves.
mastodon_toot_url: "https://mastodon.social/@mxmehl/103916900645046939"
--- ---
For the 4th time, and less than 5 months after the last meeting, the For the 4th time, and less than 5 months after the last meeting, the
@@ -10,7 +10,6 @@ tags:
headerimage: headerimage:
src: /blog/git-sed.png src: /blog/git-sed.png
text: Replacing content in thousands of files? No problem! text: Replacing content in thousands of files? No problem!
mastodon_toot_url: "https://mastodon.social/@mxmehl/104590750280074999"
--- ---
In the recent weeks and months, the [FSFE Web Team](https://fsfe.org/contribute/web/) has been doing some heavy work on the [FSFE website](https://fsfe.org). We moved and replaced thousands of files and their respective links to improve the structure of a historically grown website (19+ years, 23243 files, almost 39k commits). But how to do that most efficiently in a version controlled system like Git? In the recent weeks and months, the [FSFE Web Team](https://fsfe.org/contribute/web/) has been doing some heavy work on the [FSFE website](https://fsfe.org). We moved and replaced thousands of files and their respective links to improve the structure of a historically grown website (19+ years, 23243 files, almost 39k commits). But how to do that most efficiently in a version controlled system like Git?
@@ -11,7 +11,6 @@ tags:
headerimage: headerimage:
src: /blog/docker.jpg src: /blog/docker.jpg
text: Shipping a load of containers requires a reliable infrastructure text: Shipping a load of containers requires a reliable infrastructure
mastodon_toot_url: "https://mastodon.social/@mxmehl/108193478971435955"
--- ---
So you have a number of Docker containers running web services which you would So you have a number of Docker containers running web services which you would
+6 -7
View File
@@ -10,7 +10,6 @@ tags:
headerimage: headerimage:
src: /blog/library.jpg src: /blog/library.jpg
text: Wouldn't it be a shame if your library were to be destroyed? text: Wouldn't it be a shame if your library were to be destroyed?
mastodon_toot_url: "https://mastodon.social/@mxmehl/111109533835169070"
--- ---
I have been using [Seafile](https://www.seafile.com/) for years to host and I have been using [Seafile](https://www.seafile.com/) for years to host and
@@ -20,7 +19,7 @@ all its files isn't so trivial. This is because the files are stored in a layout
similar to bare Git repositories, and Seafile's headless tool, seafile-cli, similar to bare Git repositories, and Seafile's headless tool, seafile-cli,
is... suboptimal. So I created what started out as a wrapper for it and ended up is... suboptimal. So I created what started out as a wrapper for it and ended up
as a full-blown tool for automatically synchronising your libraries to a backup as a full-blown tool for automatically synchronising your libraries to a backup
location: [**Seafile Mirror**](https://github.com/mxmehl/seafile-mirror). location: [**Seafile Mirror**](https://src.mehl.mx/mxmehl/seafile-mirror).
## My requirements ## My requirements
@@ -64,7 +63,7 @@ turned out that this tool has a number of fundamental issues:
## The solution ## The solution
[seafile-mirror](https://github.com/mxmehl/seafile-mirror) takes care of all [seafile-mirror](https://src.mehl.mx/mxmehl/seafile-mirror) takes care of all
these stumbling blocks: these stumbling blocks:
* It downloads/syncs defined libraries in customisable intervals * It downloads/syncs defined libraries in customisable intervals
@@ -95,13 +94,13 @@ and configuration.
The tool has been running every day since a couple of months without any issues. The tool has been running every day since a couple of months without any issues.
However, I could imagine a few more features to be helpful for more people: However, I could imagine a few more features to be helpful for more people:
* Support of encrypted libraries: Shouldn't be a big issue, it would require
passing the password to the underlying seafile-cli command.
([#1](https://github.com/mxmehl/seafile-mirror/issues/1))
* Support of login tokens: Currently, only user/password auth is supported which * Support of login tokens: Currently, only user/password auth is supported which
is fine for my use-case as it's just a read-only user. This wouldn't be hard is fine for my use-case as it's just a read-only user. This wouldn't be hard
to fix either, seafile-cli supports it (at least in theory). to fix either, seafile-cli supports it (at least in theory).
([#2](https://github.com/mxmehl/seafile-mirror/issues/2)) ([#2](https://src.mehl.mx/mxmehl/seafile-mirror/issues/2))
* Support of encrypted libraries: Shouldn't be a big issue, it would require
passing the password to the underlying seafile-cli command.
([#3](https://src.mehl.mx/mxmehl/seafile-mirror/issues/3))
If you have encountered problems or would like to point out the need for If you have encountered problems or would like to point out the need for
specific features, please feel free to contact me or comment on the Mastodon specific features, please feel free to contact me or comment on the Mastodon
@@ -19,7 +19,6 @@ slides: https://fosdem.org/2026/events/attachments/ZSWH3N-deutsche-bahn-supply-c
event: event:
name: FOSDEM 2026 name: FOSDEM 2026
href: https://fosdem.org/2026/schedule/event/ZSWH3N-deutsche-bahn-supply-chain-cra-strategy/ href: https://fosdem.org/2026/schedule/event/ZSWH3N-deutsche-bahn-supply-chain-cra-strategy/
mastodon_toot_url: "https://mastodon.social/@mxmehl/116160561981890042"
--- ---
At FOSDEM 2026, I presented Deutsche Bahn's software supply chain strategy in the context of the EU Cyber Resilience Act (CRA), but made clear from the start that CRA was the context, not the trigger. We didn't adopt SBOMs because of regulation regulation validated the direction we were already taking based on operational needs. The presentation positioned our work at the intersection of CRA compliance requirements, IT operation best practices, and the practical realities of running IT infrastructure for an organization with 220,000+ employees, 7,000+ IT applications, and 100,000+ Open Source components. At FOSDEM 2026, I presented Deutsche Bahn's software supply chain strategy in the context of the EU Cyber Resilience Act (CRA), but made clear from the start that CRA was the context, not the trigger. We didn't adopt SBOMs because of regulation regulation validated the direction we were already taking based on operational needs. The presentation positioned our work at the intersection of CRA compliance requirements, IT operation best practices, and the practical realities of running IT infrastructure for an organization with 220,000+ employees, 7,000+ IT applications, and 100,000+ Open Source components.
@@ -19,7 +19,6 @@ slides: https://fosdem.org/2026/events/attachments/7EYTRJ-deutsche-bahn-large-sc
event: event:
name: FOSDEM 2026 name: FOSDEM 2026
href: https://fosdem.org/2026/schedule/event/7EYTRJ-deutsche-bahn-large-scale-sbom-approach/ href: https://fosdem.org/2026/schedule/event/7EYTRJ-deutsche-bahn-large-scale-sbom-approach/
mastodon_toot_url: "https://mastodon.social/@mxmehl/116160570821178215"
--- ---
At FOSDEM 2026, I presented Deutsche Bahn's journey from operational need to concrete implementation of large-scale SBOM collection and use. The scale is staggering: approximately 500,000 SBOMs across our software supply chain expected, covering 7,000+ IT applications, 100,000+ Open Source components, and diverse sourcing streams from software we build ourselves to what we buy and operate. The talk focused on how we moved from understanding that "we need to know, in real-time, which exact component is used where and how" to actually making this happen in an organization with 220,000+ employees and hundreds of subsidiaries. At FOSDEM 2026, I presented Deutsche Bahn's journey from operational need to concrete implementation of large-scale SBOM collection and use. The scale is staggering: approximately 500,000 SBOMs across our software supply chain expected, covering 7,000+ IT applications, 100,000+ Open Source components, and diverse sourcing streams from software we build ourselves to what we buy and operate. The talk focused on how we moved from understanding that "we need to know, in real-time, which exact component is used where and how" to actually making this happen in an organization with 220,000+ employees and hundreds of subsidiaries.
@@ -1,30 +0,0 @@
---
title: "Getting Real with the Supply Chain: From SBOM Data to Action"
date: 2026-03-17
categories:
# Language
- english
# - deutsch
- presentation
# - podcast
# - article
tags:
- OSPO
- SupplyChain
- DeutscheBahn
headerimage:
src: max-cornelius-stage.jpg
alt: Cornelius Schumacher and Max Mehl giving the presentation at FOSS Backstage 2026. It's a total view of the auditorium from the back, with the two speakers on stage and the final slide in the background.
# summary: Visible on the listing page, but not on the article page
video: https://www.youtube.com/watch?v=M8wYRRCWaQU
slides: https://up.mehl.mx/slides/2026-03-17-foss-backstage-supply-chain.pdf
event:
name: FOSS Backstage 2026
href: https://26.foss-backstage.de/session/getting-real-with-the-supply-chain-from-sbom-data-to-action/
---
At DB, we handle 100,000+ SBOMs per day. For our small, virtual Open Source Program Office (OSPO), the challenge is not to get lost in the data, but to cut through the jungle and identify real risks. Together with my OSPO colleague Cornelius Schumacher, I presented this challenge at the FOSS Backstage conference in Berlin. We explained how we gather data, generate insights, and take action.
This talk was partly inspired by my earlier FOSDEM talks ([here](/blog/2026-01-fosdem-supply-chain-strategy) and [there](/blog/2026-02-fosdem-sbom-collection)), where I focused on DB's SBOM program and its tools. In this presentation, however, we highlighted what can be learned from it for professional Open Source management.
One topic stood out throughout the presentation: the need for an OSPO to balance between people, value, and risk. None of these should dominate, even though governance functions often tend to focus on risk. Instead, Cornelius and I advocated for a risk-based approach to managing Open Source.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 KiB

@@ -1,28 +0,0 @@
---
title: "Software-Lieferketten bei der Deutschen Bahn"
date: 2026-03-25
categories:
- deutsch
- podcast
tags:
- Community
- DeutscheBahn
- SupplyChain
summary: Ich wurde mal wieder von Ralf Hersel zum “Captain its Wednesday” Podcast von GNU/Linux.ch eingeladen, um über Software-Lieferketten bei der Deutschen Bahn zu sprechen. Anlass waren meine jüngsten Vorträge auf der FOSS Backstage und der FOSDEM, in denen ich über die Herausforderungen und Chancen von Software-Lieferketten bei der DB gesprochen habe.
headerimage:
src: ciw.jpg
alt: The famous "Captain it's Wednesday" comic
processes:
- fill 1000x440 center webp
audio: https://gnulinux.ch/podcast/CIW175.mp3
event:
name: Captain it's Wednesday Podcast
href: https://gnulinux.ch/ciw175-podcast
mastodon_toot_url: https://mastodon.social/@mxmehl/116318946107759692
---
Ich wurde mal wieder von Ralf Hersel zum "Captain it's Wednesday" Podcast von GNU/Linux.ch eingeladen, um über Software-Lieferketten bei der Deutschen Bahn zu sprechen. Anlass waren meine jüngsten Vorträge auf der [FOSS Backstage](/blog/2026-03-foss-backstage-getting-real-supply-chain) und der [FOSDEM](/blog/2026-01-fosdem-supply-chain-strategy), in denen ich über die Herausforderungen und Chancen von Software-Lieferketten bei der DB gesprochen habe.
Mit Ralf habe ich mal ganz vorne angefangen: was ist eine Software-Lieferkette überhaupt, warum ist sie wichtig, und wie sieht sie bei einem großen Unternehmen wie der Deutschen Bahn aus, und was haben diese SBOMs damit zu tun? Wir haben über die enormen Mengen an Software-Komponenten gesprochen, die täglich bei der DB verarbeitet werden, und wie wir versuchen, den Überblick zu behalten und Risiken zu managen. Dabei ging es auch um die Rolle von Freier und Open Source in der Lieferkette und wie wir dabei mit der Community zusammenarbeiten.
Nach exakt 37 Minuten war das Gespräch auch schon wieder vorbei und natürlich konnten wir nicht in jedes Detail eintauchen. Aber ich hoffe, es war dennoch ein interessanter Einblick für die Zuhörenden.
-65
View File
@@ -1,65 +0,0 @@
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
[[tools.hugo-extended]]
version = "0.162.1"
backend = "aqua:gohugoio/hugo/hugo-extended"
[tools.hugo-extended."platforms.linux-arm64"]
checksum = "sha256:f5531494dd573cfc142779894a9e3e414ab05626d6e0492cc06209dc783aaf39"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_linux-arm64.tar.gz"
[tools.hugo-extended."platforms.linux-arm64-musl"]
checksum = "sha256:f5531494dd573cfc142779894a9e3e414ab05626d6e0492cc06209dc783aaf39"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_linux-arm64.tar.gz"
[tools.hugo-extended."platforms.linux-x64"]
checksum = "sha256:e34160095b6a6406af857fe212f50e4451f67ed1276b9bb0de13d08754980118"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_linux-amd64.tar.gz"
[tools.hugo-extended."platforms.linux-x64-musl"]
checksum = "sha256:e34160095b6a6406af857fe212f50e4451f67ed1276b9bb0de13d08754980118"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_linux-amd64.tar.gz"
[tools.hugo-extended."platforms.macos-arm64"]
checksum = "sha256:ed246e094d3d5c54583ffcebd8c98529072f57901bd3b1bb2f1fdc968766f13d"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_darwin-universal.pkg"
[tools.hugo-extended."platforms.macos-x64"]
checksum = "sha256:ed246e094d3d5c54583ffcebd8c98529072f57901bd3b1bb2f1fdc968766f13d"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_darwin-universal.pkg"
[tools.hugo-extended."platforms.windows-x64"]
checksum = "sha256:62b3a0d4ec48a7d00270c3f5e87c3de097c855200c47ad02640cf4a219c361ea"
url = "https://github.com/gohugoio/hugo/releases/download/v0.162.1/hugo_extended_0.162.1_windows-amd64.zip"
[[tools.lychee]]
version = "0.24.2"
backend = "aqua:lycheeverse/lychee"
[tools.lychee."platforms.linux-arm64"]
checksum = "sha256:5d0b0e3aeab240f41920c633a6eaf97599be6eedda034b36e858ede7dba5e535"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-unknown-linux-musl.tar.gz"
[tools.lychee."platforms.linux-arm64-musl"]
checksum = "sha256:5d0b0e3aeab240f41920c633a6eaf97599be6eedda034b36e858ede7dba5e535"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-unknown-linux-musl.tar.gz"
[tools.lychee."platforms.linux-x64"]
checksum = "sha256:73657a111819a30c47c08352896796f23d64e4eb2b3ed39b6d32149241566fc5"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-unknown-linux-musl.tar.gz"
[tools.lychee."platforms.linux-x64-musl"]
checksum = "sha256:73657a111819a30c47c08352896796f23d64e4eb2b3ed39b6d32149241566fc5"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-unknown-linux-musl.tar.gz"
[tools.lychee."platforms.macos-arm64"]
checksum = "sha256:c9d3740ea2d891854d37116c9fba840f37b6e7c89d330e7db84ac333631c4977"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-aarch64-apple-darwin.tar.gz"
[tools.lychee."platforms.macos-x64"]
checksum = "sha256:887503a9cff667d322b8d0892b40bf49976eb9507af8483220a3706cdad55978"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-apple-darwin.tar.gz"
[tools.lychee."platforms.windows-x64"]
checksum = "sha256:32975d1493ee1a975d6bb41e4fb56fe419cb442ded628bb772ba2e614acfacad"
url = "https://github.com/lycheeverse/lychee/releases/download/lychee-v0.24.2/lychee-x86_64-pc-windows-msvc.zip"
-33
View File
@@ -1,33 +0,0 @@
[tools]
hugo-extended = "0.162.1"
lychee = "latest"
[vars]
build_dir = "public"
[tasks.cleanup]
description = "Clean up the build destination directory"
run = "rm -r {{vars.build_dir}} || true"
[tasks.build]
depends = ["cleanup"]
description = "Build the static site using Hugo"
run = "hugo -d {{vars.build_dir}}"
[tasks.preview]
depends = ["cleanup"]
description = "Preview the site locally using Hugo's built-in server"
run = "hugo server"
[tasks.linkcheck]
depends = ["build"]
description = "Check for broken links using lychee"
run = '''
lychee \
--max-concurrency 5 --cache --max-cache-age 1h \
--index-files 'index.html' \
--root-dir {{vars.build_dir}}/ \
-u 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Apple WebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36' \
--exclude 'glyphicons-halflings-regular\.(eot|woff|woff2|ttf|svg)' \
{{vars.build_dir}}/
'''
+1 -1
View File
@@ -9,7 +9,7 @@ $config = [
// the URL of your blog. All toots are searched for this string // the URL of your blog. All toots are searched for this string
// please use https?:// as schema // please use https?:// as schema
'search-url' => 'https?://mehl.mx', 'search-url' => 'https?://mehl.mx',
'cache_toots' => 1800, // seconds to cache toots 'cache_toots' => 300, // seconds to cache toots
'cache_comments' => 300, // seconds to cache comments (per ID) 'cache_comments' => 300, // seconds to cache comments (per ID)
'debug' => false // writes some debug messages in error_log 'debug' => false // writes some debug messages in error_log
]; ];
@@ -363,13 +363,6 @@ div.contact p {
margin-top: 0; margin-top: 0;
} }
} }
// First and last card in the list have different border radius
.row:first-child .card {
border-radius: 1rem 1rem 0 1rem;
}
.row:last-child .card {
border-radius: 0 1rem 1rem 1rem;
}
} }
/* Helpers */ /* Helpers */
@@ -65,9 +65,7 @@
</div> </div>
<div class="col-xs-9 col-md-10"> <div class="col-xs-9 col-md-10">
{{ if $selection }} {{ if $selection }}
{{- with .OutputFormats.Get "RSS" -}} <span class="article-rss"><a class="label label-rss" href="/{{ .Data.Plural }}/{{lower .Title}}/index.xml" title="RSS Feed"><i class="fa fa-rss" aria-hidden="true"></i> Subscribe to »{{.Title}}«</a></span>
<span class="article-rss"><a class="label label-rss" href="{{ .Permalink }}" title="RSS Feed"><i class="fa fa-rss" aria-hidden="true"></i> Subscribe to »{{ $.Title }}«</a></span>
{{- end -}}
{{ else }} {{ else }}
<span class="article-rss"><a class="label label-rss" href="/blog/index.xml" title="RSS Feed"><i class="fa fa-rss" aria-hidden="true"></i> Subscribe to all posts</a></span> <span class="article-rss"><a class="label label-rss" href="/blog/index.xml" title="RSS Feed"><i class="fa fa-rss" aria-hidden="true"></i> Subscribe to all posts</a></span>
{{ end }} {{ end }}
+14 -56
View File
@@ -1,70 +1,28 @@
{{- $authorEmail := "" }} {{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
{{- with site.Params.author }}
{{- if reflect.IsMap . }}
{{- with .email }}
{{- $authorEmail = . }}
{{- end }}
{{- end }}
{{- end }}
{{- $authorName := "" }}
{{- with site.Params.author }}
{{- if reflect.IsMap . }}
{{- with .name }}
{{- $authorName = . }}
{{- end }}
{{- else }}
{{- $authorName = . }}
{{- end }}
{{- end }}
{{- $pctx := . }}
{{- if .IsHome }}{{ $pctx = .Site }}{{ end }}
{{- $pages := slice }}
{{- if or $.IsHome $.IsSection }}
{{- $pages = $pctx.RegularPages }}
{{- else }}
{{- $pages = $pctx.Pages }}
{{- end }}
{{- $limit := .Site.Config.Services.RSS.Limit }}
{{- if ge $limit 1 }}
{{- $pages = $pages | first $limit }}
{{- end }}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel> <channel>
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ .Site.Title }}{{ with .Title }} ({{.|humanize}}){{ end }}{{ end }}</title> <title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ .Site.Title }}{{ with .Title }} ({{.|humanize}}){{ end }}{{ end }}</title>
<link>{{ .Permalink }}</link> <link>{{ .Permalink }}</link>
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description> <description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}</description>
<generator>Hugo</generator> <generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
<language>{{ site.Language.LanguageCode }}</language> <language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
{{- with $authorEmail }} <managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor> <webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
{{- end }} <copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
{{- with $authorEmail }} <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster> {{ with .OutputFormats.Get "RSS" }}
{{- end }}
{{- with .Site.Copyright }}
<copyright>{{ . }}</copyright>
{{- end }}
{{- if not .Date.IsZero }}
<lastBuildDate>{{ (index $pages.ByLastmod.Reverse 0).Lastmod.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
{{- end }}
{{- with .OutputFormats.Get "RSS" }}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }} {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{- end }} {{ end }}
{{- range $pages }} {{ range .Pages }}
<item> <item>
<title>{{ .Title }}</title> <title>{{ .Title }}</title>
<link>{{ .Permalink }}</link> <link>{{ .Permalink }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate> <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{- with $authorEmail }} {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
<author>{{.}}{{ with $authorName }} ({{.}}){{end}}</author>
{{- end }}
<guid>{{ .Permalink }}</guid> <guid>{{ .Permalink }}</guid>
<description>{{ .Summary | transform.XMLEscape | safeHTML }}</description> <description>{{ .Summary | html }}</description>
<content:encoded>{{ .Content | transform.XMLEscape | safeHTML }}</content:encoded> <content:encoded>{{ .Content | html }}</content:encoded>
</item> </item>
{{- end }} {{ end }}
</channel> </channel>
</rss> </rss>
@@ -75,10 +75,10 @@
{{ end }} {{ end }}
</div> </div>
{{ end }} {{ end }}
<!-- comments --> </div>
</div>
<hr>
{{ partial "comments" . }} {{ partial "comments" . }}
</div>
</div>
{{ partial "social" . }} {{ partial "social" . }}
</div> </div>
</div> </div>
@@ -9,13 +9,13 @@
{{- if .Params.heading -}} {{- if .Params.heading -}}
{{- $title = .Params.heading -}} {{- $title = .Params.heading -}}
{{- else -}} {{- else -}}
{{- $title = printf "%s | %s" .Title .Site.Title -}} {{- $title = print .Site.Title " | " .Title -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="author" content="{{ .Site.Params.Author.name }}" /> <meta name="author" content="{{ .Site.Params.Author }}" />
{{ with .Site.Params.description }}<meta name="description" content="{{ . }}" />{{ end }} {{ with .Site.Params.description }}<meta name="description" content="{{ . }}" />{{ end }}
{{ with .Site.Params.keywords }}<meta name="keywords" content="{{ . }}" />{{ end }} {{ with .Site.Params.keywords }}<meta name="keywords" content="{{ . }}" />{{ end }}
<link rel="shortcut icon" type="image/x-icon" href="{{ .Site.BaseURL }}img/favicon.ico" /> <link rel="shortcut icon" type="image/x-icon" href="{{ .Site.BaseURL }}img/favicon.ico" />
@@ -13,10 +13,9 @@
<!-- Theme stylesheet, combination of all in assets/scss --> <!-- Theme stylesheet, combination of all in assets/scss -->
{{- $style := resources.Get "scss/main.scss" | resources.ExecuteAsTemplate "scss/main.scss" . | toCSS (dict "targetPath" "css/main.css" "enableSourceMap" false) }} {{- $style := resources.Get "scss/main.scss" | resources.ExecuteAsTemplate "scss/main.scss" . | toCSS (dict "targetPath" "css/main.css" "enableSourceMap" false) }}
<link rel="stylesheet" href="{{ ($style).RelPermalink }}?v={{ md5 $style.Content }}"> <link rel="stylesheet" href="{{ ($style).RelPermalink }}?v={{ md5 time.Now.Unix }}">
<!-- Custom CSS --> <!-- Custom CSS -->
{{- range .Site.Params.custom_css }} {{- range .Site.Params.custom_css }}
{{- $md5 := md5 (readFile (printf "static/%s" .)) }} <link rel="stylesheet" href="{{ relURL . }}?v={{ md5 time.Now.Unix }}" />
<link rel="stylesheet" href="{{ relURL . }}?v={{ $md5 }}" />
{{- end }} {{- end }}