Geen omschrijving
  • Jinja 35.8%
  • JavaScript 32.8%
  • Python 15.2%
  • CSS 14.9%
  • Dockerfile 0.7%
  • Andere 0.6%
Zoek een bestand
2026-07-21 13:31:32 +02:00
_data usercentrics settings-id bijgewerkt (nkDOL7Eaf0A__w → YJIjhYsutQlo2D) 2026-07-19 23:15:11 +02:00
_templates usercentrics web cmp ingebouwd (eigen cookie-banner via toggle uit) 2026-07-19 23:08:24 +02:00
admin selfhost decap-cms + marked + dompurify (geen cdn-dependency meer) 2026-06-06 19:55:18 +02:00
assets Upload “assets/img/achtergrond_sekondant.jpeg” 2026-07-21 13:31:32 +02:00
content Update Pagina “home” 2026-06-02 20:12:48 +02:00
.dockerignore deploy via coolify ipv forgejo actions 2026-06-01 20:45:57 +02:00
.gitignore deploy via coolify ipv forgejo actions 2026-06-01 20:45:57 +02:00
build.py security-hardening: autoescape, scheme-validatie, slug-validatie, dompurify 2026-06-05 11:00:54 +02:00
Dockerfile mature cms: pdf-blok, downloads, 6 nieuwe blok-types, seo-pakket, nieuws-uitbreiding 2026-06-02 09:03:52 +02:00
nginx.conf hsts toegevoegd (max-age 1 jaar, includeSubDomains) 2026-06-05 11:02:22 +02:00
pentest-rapport-sekondant.pdf pentest-rapport: hoofdstuk 5 tabel compacter (8pt cellen via Paragraph, smallere kolommen, repeatRows=1 voor auto-split bij overflow) 2026-06-05 11:18:43 +02:00
README.md ai-assistent verwijderd 2026-06-05 07:10:03 +02:00
requirements.txt cookiebanner + image-pipeline + ai-assistent 2026-06-02 10:17:35 +02:00

Sekondant — statische site + CMS

Deze repo bevat de website sekondant.je-ma.com: een set statische HTML-pagina's die uit content-bestanden gegenereerd wordt, met een web-admin (Decap CMS) zodat de content zonder code-kennis bewerkt kan worden. Gedeployed via Coolify.

SekWebsite/
├── content/                  ← *** wat je bewerkt ***  (YAML + Markdown)
│   ├── index.yml             ← homepage
│   ├── welkom.yml
│   ├── voor-wie-werken-wij.yml
│   ├── zaalhuur.yml
│   ├── vacatures.yml
│   ├── route.yml
│   ├── contact.yml
│   ├── pagina/               ← extra pagina's (zelf aanmaken via CMS)
│   ├── juridisch/            ← juridische pagina's (folder-collectie)
│   └── nieuws/               ← nieuwsberichten (folder-collectie)
├── _data/site.yml            ← menu's, logo, footer, copyright, badges
├── _templates/
│   ├── base.html.j2          ← gedeelde HTML-skelet (nav + footer)
│   ├── _blocks.html.j2       ← block-render-macro (tekst, foto, kaarten…)
│   ├── _icons.html.j2        ← SVG-iconenset
│   └── *.html.j2             ← per pagina-type
├── assets/                   ← CSS, JS, afbeeldingen
├── admin/                    ← Decap CMS web-admin (op /admin/)
│   ├── index.html            ← laadt decap-cms + marked + preview.js
│   ├── config.yml            ← schema voor alle pagina's
│   └── preview.js            ← live preview (huisstijl + per-pagina rendering)
├── build.py                  ← genereert _site/ uit content/ + templates
├── requirements.txt          ← Python-deps
├── Dockerfile                ← multi-stage build: Python → nginx
└── .dockerignore

Wat je via de web-admin kan

Open https://sekondant.je-ma.com/admin/, log in via Forgejo. Linkerzijbalk:

Collectie Wat erin staat
Hoofdpagina's De zeven vaste pagina's met hun eigen layout (homepage, welkom, voor wie, zaalhuur, vacatures, route, contact). Elk veld heeft uitleg-hint en list-summary.
Extra pagina's Maak nieuwe pagina's met een vrij in te delen layout via blokken. Zie hieronder.
Nieuws Nieuwsberichten met datum, samenvatting en body. URL automatisch /nieuws/2026-06-01-titel.html. Archief op /nieuws.html regenereert zichzelf.
Juridische pagina's Cookieverklaring, privacy, toegankelijkheid, CVD. Folder-collectie: nieuwe disclosures toevoegen kan met "New".
Site-instellingen Logo, slogan, footer-copyright, badges (meerdere mogelijk), hoofdmenu, juridische footer-links.

