Skip to content

Commit a56a3e1

Browse files
authored
Merge pull request #2 from adab-tech/build/mapping-voices
Build Mapping Voices: an interactive atlas of oral-history archives
2 parents ef9373c + 9245e44 commit a56a3e1

11 files changed

Lines changed: 2538 additions & 280 deletions

File tree

.github/workflows/deploy-pages.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
# Allow manually triggering a deployment from the Actions tab.
7+
workflow_dispatch:
8+
9+
# Allow one concurrent deployment; skip runs queued behind an already-running one.
10+
concurrency:
11+
group: pages
12+
cancel-in-progress: true
13+
14+
permissions:
15+
contents: read
16+
pages: write
17+
id-token: write
18+
19+
jobs:
20+
validate:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Node.js
27+
uses: actions/setup-node@v4
28+
with:
29+
node-version: "20"
30+
31+
- name: Validate data/collections.json
32+
run: node scripts/validate-data.mjs
33+
34+
deploy:
35+
needs: validate
36+
runs-on: ubuntu-latest
37+
environment:
38+
name: github-pages
39+
url: ${{ steps.deployment.outputs.page_url }}
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@v4
43+
44+
- name: Configure Pages
45+
uses: actions/configure-pages@v5
46+
47+
- name: Upload artifact
48+
uses: actions/upload-pages-artifact@v3
49+
with:
50+
# This is a plain static site (no build step) — publish the repo root.
51+
path: .
52+
53+
- name: Deploy to GitHub Pages
54+
id: deployment
55+
uses: actions/deploy-pages@v4

README.md

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,93 @@
11
# Mapping Voices
22

3-
Digital humanities project for analyzing and visualizing mapped voice data.
3+
Mapping Voices is an interactive atlas of oral-history and voice-testimony
4+
archives. It's a single map, filterable by country, theme, language, and
5+
decade, that puts a pin on every collection in its dataset: click a pin (or
6+
use the filters) and you get a plain-language summary plus a link straight
7+
through to the real archive holding that collection.
48

