# notACMS — generator statycznych stron na Symfony
php,symfony,static-site,nginx,architekturanotACMS to oparty na Symfony generator statycznych stron który zbudowałem na początku 2026 roku żeby zastąpić 19 lat WordPressa na holas.pl. Bez bazy danych, bez panelu admina CMS, bez PHP zaangażowanego w serwowanie treści. Cała strona — posty z bloga, strony kategorii, listy tagów, miesiące archiwum, wyszukiwarka, feed RSS, sitemap — jest pre-renderowana do statycznych plików HTML i serwowana przez nginx.
Kod jest open-source na licencji Apache 2.0, z 368 testami PHPUnit, CI/CD przez GitHub Actions i wzorcem lokalnych nadpisań który pozwala użytkownikom customizować szablony, CSS i tłumaczenia bez forkowania.
Architektura
Cała treść żyje w plikach Markdown z YAML frontmatterem:
content/
├── blog/
│ └── tutorials/
│ └── my-post/
│ ├── en.md ← wersja angielska
│ ├── pl.md ← wersja polska
│ └── files/ ← obrazki, serwowane z /media/my-post/
└── pages/
└── about/
├── en.md
└── pl.md
ContentTreeBuilder skanuje system plików, parsuje każdy plik przez league/commonmark (GitHub Flavoured Markdown + YAML frontmatter) i buduje typowane ContentTree — indeks w pamięci wszystkich postów i stron dla danego locale. Tagi, kategorie, miesiące archiwum i mapy URL są obliczane z tego indeksu.
Statyczny build używa sub-requestów Symfony: HttpKernelInterface::handle() z SUB_REQUEST renderuje każdy URL przez pełny kernel bez dotykania sieci. Jeśli URL działa w development, będzie w buildzie statycznym. Brak osobnego silnika szablonów, brak konfiguracji buildu.
Kluczowe funkcje
- Wielojęzyczność — sparowane
en.md+pl.mdw tym samym katalogu, automatyczne mapowanie tłumaczeń, tagihreflang, przełącznik języka - Wyszukiwarka — statyczny indeks oparty na WASM przez Pagefind, po stronie klienta, bez Elasticsearch ani Algolia
- Responsywne obrazki — automatyczne generowanie srcset przez ImageMagick, konfigurowalne szerokości wariantów
- Drafty i zaplanowane posty — dev-only przełączniki podglądu, zaplanowane posty publikowane automatycznie w czasie buildu
- Formularz kontaktowy — Cloudflare Turnstile CAPTCHA, ciasny CSP, pojedynczy endpoint POST
- Styleguide — strona tylko dla dev dokumentująca każdy komponent z prawdziwymi klasami CSS
- Wzorzec lokalnych nadpisań — katalog
local/scala się na bazę w czasie buildu, customizacja bez forkowania
Stos technologiczny
- PHP 8.5, Symfony 7.x
- Szablony Twig, SCSS (dart-sass przez symfonycasts/sass-bundle)
- Symfony AssetMapper (bez webpacka, bez Vite, bez pipeline'u Node.js)
- nginx + PHP-FPM (dwa kontenery Docker na produkcji)
- Pagefind do wyszukiwania
- PHPUnit 13, PHPStan level 6, Rector, PHP CS Fixer
Dlaczego go zbudowałem?
Hugo, Jekyll i Eleventy były oczywistymi kandydatami. Wybrałem budowę customowej aplikacji Symfony bo znam Symfony dobrze, a posiadanie pełnego stacka okazało się mieć realne zalety: te same szablony, kontrolery i pipeline treści obsługują zarówno development jak i produkcję. Nie ma "silnika szablonów build-time" oddzielonego od "silnika szablonów runtime." To po prostu Symfony.
Pełna historia dlaczego WordPress musiał odejść jest w Dlaczego odszedłem od WordPressa. Głębokie zanurzenie w architekturę jest w Symfony jako generator statycznych stron.
Open Source
notACMS jest dostępny na GitHubie na licencji Apache 2.0. Przygotowanie do wydania — testy, audyt AI, poprawki bezpieczeństwa, wzorzec lokalnych nadpisań — jest udokumentowane w serii o open-source.