Sommige gegevens heeft niet één huishouden, maar iedereen die MealieShopper gebruikt: een lijst die je samen bijhoudt, een koppeling die iemand al eens heeft uitgezocht. Die horen op één vaste plek, waar ze voor iedereen op hetzelfde adres staan, en waar niets bij komt zonder dat iemand het heeft bekeken. Deze repository is die plek. Je stuurt een bestand in met een pull request; een controle laat zien wat er op de site verandert, ook wat er in een zip zit; de eigenaar keurt het goed, en daarna staat het vanzelf online.
.json of .zip: één document, of een zip met veel documenten tegelijk, rechtstreeks vanuit de browser.publicatie en op data.mealieshopper.nl, met een catalogus in index.json.schemas/ bepaal je wat er in een collectie mag.Alles staat op https://data.mealieshopper.nl. Begin bij de catalogus:
curl https://data.mealieshopper.nl/index.json
{
"site": "https://data.mealieshopper.nl",
"generated_at": "2026-11-07T10:00:00Z",
"commit": "…",
"collections": [
{
"name": "recepten",
"title": "Recepten",
"description": "…",
"schema": "https://data.mealieshopper.nl/schemas/recepten.schema.json",
"files": [
{ "path": "recepten/soepen.json", "url": "https://data.mealieshopper.nl/recepten/soepen.json",
"bytes": 2048, "sha256": "…", "items": 12 }
]
}
]
}
https://data.mealieshopper.nl/<collectie>/<bestand>.json.items is het aantal items als het document een lijst is, anders null.sha256 hoort bij het bestand zoals het op de site staat. Wil je zeker weten dat je een bepaalde versie hebt, vergelijk dan die.commit en generated_at horen bij de laatste wijziging aan de gegevens.Access-Control-Allow-Origin: * mee, dus een webapp kan alles rechtstreeks ophalen.Je hebt een GitHub-account nodig, verder niets.
data/, bijvoorbeeld data/recepten/. Bestaat hij nog niet, maak hem dan in je pull request (een nieuwe collectie heeft liefst ook een schema, zie schemas/)..json- of .zip-bestand erin.| Regel | Waarom |
|---|---|
Alleen .json, of een .zip met alleen .json |
Wat erin staat, moet te controleren zijn. Wat zip-programma’s zelf toevoegen (__MACOSX/, .DS_Store) slaan we over. |
Een document hoort in een collectie: data/<collectie>/…/<naam>.json |
De eerste map is de collectie. |
Namen van collecties: kleine letters, cijfers en - (niet schemas). Bestandsnamen: letters, cijfers, ., - en _, zonder spaties |
Elk pad is ook een webadres. |
Een zip pakt uit waar hij staat: data/recepten/bundel.zip met a.json erin wordt recepten/a.json |
Zo stuur je veel bestanden tegelijk in. Een zip direct in data/ heeft de collecties als mappen in zich. |
| Elk pad op de site komt uit één bestand, ook als je hoofdletters negeert | Twee bronnen voor hetzelfde adres kunnen niet allebei winnen. |
Strikte JSON: UTF-8, geen dubbele sleutels, geen NaN, bovenaan een object of een lijst |
Een dubbele sleutel verdwijnt ongemerkt. |
Voldoet aan schemas/<collectie>.schema.json, als die er is |
Daarmee bepaalt een collectie zelf wat erin mag. |
Geen sleutels die op een geheim wijzen (token, api_key, password, secret, cookie, …) |
Alles hier is openbaar. |
| Hoogstens 10 MB per document, 25 MB per zip, 100 MB uitgepakt per zip en 2000 bestanden per zip | 25 MB is ook de grens van GitHub voor een bestand dat je in de browser toevoegt. |
| Gegevens en code niet in één pull request | Een inzending kan de controle die haar keurt niet veranderen. |
main met bestanden in data/ (en eventueel een schema in schemas/).main zou staan, met de regels en de code van main (niet die van de pull request), en zet in de samenvatting wat er op de site verandert. De check Tests draait de tests.main: elk document uitgepakt en opgemaakt, de schema’s, index.json en een overzichtspagina. Dat zet hij als nieuwe commit op de branch publicatie en rolt hij uit naar GitHub Pages, op data.mealieshopper.nl.main bewaart de bestanden zoals ze goedgekeurd zijn, ook een zip. Wil je ze in main liever als losse bestanden, pak een zip dan uit met python scripts/datastore.py unpack data/<collectie>/<bestand>.zip en stuur dat in als pull request. Op de site verandert er dan niets.
Eenmalig, door de eigenaar, in de instellingen van de repository op GitHub.
main als standaardbranch. Maak de branch main (als die er nog niet is) en zet hem onder Settings → General → Default branch.data.mealieshopper.nl in en zet Enforce HTTPS aan. Pages voor een private repository vraagt GitHub Pro of een betaald abonnement; de site zelf is altijd openbaar.CNAME-record voor data.mealieshopper.nl naar helmerznl.github.io.main (Settings → Rules → Rulesets, of Branches):
CODEOWNERS);Bescherm de branch publicatie niet op een manier die github-actions[bot] tegenhoudt: alleen de workflow schrijft erin.
Je kunt je eigen pull request op GitHub niet goedkeuren. Stuur je zelf iets in, dan voeg je als beheerder samen met Merge without waiting for requirements to be met, nadat de checks groen zijn.
| Taak | Hoe |
|---|---|
| Een inzending goedkeuren | De pull request, Files changed en de samenvatting van Inzending controleren bekijken, dan Review changes → Approve en samenvoegen |
| Iets van de site halen | Een pull request die het bestand uit data/ verwijdert (of de zip waar het in zit vervangt) |
| Een publicatie terugdraaien | De pull request terugdraaien met Revert en die samenvoegen; de site volgt main |
| Opnieuw publiceren | Actions → Publiceren → Run workflow |
| Lokaal controleren | python -m pip install -r requirements.txt, dan python scripts/datastore.py check |
| Lokaal de site bouwen | python scripts/datastore.py build --out _site en open _site/index.html |
GET https://data.mealieshopper.nl/index.json antwoordt 200 met de catalogus.| Waar | Wat erin staat |
|---|---|
main, map data/ |
De goedgekeurde bestanden, zoals ze ingestuurd zijn |
main, map schemas/ |
Het JSON Schema per collectie |
Branch publicatie |
De gepubliceerde site: alles uitgepakt en opgemaakt, met index.json. Elke publicatie is een commit |
| GitHub Pages | Dezelfde site, op data.mealieshopper.nl |
De repository is de back-up: elke inzending en elke publicatie staat in de geschiedenis van git. publicatie en de site zijn altijd opnieuw te maken uit main (Run workflow). Een kopie maak je met git clone --mirror.
flowchart LR
I[Inzender] -->|pull request<br/>.json of .zip| PR[Pull request naar main]
PR --> C[Inzending controleren<br/>en Tests]
C -->|samenvatting| E[Eigenaar keurt goed<br/>en voegt samen]
E --> M[(main: data/, schemas/)]
M --> P[Publiceren]
P --> B[(branch publicatie)]
P --> G[GitHub Pages<br/>data.mealieshopper.nl]
G --> A[MealieShopper en<br/>andere gebruikers]
| Onderdeel | Doel |
|---|---|
scripts/datastore.py |
check, build en unpack: alle regels staan hier. Python met alleen jsonschema erbij |
inzending.yml |
Inzending controleren, met de code van main (pull_request_target); voert niets uit wat de pull request meebrengt |
controleren.yml |
Tests, met de code van de pull request |
publiceren.yml |
Bouwen, op publicatie zetten en naar GitHub Pages |
site/ |
De overzichtspagina en het logo |
Gegevens insturen staat hierboven. Een wijziging aan de code (de controle, de site, de workflows) gaat in een eigen pull request naar main, nooit samen met gegevens. De werkafspraken voor mensen en AI-hulpen staan in AGENTS.md.
python -m pip install -r requirements.txt
python -m unittest discover -s tests
python scripts/datastore.py check
main, niet die van de pull request, en leest de ingestuurde bestanden alleen. Een zip met .., een absoluut pad, een symbolische koppeling of een wachtwoord wordt geweigerd, net als een zip die uitgepakt te groot wordt.MealieShopper is gratis. Heb je er iets aan? Met een koffie houd je de ontwikkeling gaande.
Er is nog geen licentie gekozen voor de gegevens of de code: alle rechten voorbehouden.