Replace data/issues.json with content/_index.md files per issue
Issue metadata (title, description, season, status) now lives in content/issues/XX/_index.md. terms.html reads from those pages via $.Site.GetPage, driven by issueIds param in hugo.toml. Removes the JSON data file and its generation from import-posts.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "The Glasshouse"
|
||||||
|
description: "A study in transparency, condensation, and the long late light of June."
|
||||||
|
issueNumber: "№ 02"
|
||||||
|
season: "Summer MMXXVI"
|
||||||
|
status: "forthcoming"
|
||||||
|
---
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "Atelier After Hours"
|
||||||
|
description: "The slow work of cloth and thread, photographed when the studio is half-empty."
|
||||||
|
issueNumber: "№ 03"
|
||||||
|
season: "Autumn MMXXVI"
|
||||||
|
status: "forthcoming"
|
||||||
|
---
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"id": "01",
|
|
||||||
"number": "\u2116 01",
|
|
||||||
"title": "Fabric, Light & Gesture",
|
|
||||||
"season": "Spring MMXXVI",
|
|
||||||
"publishedAt": "2026-03-21",
|
|
||||||
"blurb": "The inaugural plates \u2014 one hundred photographs gathered across ateliers, streets, and quiet hotel corridors.",
|
|
||||||
"status": "current"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "02",
|
|
||||||
"number": "\u2116 02",
|
|
||||||
"title": "The Glasshouse",
|
|
||||||
"season": "Summer MMXXVI",
|
|
||||||
"publishedAt": "2026-06-21",
|
|
||||||
"blurb": "Forthcoming \u2014 a study in transparency, condensation, and the long late light of June.",
|
|
||||||
"status": "forthcoming"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "03",
|
|
||||||
"number": "\u2116 03",
|
|
||||||
"title": "Atelier After Hours",
|
|
||||||
"season": "Autumn MMXXVI",
|
|
||||||
"publishedAt": "2026-09-22",
|
|
||||||
"blurb": "Forthcoming \u2014 the slow work of cloth and thread, photographed when the studio is half-empty.",
|
|
||||||
"status": "forthcoming"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -21,6 +21,7 @@ term = ["HTML"]
|
|||||||
[params]
|
[params]
|
||||||
description = "Roux is a slow-publishing fashion journal — one hundred photographs at a time. Editorial, couture, beauty and backstage plates."
|
description = "Roux is a slow-publishing fashion journal — one hundred photographs at a time. Editorial, couture, beauty and backstage plates."
|
||||||
author = "Roux Editorial"
|
author = "Roux Editorial"
|
||||||
|
issueIds = ["01", "02", "03"]
|
||||||
issueNumber = "01"
|
issueNumber = "01"
|
||||||
issueName = "Fabric, Light & Gesture"
|
issueName = "Fabric, Light & Gesture"
|
||||||
issueSeason = "Spring MMXXVI"
|
issueSeason = "Spring MMXXVI"
|
||||||
|
|||||||
+12
-12
@@ -1,5 +1,4 @@
|
|||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
{{- $issues := .Site.Data.issues }}
|
|
||||||
<section id="hero" class="px-[var(--pad)] pt-[clamp(36px,5vw,64px)] pb-[clamp(28px,3.5vw,48px)] border-b border-[var(--rule)]">
|
<section id="hero" class="px-[var(--pad)] pt-[clamp(36px,5vw,64px)] pb-[clamp(28px,3.5vw,48px)] border-b border-[var(--rule)]">
|
||||||
<div class="font-sans font-medium text-[10px] leading-none tracking-[.22em] uppercase text-ink-soft mb-4">Archive · Every issue</div>
|
<div class="font-sans font-medium text-[10px] leading-none tracking-[.22em] uppercase text-ink-soft mb-4">Archive · Every issue</div>
|
||||||
<h1 class="font-display font-normal text-[clamp(48px,7vw,96px)] leading-[0.94] m-0 mb-4">The <em>issues</em></h1>
|
<h1 class="font-display font-normal text-[clamp(48px,7vw,96px)] leading-[0.94] m-0 mb-4">The <em>issues</em></h1>
|
||||||
@@ -9,11 +8,13 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="grid [grid-template-columns:repeat(auto-fill,minmax(280px,1fr))] gap-[var(--gap)] px-[var(--pad)] py-[var(--gap)]">
|
<div class="grid [grid-template-columns:repeat(auto-fill,minmax(280px,1fr))] gap-[var(--gap)] px-[var(--pad)] py-[var(--gap)]">
|
||||||
{{- range $i, $iss := $issues }}
|
{{- range $i, $id := $.Site.Params.issueIds }}
|
||||||
|
{{- $iss := $.Site.GetPage (printf "/issues/%s" $id) }}
|
||||||
|
{{- if not $iss }}{{- continue }}{{- end }}
|
||||||
|
{{- $isCurrent := eq $iss.Params.status "current" }}
|
||||||
|
{{- $isForth := eq $iss.Params.status "forthcoming" }}
|
||||||
|
{{- $issueURL := printf "/issues/%s/" $id }}
|
||||||
{{- $delay := mul $i 80 }}
|
{{- $delay := mul $i 80 }}
|
||||||
{{- $isCurrent := eq $iss.status "current" }}
|
|
||||||
{{- $isForth := eq $iss.status "forthcoming" }}
|
|
||||||
{{- $issueURL := printf "/issues/%s/" $iss.id }}
|
|
||||||
|
|
||||||
{{- if $isForth }}
|
{{- if $isForth }}
|
||||||
<div data-issue-card style="--d:{{ $delay }}ms"
|
<div data-issue-card style="--d:{{ $delay }}ms"
|
||||||
@@ -34,15 +35,14 @@
|
|||||||
Forthcoming
|
Forthcoming
|
||||||
</div>
|
</div>
|
||||||
{{- else }}
|
{{- else }}
|
||||||
{{- $termPage := $.Site.GetPage (printf "/issues/%s" $iss.id) }}
|
{{- $firstPost := index $iss.Pages 0 }}
|
||||||
{{- $firstPost := cond (ne $termPage nil) (index $termPage.Pages 0) nil }}
|
|
||||||
{{- if $firstPost }}
|
{{- if $firstPost }}
|
||||||
{{- $img := $firstPost.Resources.GetMatch "*.png" }}
|
{{- $img := $firstPost.Resources.GetMatch "*.png" }}
|
||||||
{{- if $img }}
|
{{- if $img }}
|
||||||
{{- $cover := $img.Resize "480x720 webp" }}
|
{{- $cover := $img.Resize "480x720 webp" }}
|
||||||
<picture>
|
<picture>
|
||||||
<source srcset="{{ $cover.RelPermalink }}" type="image/webp" />
|
<source srcset="{{ $cover.RelPermalink }}" type="image/webp" />
|
||||||
<img src="{{ $cover.RelPermalink }}" alt="Issue {{ $iss.number }} cover" loading="lazy"
|
<img src="{{ $cover.RelPermalink }}" alt="Issue {{ $iss.Params.issueNumber }} cover" loading="lazy"
|
||||||
class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.02]" />
|
class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.02]" />
|
||||||
</picture>
|
</picture>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
@@ -51,11 +51,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{/* Metadata */}}
|
{{/* Metadata */}}
|
||||||
<div class="font-sans font-medium text-[10px] leading-none tracking-[.22em] uppercase text-roux mb-2">{{ $iss.number }}</div>
|
<div class="font-sans font-medium text-[10px] leading-none tracking-[.22em] uppercase text-roux mb-2">{{ $iss.Params.issueNumber }}</div>
|
||||||
<h2 class="font-display font-normal text-[clamp(22px,2vw,30px)] leading-[1.05] m-0 mb-2">{{ $iss.title }}</h2>
|
<h2 class="font-display font-normal text-[clamp(22px,2vw,30px)] leading-[1.05] m-0 mb-2">{{ $iss.Title }}</h2>
|
||||||
<p class="font-serif italic text-[13px] leading-[1.5] text-ink-soft mb-4 flex-1">{{ $iss.blurb }}</p>
|
<p class="font-serif italic text-[13px] leading-[1.5] text-ink-soft mb-4 flex-1">{{ $iss.Params.description }}</p>
|
||||||
<div class="flex items-center justify-between font-sans text-[11px] leading-none tracking-[.1em] text-ink-soft mt-auto pt-4 border-t border-[var(--rule-2)]">
|
<div class="flex items-center justify-between font-sans text-[11px] leading-none tracking-[.1em] text-ink-soft mt-auto pt-4 border-t border-[var(--rule-2)]">
|
||||||
<span>{{ $iss.season }}</span>
|
<span>{{ $iss.Params.season }}</span>
|
||||||
{{- if $isCurrent }}
|
{{- if $isCurrent }}
|
||||||
<span class="text-ink">Read the issue →</span>
|
<span class="text-ink">Read the issue →</span>
|
||||||
{{- else if $isForth }}
|
{{- else if $isForth }}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ Only imports posts whose generated_image exists in the selected images folder.
|
|||||||
Run from the site root: python3 scripts/import-posts.py
|
Run from the site root: python3 scripts/import-posts.py
|
||||||
"""
|
"""
|
||||||
import csv
|
import csv
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -15,10 +14,8 @@ CSV_PATH = GINGER / "posts.csv"
|
|||||||
IMG_DIR = GINGER / "images" / "final" / "selected"
|
IMG_DIR = GINGER / "images" / "final" / "selected"
|
||||||
SITE = Path(__file__).parent.parent
|
SITE = Path(__file__).parent.parent
|
||||||
CONTENT = SITE / "content" / "posts"
|
CONTENT = SITE / "content" / "posts"
|
||||||
DATA_DIR = SITE / "data"
|
|
||||||
|
|
||||||
CONTENT.mkdir(parents=True, exist_ok=True)
|
CONTENT.mkdir(parents=True, exist_ok=True)
|
||||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
# Collect available images
|
# Collect available images
|
||||||
available = {f.name for f in IMG_DIR.iterdir() if f.is_file()}
|
available = {f.name for f in IMG_DIR.iterdir() if f.is_file()}
|
||||||
@@ -82,36 +79,3 @@ tags:
|
|||||||
(bundle / "index.md").write_text(md, encoding="utf-8")
|
(bundle / "index.md").write_text(md, encoding="utf-8")
|
||||||
|
|
||||||
print(f"Created {len(matched)} page bundles in {CONTENT}")
|
print(f"Created {len(matched)} page bundles in {CONTENT}")
|
||||||
|
|
||||||
# Write data/issues.json
|
|
||||||
issues = [
|
|
||||||
{
|
|
||||||
"id": "01",
|
|
||||||
"number": "№ 01",
|
|
||||||
"title": "Fabric, Light & Gesture",
|
|
||||||
"season": "Spring MMXXVI",
|
|
||||||
"publishedAt": "2026-03-21",
|
|
||||||
"blurb": "The inaugural plates — one hundred photographs gathered across ateliers, streets, and quiet hotel corridors.",
|
|
||||||
"status": "current"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "02",
|
|
||||||
"number": "№ 02",
|
|
||||||
"title": "The Glasshouse",
|
|
||||||
"season": "Summer MMXXVI",
|
|
||||||
"publishedAt": "2026-06-21",
|
|
||||||
"blurb": "Forthcoming — a study in transparency, condensation, and the long late light of June.",
|
|
||||||
"status": "forthcoming"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "03",
|
|
||||||
"number": "№ 03",
|
|
||||||
"title": "Atelier After Hours",
|
|
||||||
"season": "Autumn MMXXVI",
|
|
||||||
"publishedAt": "2026-09-22",
|
|
||||||
"blurb": "Forthcoming — the slow work of cloth and thread, photographed when the studio is half-empty.",
|
|
||||||
"status": "forthcoming"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
(DATA_DIR / "issues.json").write_text(json.dumps(issues, indent=2), encoding="utf-8")
|
|
||||||
print("Wrote data/issues.json")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user