feat(cms): U1 content model + migration scaffold for blog/news/events

Establish content/ as the source of truth for editable content and
back-fill it from the existing detail pages, per U1 of the no-code CMS
plan.

- docs/content-model.md: front-matter schema (EN/MK/SI), body_format
  html-vs-markdown, content/events -> projects/ output mapping.
- tools/migrate_pages_to_content.py: bs4/yaml extractor; pulls title,
  subtitle, category, ISO date (from ARTICLE_DATES), hero image+caption;
  preserves the article body PLUS trailing sibling sections (event
  galleries) verbatim as body_format: html. Reports unparseable pages
  instead of emitting half-formed files.
- content/**: 51 files (17 entries x EN/MK/SI), 0 skips.
- tools/tests/test_migrate_roundtrip.py: 12 characterization tests
  (structured fields, news-has-no-subtitle, event gallery/lightbox
  preserved, Cyrillic UTF-8 round-trip, every page parses).
- .gitignore: ignore __pycache__/ and *.pyc.

U1 is unblocked and standalone. U2 (render content -> pages) is next;
U5/U6 remain blocked on Open Question Q1 (Gitea<->GitHub topology).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
popovskikandClaude Opus 4.8 committed 2026-08-08 16:18:29 +02:00
1 parent 6204db5f0c
commit 9ddd0f88ef
55 files changed
+4572

No files matched your search

@@ -0,0 +1,70 @@
---
type: event
slug: paint-and-wine-at-sunset
lang: en
source_folder: projects
title: Paint & Wine at Sunset, Celebrating Women’s Day with Art & Music
subtitle: Paint, wine, and music brought students together in Gorizia to celebrate Women’s Day and mark the first MSOS Nova Gorica event.
date: '2025-03-08'
date_line: Published on March 8, 2025
hero:
src: /images/paint-wine-1.webp
alt: Paint & Wine at Sunset event in Gorizia
width: '1600'
height: '1067'
body_format: html
---
<div class="article-body">
<p>On International Women’s Day, the MSOS Nova Gorica team hosted its very first local event in collaboration with the Macedonian Cultural Association "Ohridski Biseri". Students from Ljubljana, Nova Gorica, and the surrounding region crossed the border into Gorizia, Italy, for an evening of painting, wine, and music.</p>
<figure class="article-inline-image">
<img alt="Students painting during the Paint &amp; Wine evening" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-2.webp" width="720"/>
</figure>
<h2 id="section-1">A first for MSOS Nova Gorica</h2>
<p>This was more than just an event. It was the first official activity organized by our new MSOS Nova Gorica team. With support from the Macedonian Cultural Association "Ohridski Biseri", we transformed the cozy venue Etnoteca Mama Angela into a space filled with creativity and laughter.</p>
<figure class="article-inline-image">
<img alt="The cozy venue Etnoteca Mama Angela" decoding="async" height="1067" loading="lazy" src="../../../images/paint-wine-3.webp" width="1600"/>
</figure>
<h2 id="section-2">Art, music, and togetherness</h2>
<p>The concept was simple but powerful: a Paint &amp; Wine Night where anyone could sit down with a canvas, brushes, and a glass of wine, and let inspiration take over. No prior painting experience was needed. Some chose to create symbolic pieces honoring women, others painted freely from the heart.</p>
<p>A live DJ set gave the evening a vibrant rhythm, turning it into more than just a workshop. It became a celebration. Between brushstrokes and beats, students connected, shared stories, and enjoyed an atmosphere that was both creative and festive.</p>
<figure class="article-inline-image">
<img alt="Canvases filling with color as students paint" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-4.webp" width="720"/>
</figure>
<figure class="article-inline-image">
<img alt="Students enjoying wine and music together" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-5.webp" width="720"/>
</figure>
<h2 id="section-3">Why it mattered</h2>
<p>Held on March 8, International Women’s Day, the event carried a deeper meaning. It was a chance to celebrate and appreciate women, not only through words but through art. The paintings that came out of the night were diverse, personal, and full of color, much like the student community itself.</p>
<p>To capture the spirit of the night, we created an aftermovie, which you can watch below.</p>
<div class="video-responsive">
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" src="https://www.youtube-nocookie.com/embed/xGN3-6hnfE4" title="YouTube video player"></iframe>
</div>
<figure class="article-inline-image">
<img alt="Finished paintings on display" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-6.webp" width="720"/>
</figure>
<figure class="article-inline-image">
<img alt="The group enjoying the celebration" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-7.webp" width="720"/>
</figure>
<h2 id="section-4">Looking ahead</h2>
<p>Paint &amp; Wine Night showed that MSOS Nova Gorica is ready to bring fresh ideas and energy to our student family. From wine glasses clinking to canvases filling with color, the night left everyone with memories and a few paint-stained fingers, that will not be forgotten.</p>
<figure class="article-inline-image">
<img alt="A memory from the Paint &amp; Wine evening" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-8.webp" width="720"/>
</figure>
<figure class="article-inline-image">
<img alt="The MSOS Nova Gorica community at sunset" decoding="async" height="1067" loading="lazy" src="../../../images/paint-wine-9.webp" width="1600"/>
</figure>
</div>
<section class="event-gallery">
<h2 class="event-gallery-title">Photos from the event</h2>
<div class="event-gallery-grid js-lightbox">
<button class="eg-thumb" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-1.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 1" decoding="async" height="1067" loading="lazy" src="../../../images/paint-wine-1.webp" width="1600"/></button>
<button class="eg-thumb" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-2.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 2" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-2.webp" width="720"/></button>
<button class="eg-thumb" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-3.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 3" decoding="async" height="1067" loading="lazy" src="../../../images/paint-wine-3.webp" width="1600"/></button>
<button class="eg-thumb" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-4.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 4" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-4.webp" width="720"/></button>
<button class="eg-thumb" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-5.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 5" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-5.webp" width="720"/><span class="eg-more">+4</span></button>
<button class="eg-thumb is-hidden" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-6.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 6" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-6.webp" width="720"/></button>
<button class="eg-thumb is-hidden" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-7.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 7" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-7.webp" width="720"/></button>
<button class="eg-thumb is-hidden" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-8.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 8" decoding="async" height="480" loading="lazy" src="../../../images/paint-wine-8.webp" width="720"/></button>
<button class="eg-thumb is-hidden" data-caption="Paint &amp; Wine at Sunset" data-full="../../../images/paint-wine-9.webp" type="button"><img alt="Paint &amp; Wine at Sunset, photo 9" decoding="async" height="1067" loading="lazy" src="../../../images/paint-wine-9.webp" width="1600"/></button>
</div>
</section>