neoground / charm-markdown
Charm Markdown Module
Requires
- php: >=8.4
- erusev/parsedown: ^1.8
- erusev/parsedown-extra: ^0.9.0
- neoground/charm: ^3.8
README
Markdown and YAML frontmatter support for Charm Framework 3.8 and later.
Charm Markdown provides a focused API for loading Markdown documents, extracting YAML metadata, rendering HTML, and generating structured heading lists for navigation or tables of contents.
Tip
Using Charm Markdown without Charm Framework
This package can also be used as a standalone Markdown component. Install it through Composer and instantiate the kernel binding directly:
composer require neoground/charm-markdown
use Neoground\Charm\Markdown\Markdown; $markdown = new Markdown(); $document = $markdown->fromString('# Hello World'); echo $document->getHtml();
The Neoground\Charm\Markdown\Markdown class exposes the same parsing and rendering methods used by the Charm
Framework integration.
Features
- Load Markdown from files or strings
- Parse YAML frontmatter
- Render Markdown as HTML
- Support Markdown Extra syntax
- Generate stable heading IDs for anchors
- Extract document headings for tables of contents
- Use Markdown rendering directly in Twig views
- Access parsing utilities independently when a document object is not required
Also take a look at the Charmdown class which extends ParsedownExtra.
We added a few features for more immersive content and easier implementation in your apps and sites:
- Table of content extraction
- Support for "alert" style boxes github-style
Requirements
- PHP 8.4 or later with Composer support
- Charm Framework 3.8 or later
The module uses the following libraries provided through the Charm ecosystem:
Installation
Install the package through Composer:
composer require neoground/charm-markdown
Then install the module in your Charm application:
bob cm:i neoground/charm-markdown
Quick Start
Load a Markdown file
$filepath = C::Storage()->getDataPath() . DS . 'demo.md'; $document = C::Markdown()->fromFile($filepath);
Load Markdown from a string
$document = C::Markdown()->fromString('# Hello World');
Document API
A loaded document provides access to its Markdown content, YAML metadata, rendered HTML, and heading structure.
Get the Markdown content
$markdown = $document->getMarkdownContent();
Returns the Markdown body without YAML frontmatter.
Get YAML frontmatter
$metadata = $document->getYaml();
Returns the parsed YAML frontmatter as an array. If the document contains no frontmatter, an empty array is returned.
Render the document as HTML
$html = $document->getHtml();
The generated HTML supports Markdown Extra syntax. Headings receive id attributes so they can be referenced through
anchor links.
Get the document heading structure
$contents = $document->getContentsList();
Returns the document headings as an array suitable for building a table of contents or section navigation.
YAML Frontmatter
A Markdown document can include YAML metadata at the beginning of the file:
--- title: Example Document description: A short example using YAML frontmatter. published: true --- # Example Document This is the Markdown content.
The frontmatter and Markdown body can then be accessed independently:
$document = C::Markdown()->fromFile($filepath); $metadata = $document->getYaml(); $markdown = $document->getMarkdownContent(); $html = $document->getHtml();
Direct Parsing Utilities
The Markdown service can also process raw content without creating a document object.
Separate YAML and Markdown
$result = C::Markdown()->separateMarkdownFromYaml($content);
Returns an array containing:
[
'yaml' => [],
'markdown' => '',
]
The yaml value contains the parsed frontmatter. The markdown value contains the remaining Markdown content.
Extract YAML metadata
$metadata = C::Markdown()->getYaml($content);
Returns the YAML frontmatter as an array.
Extract the Markdown body
$markdown = C::Markdown()->getMarkdownContent($content);
Returns the Markdown content without frontmatter.
Render Markdown as HTML
$html = C::Markdown()->toHtml($content);
Converts the supplied Markdown content into HTML.
Usage in Twig Views
Markdown strings can be rendered directly inside Twig templates:
<div id="content"> {{ markdownToHtml(markdownString)|raw }} </div>
Because the rendered HTML is output using Twig's raw filter, only process Markdown content from trusted sources or
apply appropriate sanitization before rendering user-generated content.
Example
$document = C::Markdown()->fromString( <<<'MARKDOWN' --- title: Getting Started category: Documentation --- # Getting Started This is an example document. ## Installation Install the package using Composer. MARKDOWN ); $metadata = $document->getYaml(); $html = $document->getHtml(); $contents = $document->getContentsList();
The resulting metadata contains the document title and category, while the rendered HTML contains anchorable heading elements.
Security
Charm Markdown converts Markdown into HTML but does not inherently guarantee that arbitrary user-generated content is safe to render.
When accepting Markdown from untrusted sources:
- sanitize the generated HTML
- restrict unsupported or unsafe HTML input
- validate YAML metadata before using it
- avoid rendering untrusted output through Twig's
rawfilter without additional protection
Developed by Neoground as part of the Charm Framework ecosystem.