5-
[![Portfolio](https://img.shields.io/badge/Adamu_Abubakar-adamu.tech-0f766e?style=flat-square)](https://adamu.tech)
6-
[![DH](https://img.shields.io/badge/Focus-Digital_Humanities-4f46e5?style=flat-square)](https://adamu.tech)
9+
It exists because oral history is scattered. National sound archives,
10+
university folklore centers, UNESCO-listed oral-tradition programs,
11+
grassroots memory projects, and things like StoryCorps or the Genocide
12+
Archive of Rwanda each publish their own holdings on their own site, with no
13+
shared, geographic way to see what's out there across all of them at once.
14+
This project is a single entry point for browsing that landscape spatially —
15+
built for digital humanities researchers, oral historians, students, and
16+
anyone else curious about oral history and voice-testimony archives, and
17+
useful today because nothing like it currently exists. It's a standalone
18+
static web app, deployed on GitHub Pages, with no backend and no build step.
719

8-
---
20+
## Running it locally
921

10-
## Overview
22+
There's no build step — it's plain HTML/CSS/JS served over `fetch()`, so any
23+
static file server works. From the repo root:
1124

12-
Mapping Voices supports exploratory analysis of voice-related humanities datasets with an accessible web front end.
25+
```bash
26+
# Python (already on most systems)
27+
python3 -m http.server 8080
28+
29+
# or Node, if you have it
30+
npx http-server -p 8080
31+
32+
# or PHP
33+
php -S localhost:8080
34+
```
35+
36+
Then open `http://localhost:8080`. Opening `index.html` directly via
37+
`file://` won't work — the app fetches `data/collections.json` at runtime,
38+
and browsers block `fetch()` against `file://` URLs.
39+
40+
## The seed dataset
1341

14-
## Features
42+
`data/collections.json` holds the map's data: about 30 entries covering
43+
real, publicly documented oral-history and voice-testimony collections, with
44+
real institutions and a real, working link to each collection's own public
45+
page. No fictional archives, testimonies, or recordings are included — if an
46+
entry couldn't be verified as real, it isn't here. The set deliberately
47+
spans every inhabited continent, with particular attention to Niger and the
48+
wider Sahel/West Africa region (Niger's CELHTO and IRSH, Mali's Sunjata-epic
49+
field recordings, Guinea's Sosso-Bala griot tradition, Nigeria's Ifa corpus,
50+
Benin/Nigeria/Togo's Gelede heritage, Senegal's IFAN sound archives, Ghana's
51+
Nketia Archives), since that region is under-represented in most general
52+
oral-history tool demos and this project grew out of Hausa/Sahel-region
53+
digital humanities research.
1554

16-
- Interactive maps and narrative views
17-
- Static, deployable HTML/JS assets
18-
- Research-oriented presentation layer
55+
**This is a curated, illustrative starting set — not an exhaustive index.**
56+
There are hundreds of oral-history and voice-archive collections worldwide
57+
that aren't in here yet. See `data/schema-notes.md` for the full field
58+
reference and the exact steps for adding a new entry (in short: confirm it's
59+
real, add an object matching the schema, run
60+
`node scripts/validate-data.mjs`, and fix anything it flags before opening a
61+
PR).
1962

20-
## Quick start
63+
## Validating the data
2164

2265
```bash
23-
git clone https://github.com/adab-tech/mapping.git
24-
cd mapping
25-
# Serve locally, e.g. npx http-server -p 8080
66+
node scripts/validate-data.mjs
2667
```
2768

28-
## Author
69+
Zero dependencies — plain Node built-ins only, no `npm install` needed. It
70+
checks that every entry has its required fields, that `lat`/`lng` are real
71+
coordinates, that every `id` is unique, that `url` is well-formed, and that
72+
array fields aren't empty, and exits non-zero with a specific message per
73+
problem found. The same check runs in CI on every push, via
74+
`.github/workflows/deploy-pages.yml`.
2975

30-
**Adamu Abubakar** · [adamu.tech](https://adamu.tech) · [contact@adamu.tech](mailto:contact@adamu.tech)
76+
## Deployment
77+
78+
Pushing to `main` runs `.github/workflows/deploy-pages.yml`, which validates
79+
`data/collections.json` and then publishes the repository root to GitHub
80+
Pages via `actions/upload-pages-artifact` and `actions/deploy-pages`. No
81+
build step is involved.
82+
83+
## Project layout
84+
85+
```
86+
index.html entry point
87+
css/style.css styles
88+
js/app.js map + filtering logic
89+
data/collections.json the seed dataset (see above)
90+
data/schema-notes.md schema reference + how to add an entry
91+
scripts/validate-data.mjs zero-dependency data validator
92+
.github/workflows/deploy-pages.yml GitHub Pages deployment
93+
```

SPEC.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Mapping Voices — build spec
2+
3+
## What this is
4+
A static, client-side web app (no backend, no build step, deployable via GitHub Pages)
5+
that lets people explore oral-history / voice-testimony collections on an interactive
6+
map — filterable by country, theme, language, and decade.
7+
8+
## The 5 Ws (why this exists)
9+
- **Who**: digital humanities researchers, oral historians, students, and the public
10+
interested in oral history and voice-testimony archives.
11+
- **What**: an interactive atlas — a world map with pins for real, publicly documented
12+
oral-history/voice-archive collections; click a pin (or use the filters) to see a
13+
summary and a link to the actual source archive.
14+
- **When**: now — no tool like this exists in this account, and it directly serves
15+
active digital-humanities/oral-history research interests.
16+
- **Where**: a standalone static web app, deployed on GitHub Pages.
17+
- **Why**: oral history and voice-testimony collections are scattered across dozens of
18+
institutional archives with no shared, geographic way to browse what exists — this
19+
gives that a single entry point.
20+
21+
## Data honesty rule (important)
22+
The seed dataset must describe **real, publicly documented oral-history/voice-archive
23+
collections** (e.g. national sound archives, university oral history projects, UNESCO-
24+
listed oral tradition collections, StoryCorps, etc.) with accurate metadata and a real
25+
link to the actual collection/archive page. Do not invent fictional testimonies,
26+
recordings, or archives. It's a *seed/demo dataset* meant to make the tool immediately
27+
useful and honest, not an exhaustive index — the README must say so explicitly and
28+
explain how to add more entries.
29+
30+
## Data schema (`data/collections.json`)
31+
A JSON array of objects, each shape:
32+
```json
33+
{
34+
"id": "string, kebab-case, unique",
35+
"title": "string — the collection's real name",
36+
"archive": "string — the holding institution's real name",
37+
"country": "string — ISO-ish common name, e.g. 'Niger', 'United States'",
38+
"lat": "number",
39+
"lng": "number",
40+
"languages": ["array of strings, e.g. ['Hausa', 'French']"],
41+
"themes": ["array of strings, e.g. ['migration', 'oral tradition', 'women's history']"],
42+
"decade_start": "number, e.g. 1990",
43+
"decade_end": "number or null if ongoing",
44+
"summary": "1-3 sentences, plain language, on what the collection actually contains",
45+
"url": "string — a real, working URL to the collection or archive's public page"
46+
}
47+
```
48+
Aim for ~25-30 entries with real geographic and thematic spread — don't cluster
49+
everything in one region. Include several African/Sahel-region entries (Niger and
50+
neighboring countries) alongside collections from other continents, since that region
51+
is currently under-represented in most general "oral history" tool demos.
52+
53+
## Frontend contract
54+
The frontend reads `data/collections.json` via `fetch('data/collections.json')` — a
55+
plain relative path, no build step, works both locally (via any static server) and on
56+
GitHub Pages. Do not hardcode the dataset into the JS/HTML.
57+
58+
## File layout (fixed — do not deviate, this is how the two build tracks stay non-conflicting)
59+
```
60+
index.html
61+
css/style.css
62+
js/app.js
63+
data/collections.json
64+
data/schema-notes.md (short doc: how to add a new entry)
65+
.github/workflows/deploy-pages.yml
66+
README.md
67+
scripts/validate-data.mjs (Node, zero-dependency, checks collections.json against the schema)
68+
```
69+
70+
## Design direction
71+
Editorial, atlas-like — not a generic SaaS dashboard. Think: a printed atlas or a
72+
research archive's reading room, rendered for the web. A serif display face for
73+
titles, a neutral sans for UI chrome. Muted, paper-like background tones (not stark
74+
white, not dark-mode-first) with one confident accent color for map pins/active
75+
states. Real typographic hierarchy. The map is the hero — everything else (filters,
76+
detail panel) supports it without competing with it.
77+
78+
## Map library
79+
Use Leaflet.js loaded from a CDN (no API key required, unlike Google Maps) with the
80+
OpenStreetMap tile layer (free, no key, attribution required per their terms — include
81+
it, it's a one-line requirement).
82+
83+
## Accessibility & responsiveness
84+
- Filters and the detail panel must be fully keyboard-operable.
85+
- Map pins need accessible labels (not just visual markers).
86+
- Must work down to a 375px-wide mobile viewport: map on top, filters/detail panel
87+
stack below or slide in as a drawer — your call on the exact pattern, but no
88+
horizontal overflow at any width.
89+
90+
## Deployment
91+
`.github/workflows/deploy-pages.yml` — a GitHub Actions workflow using
92+
`actions/upload-pages-artifact` + `actions/deploy-pages` to publish the repo root
93+
(or a `/docs` folder if you prefer — pick one and be consistent with the file layout
94+
above) to GitHub Pages on every push to `main`. No build step needed since this is
95+
plain HTML/CSS/JS.

0 commit comments

Comments
 (0)