Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Markdown Wiki Bundle Laravel Package

gigadrive/markdown-wiki-bundle

A Symfony bundle that turns Markdown files into a browsable wiki, handling routing, parsing, and templating for you. Drop .md docs into a folder and get a navigable knowledge base that fits into existing Symfony apps. Lightweight and easy to set up, though docs and community support are limited.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check before you install anything. gigadrive/markdown-wiki-bundle is a Symfony 5 bundle — it ships a Bundle class, a DI extension, service definitions in Resources/config, and Twig templates in Resources/views. It is not a Laravel package, and composer require gigadrive/markdown-wiki-bundle in a Laravel app will install dependencies you never boot. It is also archived (last release 2022-03-16, 0 dependents, 3 stars), so treat it as a reference implementation, not a dependency.

If you are actually in a Symfony 5 app (the only supported path):

  1. composer require gigadrive/markdown-wiki-bundle
  2. Register Gigadrive\MarkdownWikiBundle\MarkdownWikiBundle in config/bundles.php
  3. Publish/point the content directory config at a folder of .md files
  4. Navigate to the route the bundle exposes and confirm a page renders

If you are in Laravel (the likely case), don't install it. Spend 15 minutes reading the source instead:

  • README.md — config keys and route shape
  • src/ — the controller and the service that walks the content directory and converts Markdown
  • Resources/config/ — what the service actually needs injected (this tells you how thin the wrapper is)
  • Resources/views/ — the page/index template structure, which maps almost 1:1 to Blade

Then reimplement the ~100 lines of logic with league/commonmark (the same underlying converter most of these bundles use) plus a controller and a Blade view. That is the fastest path to a working help/wiki section in Laravel.

First use case: a resources/docs/*.md tree rendered at /help/{page}, with /help as an auto-generated index. Drop three markdown files in, get a routable, version-controlled help section with zero database.

Implementation Patterns

Content-as-files, slug-as-route. The bundle's core pattern is a catch-all route mapping a slug to a file path. In Laravel:

Route::get('/help/{page?}', HelpController::class)
    ->where('page', '[A-Za-z0-9\-_/]+')
    ->name('help');

The where constraint is not optional — it's your path-traversal defense (see Gotchas).

Resolve, don't file_get_contents blindly. Build an explicit resolver that maps a slug to a path under a fixed root, normalizes it, and asserts the result is still inside the root before reading. This is the one piece of logic worth copying faithfully from the bundle's source.

Cache the parsed HTML, keyed by mtime. Markdown parsing on every request is wasteful and the nav/index scan is worse. In Laravel:

$key = "help:{$page}:" . filemtime($path);
return Cache::rememberForever($key, fn () => $converter->convert(file_get_contents($path))->getContent());

The mtime in the key gives you automatic invalidation on edit without a deploy step.

Build the sidebar from the directory tree once, cache it separately. The bundle's index view enumerates files; do the same in a HelpIndex service and cache the resulting nav array. Recompute it when any file's mtime changes, or just on a short TTL (Cache::remember(..., 300, ...)) — docs change rarely and a 5-minute stale nav is harmless.

Render with {!! !!} and a hardened converter. Configure CommonMark with html_input => 'strip' and allow_unsafe_links => false unless you fully trust every author. If you need raw HTML in docs, swap strip for an allowlist sanitizer, not 'allow'.

Blade over Twig. The bundle's Twig templates are simple enough to transliterate: one layout, one page template, one index template. Keep the same variables (content, title, nav) so the mental model transfers.

Integration points that pay off day-to-day:

  • Wrap the route group in auth middleware for internal wikis; leave public help docs open.
  • Add throttle: if docs are public — file reads plus parsing are cheap but not free.
  • Include the docs directory in your deploy artifact so the wiki is versioned with the code that documents it.
  • Generate /sitemap.xml entries from the same index service.
  • For search, index filename + headings + first N chars into a simple table or a where-filtered array — you almost certainly don't need a search engine for a few hundred pages.

Gotchas and Tips

  • Archived and Symfony-5-bound. No security patches, no PHP 8.2+ guarantees, no maintainer response. Even in a Symfony project, verify it installs against your current Symfony/PHP before committing to it; the constraint set from a 2022 release will fight modern Symfony. If you're on Symfony 6+, plan to fork or replace.
  • Twig is a hard dependency of the bundle's rendering path. Pulling Twig into a Laravel app to satisfy a 3-star archived bundle is a losing trade — reimplement instead.
  • Path traversal is the real risk. Slug routes are user input. Reject .., leading /, null bytes, and backslashes explicitly; realpath() + str_starts_with($resolved, $root) is the reliable check. Don't rely on the route regex alone if slugs can contain /.
  • XSS via Markdown. CommonMark passes raw HTML through by default. Docs written by colleagues still end up in a browser — configure html_input deliberately and test with a <script> in a scratch file.
  • mtime caching breaks in containers and CI. Immutable images, read-only volume mounts, and git checkouts can all produce mtimes that don't change how you expect. Have a fallback: hash the file contents for small doc trees, or expose an artisan command that flushes the doc cache on deploy.
  • Case sensitivity. Filesystem-dependent slug matching will bite you on macOS/Windows dev vs. Linux prod. Normalize slugs to lowercase in the resolver and store filenames accordingly.
  • Extension points to note if you do fork it: the Markdown converter is almost certainly a service you can decorate/replace to add extensions (tables, footnotes, anchors, a TOC extension); the content root is config-driven; the templates are overridable. Those are the three seams worth preserving in your own implementation.
  • Debugging tip: when a page 404s, log the resolved path, not just the slug. Nine times out of ten it's a trailing slash, a case mismatch, or a .md extension assumption in the resolver.
  • Alternatives that are actually maintained for Laravel: league/commonmark directly (best control), spatie/laravel-markdown (caching + Blade components), or a static docs generator if the wiki doesn't need runtime rendering at all.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings