nks-hub / nette-markdown
Nette DI extension wrapping league/commonmark with Latte filter support
Requires
- php: ^8.2
- latte/latte: ^3.0
- league/commonmark: ^2.8
- nette/di: ^3.1
Requires (Dev)
- nette/bootstrap: ^3.2
- phpunit/phpunit: ^10.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-10 10:35:22 UTC
README
Nette DI extension that registers a league/commonmark converter as a service and adds
|markdownfilters to every Latte engine.
Features
- 🧩 Nette DI extension - One line in
config.neonmakesMarkdownConverterautowirable - 🎨 Latte filter -
{$content|markdown}works in any template; the filter is registered on all Latte engines - 📝 CommonMark - Parsing done by league/commonmark 2.x
- 🐙 GFM by default - Tables with alignment, task lists (
- [x] Done), strikethrough (~~deleted~~) and autolinks enabled without configuration - 🔗 Heading permalinks and TOC - Anchor links on headings and a generated table of contents (opt-in)
- 📚 Footnotes and smart punctuation -
[^1]reference-style footnotes, curly quotes, dashes, ellipsis (opt-in) - 🖍️ Highlight -
==text==rendered as<mark>(opt-in) - 💻 Fenced code blocks -
```langblocks get alanguage-*class - 🛡️ Safe defaults - Raw HTML input stripped, unsafe links (
javascript:) blocked - ⚙️ Configuration - Pick extensions, set
html_inputandallow_unsafe_links, change the permalink symbol
Requirements
- PHP 8.2 or higher
- league/commonmark ^2.8
- nette/di ^3.1
- latte/latte ^3.0
Installation
composer require nks-hub/nette-markdown
Register the extension in Nette DI:
# config/common.neon extensions: markdown: NksHub\Markdown\DI\MarkdownExtension
MarkdownConverter is then available for injection and the |markdown Latte filter is registered.
Usage
In presenters and services
use NksHub\Markdown\MarkdownConverter; class WikiPresenter extends Nette\Application\UI\Presenter { public function __construct( private MarkdownConverter $markdown, ) {} public function renderView(string $slug): void { $page = $this->pages->findBySlug($slug); $this->template->htmlContent = $this->markdown->convert($page->getContent()); } }
In Latte templates
{* Filter syntax *} {$page->getContent()|markdown|noescape} {* Or in a block *} {var $html = ($page->getContent()|markdown)} {$html|noescape}
Standalone, without Nette DI
use NksHub\Markdown\MarkdownConverter; $converter = new MarkdownConverter(); $html = $converter->convert('# Hello **World**'); // <h1>Hello <strong>World</strong></h1> // Safe mode — strips all HTML, blocks unsafe links $safeHtml = $converter->convertSafe($userInput);
Configuration
Defaults
extensions: markdown: NksHub\Markdown\DI\MarkdownExtension
Defaults: CommonMark + GFM (tables, task lists, strikethrough, autolinks), HTML stripped, unsafe links blocked.
Full configuration
extensions: markdown: NksHub\Markdown\DI\MarkdownExtension markdown: # Extensions to enable (default: commonmark + gfm) extensions: - commonmark # Core CommonMark spec (always needed) - gfm # Tables + Strikethrough + Task Lists + Autolinks - footnote # Reference-style footnotes - smartpunct # Curly quotes, em-dashes, ellipsis - heading_permalink # Anchor links on headings - toc # Auto-generated Table of Contents # HTML input handling: strip (default), allow, escape html_input: strip # Block javascript:, vbscript:, data: links (default: false = blocked) allow_unsafe_links: false # Heading permalink symbol (only when heading_permalink extension enabled) heading_permalink: symbol: '#'
Available extensions
| Key | Extension | Description |
|---|---|---|
commonmark |
CommonMarkCoreExtension |
Core CommonMark spec, always include this |
gfm |
Tables + Strikethrough + TaskList + Autolink | GitHub Flavored Markdown bundle |
footnote |
FootnoteExtension |
[^1] reference-style footnotes |
smartpunct |
SmartPunctExtension |
Smart quotes, dashes, ellipsis |
heading_permalink |
HeadingPermalinkExtension |
Clickable anchor links on headings |
toc |
TableOfContentsExtension |
Auto-generated TOC from headings |
mark |
MarkExtension |
==text== rendered as <mark>text</mark> |
external_link |
ExternalLinkExtension |
Attributes for external links |
API reference
MarkdownConverter
use NksHub\Markdown\MarkdownConverter; // Default: CommonMark + GFM, HTML stripped, unsafe links blocked $converter = new MarkdownConverter(); // Custom config $converter = new MarkdownConverter([ 'extensions' => ['commonmark', 'gfm', 'footnote'], 'html_input' => 'allow', 'allow_unsafe_links' => false, ]); // Convert Markdown to HTML $html = $converter->convert($markdown); // Safe conversion (always strips HTML + blocks unsafe links, regardless of config) $safeHtml = $converter->convertSafe($untrustedInput);
MarkdownFilter (Latte)
Registered by the DI extension:
{$content|markdown|noescape}
Returns Latte\Runtime\Html instance, so |noescape is required to render the HTML.
MarkdownExtension (Nette DI)
Filters registered on every Latte engine:
|markdownand|markdownSafe: always use safe conversion (convertSafe())|markdownRaw: uses the converter as configured (respectshtml_input)
Registers two services:
NksHub\Markdown\MarkdownConverter: injectable converterNksHub\Markdown\Latte\MarkdownFilter: registered on all Latte engines
Security
Defaults:
| Setting | Default | Effect |
|---|---|---|
html_input |
strip |
Removes all raw HTML from Markdown input |
allow_unsafe_links |
false |
Blocks javascript:, vbscript:, data: URLs |
For user-generated content, use convertSafe() which enforces both settings regardless of constructor config.
Do not use html_input: allow with untrusted input: it passes raw HTML through, <script> tags included.
Links
- league/commonmark: the CommonMark parser used here
- Packagist package
- @nks-hub/texy-editor: TypeScript Texy/Markdown editor with a toolbar
Development
# Install dependencies composer install # Run tests (PHPUnit 10) vendor/bin/phpunit # Run with coverage vendor/bin/phpunit --coverage-html coverage/ # Static analysis vendor/bin/phpstan analyse
Contributing
Contributions are welcome! For major changes, please open an issue first.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: description') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Support
- 📧 Email: dev@nks-hub.cz
- 🐛 Bug reports: GitHub Issues
- 📖 CommonMark docs: commonmark.thephpleague.com
- 🏗️ Nette Framework: nette.org
License
MIT License — see LICENSE for details.
Made with ❤️ by NKS Hub