notACMS 1.1 — Skeleton, motyw i dowód że to działa
php,symfony,static-site,nginx,open-source,architekturanotACMS 1.1.0 pojawił się 24 kwietnia, 1.1.1 dwa dni później, a 1.1.2 jakieś półtora tygodnia po tym. Trzy wydania które zmieniają nie tyle to co notACMS robi, ale to jak się z niego korzysta — i co dostajesz na starcie.
notACMS wyrósł z mojej własnej strony i przez pierwsze wydanie był jednym kawałkiem: klonujesz repo, masz gotowy design, zaczynasz od nadpisywania. Działało, ale każdy kto chciał zbudować własny wygląd od zera musiał walczyć z rzeczami których nie potrzebował. 1.1.0 rozwiązuje to przez podział na rdzeń i motyw demo.
Rdzeń jest skeletonem
templates/, assets/, translations/ to teraz minimalny szkielet. Systemowe fonty, tryb jasny, około 200 linii CSS. Wszystkie funkcje działają — blog, strony, wyszukiwarka, RSS, mapa strony, responsywne obrazki, formularz kontaktowy — ale wygląda to jak strona z lat 90. Celowo. Jeśli budujesz własny design, nie musisz walczyć z motywem który narzuca ci język wizualny.
Motyw demo mieszka w docs/demo/ i jest domyślnym seedem — ./notACMS deploy albo ddev build położą go przy pierwszym uruchomieniu. Jeśli wolisz skeleton, dodaj --bare:
./notACMS deploy # amber-phosphor (domyślnie), gotowy do poprawiania
./notACMS deploy --bare # skeleton, budujesz od zera
Cała reszta — wzorzec lokalnych nadpisań przez katalog local/, brak edycji rdzenia, czysty git pull — działa tak samo niezależnie od wyboru.
Co jeszcze trafiło do 1.1.0
Czas czytania i pasek postępu na postach i dokumentach. Przełącznik języków jako rozszerzenie Twig. Fragmenty postów które nie przeciekają już # z anchorów nagłówków. Szkielet testów PHPUnit w tests/. Skille AI-agent do pracy z repozytorium. Pakiet zgodności starego motywu w docs/customization/old-template/ — jedno cp -r i wracasz do wyglądu z 1.0.0.
1.1.1 — łatka którą wymusiło realne użycie
Przygotowując ten wpis na holas.pl, deployując na produkcję, zauważyłem coś irytującego: ./notACMS deploy --prod przy każdym uruchomieniu robił backup local/ i podmieniał go świeżą kopią. Jeśli miałeś tam już treść, znikała. Deploy nie odróżniał "użytkownik chce zastąpić cały motyw" od "użytkownik chce tylko zbudować stronę z istniejącą treścią".
1.1.1 naprawia to tak, że deploy działa jak ddev build: inicjuje local/ tylko gdy katalog nie istnieje lub jest pusty. Treść którą już masz zostaje nienaruszona. Chcesz wymusić reseed? Podaj --bare lub --demo jawnie.
Drugą zmianą są etykiety nawigacji z frontmatteru. Do tej pory każda zakładka w menu wymagała klucza tłumaczenia w każdym pliku locale — nav.home, nav.about, site.releases i tak dalej. Dodanie nowej strony oznaczało aktualizację N plików YAML. Teraz wystarczy menu.label w frontmatterze strony:
---
title: "Architecture guide"
menu:
label: "Architecture"
weight: 30
---
Nowa funkcja Twig content_item() odczytuje to bez dodatkowej konfiguracji:
{{ content_item('architecture-guide', 'en').menuLabel() }}
Polskie, niemieckie i francuskie treści demo dostały pełny przegląd przez wszystkie strony i wpisy.
1.1.2 — utwardzenie po przeglądzie
1.1.2 to to, co wychodzi gdy siądziesz nad kodem przed taggiem i spojrzysz na niego świeżym okiem. Podczas przeglądu wypłynęły dwa bugi bezpieczeństwa i zostały naprawione przed wydaniem: open-redirect przez normalizację ścieżki (Request::getPathInfo() nie zwija powtórzonych slashy, więc /<default-locale>//evil.com wyprodukowałoby Location: //evil.com — przekierowanie cross-origin) oraz XSS na stronie wyników wyszukiwania, gdzie pole excerpt z Pagefind było wstrzykiwane do innerHTML bez escapowania.
Ficzer headline'owy to kanoniczne URL-e. Jeśli twoja domyślna locale to en, /en/blog/ i /blog/ były obie dostępne i renderowały tę samą treść — dwa indeksowalne URL-e dla jednej strony. Nowy event listener zwraca teraz 301 z /<default-locale>/... na wersję bez prefiksu, zanim router Symfony w ogóle ruszy.
Wewnętrznie, te wszystkie inline'owe bloki |json_encode|raw z JSON-LD rozsiane po szablonach zniknęły. Mały serwis StructuredDataBuilder plus dwie funkcje Twig (json_ld() i structured_data()) zastępują je płynnym, typowanym API. JSON_THROW_ON_ERROR jest włączone, więc zły bajt UTF-8 we frontmatterze rzuci wyjątkiem podczas renderu zamiast po cichu wysyłać <script>false</script>. Bazowe szablony rdzenia dla stron contact, default i projects też emitują teraz znaczniki Schema.org — bare deploy nie ma już słabszego SEO niż każdy przykład customizacji, który dostarczamy.
Demo jako żywy dowód
Najbardziej satysfakcjonująca część tego wydania to nie kod — to co jest w docs/demo/. Nie motyw. Kompletna, czterojęzyczna strona która jest dołączona do repozytorium. Ma własny manual, dokumentację architektury, styleguide i blog wydań — wszystko działające, wszystko wyrenderowane przez ten sam system który dostajesz po git clone.
- Manual — instalacja, konfiguracja, struktura treści, frontmatter, komendy, deploy, zmienne środowiskowe, rozwiązywanie problemów
- Architektura — routing, pipeline treści, statyczny build, wyszukiwarka, wielojęzyczność, deployment
- Styleguide — każdy komponent udokumentowany z prawdziwymi tokenami SCSS
- Blog wydań — wpisy o każdej wersji, renderowane przez ten sam system
"Ufam ci że działa, ale pokaż" — to jest właśnie to. Demo nie jest przykładem, jest dowodem. Wielojęzyczne routowanie, pre-renderowanie statyczne, Pagefind, responsywne obrazki, formularz kontaktowy, RSS, sitemap — wszystko działa w treściach demo. Ktoś po świeżym git clone i ddev build widzi dokładnie tę stronę.
Linki
Pełny changelog ze wszystkimi zmianami: CHANGELOG.md.
Zmiany breakingowe i migracja z 1.0.0: UPGRADE-1.1.md.
Repozytorium: GitHub / holas1337/notACMS — Apache 2.0.