nowo-tech/wiki-bundle
nowo-tech/wiki-bundle is a PHP package that adds wiki-style content management to your application. Create and organize linked pages, manage knowledge base entries, and integrate a simple, lightweight wiki with minimal setup for documentation or internal reference.
This is not a Laravel package — it is a Symfony bundle (nowo-tech/wiki-bundle) built on Twig, Symfony Forms, and companion bundles (nowo-tech/form-kit-bundle, nowo-tech/tiptap-editor-bundle). As a Laravel developer you will almost never composer require it into a Laravel app directly; you consume it either as a sidecar Symfony service, as a headless data/API source, or by lifting its underlying libraries (league/html-to-markdown) into your own code.
Minimal path:
composer require nowo-tech/wiki-bundle:^1.6.4 inside a Symfony app (or the bundled demo/), enable the bundle, import its routes, and configure storage.UPGRADING.md#to-164 first — v1.6.4 changes how the page-edit form body is rendered, and that is the one thing that will silently break customised templates.templates/manage/page_edit.html.twig — it is the reference implementation for the new child-loop rendering rule (REQ-TWIG-003).Http::baseUrl(...)->withToken(...).First practical use case: wiki page CRUD + HTML→Markdown conversion. Pull page bodies over HTTP, run them through league/html-to-markdown (now 5.1.4) if you need to store Markdown locally, and cache the rendered output on the Laravel side.
If the demo misbehaves, demo/README.md now links the DEMO-FRANKENPHP troubleshooting section — that is your fastest route to a working reference instance.
Headless consumption (recommended for Laravel). Keep the bundle in a Symfony container, expose page read/write endpoints, and treat it as an internal service:
$page = Http::baseUrl(config('wiki.url'))
->withToken(config('wiki.token'))
->get("/api/pages/{$slug}")
->throw()
->json();
Cache aggressively — wiki reads far outnumber writes, and the bundle does no Laravel-side caching for you.
Shared-database integration. If you point Laravel at the same tables, keep all writes on the Symfony side so form-driven invariants (revisions, slugs) stay intact. Use Eloquent read-only models and a withoutTimestamps-style guard.
Template override pattern (if you must customise the form). Copy manage/page_edit.html.twig into your app's bundle override directory and preserve the structure the release introduced — custom markup for title/content, then a generic loop for everything else:
{{ form_start(form) }}
{{ form_row(form.title) }}
{{ form_row(form.content) }}
{% for child in form %}
{% if not child.rendered %}
{{ form_row(child) }}
{% endif %}
{% endfor %}
{{ form_end(form) }}
This is the whole point of REQ-TWIG-003: new fields added by future releases (or by other bundles extending the form) render automatically without you editing the template again.
Editor integration. tiptap-editor-bundle jumped 1.3.10 → 1.5.0. If you build assets yourself, rebuild (pnpm/npm) after upgrading and re-check your asset tags. If you embed the editor in a Laravel Blade view, load the bundle's compiled JS/CSS as static assets from the Symfony host rather than trying to resolve them through Vite.
Markdown pipeline. Use league/html-to-markdown for inbound HTML (imports, pasted content) and let the bundle own outbound rendering. Pin the version you test against; 5.1.4 is a patch bump and safe.
Upgrade cadence. The release is lockfile-level churn plus one view change. Run composer update "nowo-tech/*" --with-dependencies, rebuild front-end assets, then diff your overridden templates against the shipped ones.
form_end(form) is not cosmetic. The template previously used render_rest: false; it now calls form_end(form), which renders _token, hidden fields, and any unrendered children. If you keep a hand-rolled template that renders every field explicitly and switched to form_end(form), you get duplicates. Either keep form_end(form, { render_rest: false }) or adopt the not child.rendered guard — do not mix the two mental models.child.rendered is the contract. Custom-rendered fields (title, content per "rule 3") are flagged as rendered; the loop's {% if not child.rendered %} skips them. If a field renders twice, you forgot the guard; if a field never renders, it was marked rendered without being output.UPGRADING.md#to-164 is the authoritative note. Anchors drift between releases — bookmark the section, not the page.form-kit-bundle 2.7.1 → 2.12.0 is five minors of form-theme and widget changes. If your page-edit form looks subtly different, bisect there before suspecting the wiki bundle itself.bin/console debug:twig to confirm which page_edit.html.twig is actually resolved (bundle override paths beat the bundle's own), bin/console debug:container for the form type, and dump(child.rendered) inside the loop when a field goes missing.ETag/Last-Modified before opening an upstream issue.vendor:publish, facades, Eloquent models) has to be hand-written. Budget for a small bridge package if this becomes load-bearing..php-cs-fixer.dist.php now uses new ParallelConfig(2). Only relevant if you vendored the config; two workers can spike memory on constrained CI runners — drop to ParallelConfig(1) if you see OOM kills.REQ-* codes are traceability markers. REQ-TWIG-003, REQ-CS-001, "rule 3" refer to an upstream spec inventory (now 92/92). Treat them as "intentional, do not revert" if you are diffing upstream changes into your fork.^1.6.4 is fine. Patch releases here are dependency refreshes; the risk surface is the transitive nowo-tech/* minors, so commit your composer.lock and test the editor before promoting.How can I help you explore Laravel packages today?