Live preview

Rechts van het formulier verschijnt een echte preview van de pagina met de huisstijl (blauwe kleuren, Open Sans, info-cards, etc.). De preview update terwijl je typt voor:

  • Alle Hoofdpagina's (homepage met hero + 4 kaarten, welkom met media-split + service-grid, voor wie werken wij met partner-blokken, zaalhuur met vergaderzaaltabel, etc.)
  • Extra pagina's (met of zonder blokken)
  • Nieuws-berichten
  • Juridische pagina's

Block-based content (Extra pagina's)

Bij het bewerken zie je een Pagina-indeling-veld waarin je losse blokken plakt en sleept om de volgorde te bepalen. 19 blok-types beschikbaar:

Categorie Blok Wanneer gebruiken
Basis Tekst, Lead, Tussenkop Doorlopende paragrafen, intro-zin, of H2/H3 om een sectie te beginnen.
Media Afbeelding, Galerij, Video Foto's of YouTube/Vimeo-embed.
Layout Tekst + foto, Kaarten-grid, Tabel Media-split, 2/3/4 kaarten met icoon, of een eigen tabel.
Interactie CTA, Formulier, FAQ Knop-rij, Formspree-formulier, of openklap-vragen.
Storytelling Timeline, Testimonial Mijlpalen op een tijdlijn of een citaat.
Commercieel Prijstabel Pakketten met prijs, kenmerken en knop.
Accenten Aandachtsblok, Scheidingslijn Gekleurd kader voor aankondiging, of horizontale scheiding.
Downloads PDF-download Klikbare kaart met PDF-icoon en download-pijl.
Escape Eigen HTML Embeds (Google Maps iframe etc.) — pas op met onbekende bronnen.

Voor simpele pagina's kun je in plaats van blokken het "Simpele tekst"-veld gebruiken (alleen actief als er géén blokken zijn).

Nieuws-functies

  • Tags: per bericht meerdere tags. Verschijnen als chips bovenaan; klikken filtert het archief op /nieuws/tag/<tag>.html.
  • Vastpinnen: bericht blijft altijd bovenaan in het archief.
  • Downloads onderaan: lijst van PDFs in een aparte download-sectie.
  • Gerelateerde berichten: automatisch onder elk bericht op basis van overlappende tags (top 3).
  • RSS-feed op /nieuws/feed.xml met de laatste 50 berichten.

Concept / verbergen

Elke pagina, juridische pagina en nieuwsbericht heeft een Gepubliceerd?-toggle. Zet uit → niet zichtbaar op de site (ook niet in archief, RSS of sitemap). Handig om een bericht voor te bereiden en later te publiceren.

SEO per pagina

  • SEO-beschrijving (<meta description>) op elke pagina
  • Sociale-media voorbeeldafbeelding (Open Graph og:image) — wordt getoond bij delen op LinkedIn/Twitter/Facebook
  • Verbergen voor zoekmachines (noindex) per pagina
  • Auto-gegenereerd: /sitemap.xml, /robots.txt, JSON-LD voor Organization
    • BreadcrumbList op elke pagina

Naast ISO 27001 kun je via Site-instellingen → Badges in de footer logo's toevoegen — lidmaatschappen, partnerschappen, andere certificeringen. Per badge: afbeelding, alt-tekst, en optionele klikbare link.

Naast ISO 27001 kun je via Site-instellingen → Badges in de footer logo's toevoegen — lidmaatschappen, partnerschappen, andere certificeringen. Per badge: afbeelding, alt-tekst, en optionele klikbare link.

Content lokaal bewerken

pip install -r requirements.txt   # eerste keer
python3 build.py                  # output -> _site/
python3 -m http.server 8080 -d _site
# open http://localhost:8080

Deploy via Coolify

  1. Resource → New → Public/Private Repository. Verbind met code.securityasaservice.org/Sek/SekWebsite.git, branch main.
  2. Build pack: Dockerfile. Coolify detecteert de Dockerfile in de root.
  3. Domain: sekondant.je-ma.com. TLS-toggle aan.
  4. Ports Exposed: 80 (default 3000 werkt niet voor nginx).
  5. Webhook: in Forgejo bij Settings → Webhooks → Add (Gitea) plak de Coolify deploy-webhook URL. Trigger op Push events, branch main.
  6. Deploy.

Eenmalige setup in Forgejo (voor Decap CMS)

A. OAuth-applicatie

  1. User Settings → Applications → Create New OAuth2 Application
  2. Vul in:
    • Application Name: Sekondant CMS
    • Redirect URIs: https://sekondant.je-ma.com/admin/
    • Vink Confidential client uit (PKCE)
  3. Plak de Client ID in admin/config.yml bij app_id:.

B. CORS via een Caddy-sidecar

Forgejo's eigen [cors]-config werkt niet voor het OAuth-token-endpoint. Daarom loopt /login/oauth/access_token en /api/v1/* via een mini Caddy-proxy die preflights afhandelt en de juiste headers injecteert.

In de Compose-stack van Forgejo staat een service forgejo-cors (Caddy:2-alpine) op het zelfde netwerk. In Traefik gaat alleen die ene host+path-combinatie via Caddy; de rest van Forgejo loopt rechtstreeks. Zie de docker-compose voor de exacte labels.

Hoe de auto-deploy werkt

Redacteur bewerkt in Decap
        │
        ▼
Decap commit content/* naar main (Forgejo API via Caddy-CORS)
        │
        ▼
Forgejo webhook -> Coolify
        │
        ▼
Coolify docker build:
   stage 1: python -> build.py -> /site
   stage 2: nginx serveert /site op poort 80
        │
        ▼
sekondant.je-ma.com toont de nieuwe pagina

Wat staat waar?

Wil je aanpassen… Bewerk dan…
Hoofdmenu / footer-links _data/site.yml (of CMS → Site-instellingen)
Logo, copyright, slogan, badges _data/site.yml
Hero-tekst / -afbeeldingen content/index.ymlhero:
4 kaarten op homepage content/index.ymlcards:
Partner-info (Movisie/NJi/Vilans) content/voor-wie-werken-wij.yml
Vergaderzaaltabel content/zaalhuur.ymlrooms_table:
Openstaande vacatures content/vacatures.yml
Openingstijden, telefoon, mail content/contact.yml
Cookie-/privacy-/CVD-tekst content/juridisch/*.md (Markdown)
Nieuwe vrije pagina content/pagina/<slug>.md (CMS → Extra pagina's → New)
Nieuws-bericht content/nieuws/<datum>-<slug>.md (CMS → Nieuws → New)
Visuele styling / kleuren assets/css/style.css
Nginx / serve-config Dockerfile (laatste stage)
Nieuwe blok-type aan templates _templates/_blocks.html.j2 (Jinja) + admin/preview.js (preview) + admin/config.yml (CMS-velden)

Tekst, knopteksten en de "Voorkeuren wijzigen"-link in de footer zijn bewerkbaar via Site-instellingen → Cookie-banner. Toestemming wordt opgeslagen in localStorage; CustomEvent('cookie-consent') wordt afgevuurd zodat analytics- scripts kunnen reageren:

window.addEventListener('cookie-consent', function (e) {
  if (e.detail.value === 'accept') {
    // laad bv. Plausible script
  }
});

Image pipeline (WebP + lazy-loading)

build.py genereert automatisch een .webp variant naast elke jpg/png in assets/. Tijdens render worden alle <img> gewrapt in <picture> met de WebP als bron, en loading="lazy" decoding="async" toegevoegd waar nog niet aanwezig. Inline background-image:url('...jpg') wordt herschreven naar .webp als beschikbaar. Het nav-logo krijgt loading="eager" fetchpriority="high" voor LCP. Bestandsgroottes zakken doorgaans 4075% — zichtbare Lighthouse-winst zonder template-wijzigingen.

Aandachtspunten

  • Build output _site/ is niet in git — verwijder gerust als je hem niet nodig hebt.
  • Image-paths: gebruik assets/img/... (zonder leading slash). Decap upload doet dit automatisch.
  • Sub-paginas (zoals /nieuws/foo.html) gebruiken automatisch een base-path filter zodat assets, nav-links en footer-links blijven werken.
  • Body van juridische pagina's is Markdown — vetgedrukt, lijsten en links werken zoals je verwacht.
  • Geen Forgejo Actions runner nodig — Coolify regelt de build in de container.
  • Nieuws-overzicht (/nieuws.html) wordt automatisch gegenereerd; vergeet niet "Nieuws" handmatig aan het hoofdmenu toe te voegen.