Skip to main content
Jack Sleight .DEV
Statamic

Reading Markdown front matter in Statamic

Statamic's markdown modifier allows you to parse markdown into HTML. But what if you have markdown from an external source that contains front matter values? The default markdown parser and modifier dont parse or return front matter values, but it's easy to add that ability!

The first thing to do is add the FrontMatterExtension to the markdown parser. You can do this by adding the following to a service providers boot method:

# app/Providers/AppServiceProvider.php
use Statamic\Facades\Markdown;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
 
Markdown::addExtension(function () {
return new FrontMatterExtension;
});
# app/Providers/AppServiceProvider.php
use Statamic\Facades\Markdown;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
 
Markdown::addExtension(function () {
return new FrontMatterExtension;
});

You'll then need to add a new method to the parser, as the default one will only return the content and we need the extracted front matter values as well. To do this add the following to your service provider as well:

# app/Providers/AppServiceProvider.php
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
 
Markdown::macro('parseFrontMatter', function ($markdown) {
$result = $this->converter()->convert($markdown);
$frontMatter = $result instanceof RenderedContentWithFrontMatter
? $result->getFrontMatter()
: [];
return array_merge($frontMatter, ['content' => $result->getContent()]);
});
# app/Providers/AppServiceProvider.php
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
 
Markdown::macro('parseFrontMatter', function ($markdown) {
$result = $this->converter()->convert($markdown);
$frontMatter = $result instanceof RenderedContentWithFrontMatter
? $result->getFrontMatter()
: [];
return array_merge($frontMatter, ['content' => $result->getContent()]);
});

The last piece of the puzzle is creating a new modifier that will use this new parser method. To do this create a new modifier with php please make:modifier MarkdownFrontMatter and add this:

# app/Modifiers/MarkdownFrontMatter.php
namespace App\Modifiers;
 
use Statamic\Facades\Markdown;
use Statamic\Modifiers\Modifier;
 
class MarkdownFrontMatter extends Modifier
{
public function index($value, $params, $context)
{
$parser = $params[0] ?? 'default';
if (in_array($parser, [true, 'true', ''], true)) {
$parser = 'default';
}
return Markdown::parser($parser)->parseFrontMatter((string) $value);
}
}
# app/Modifiers/MarkdownFrontMatter.php
namespace App\Modifiers;
 
use Statamic\Facades\Markdown;
use Statamic\Modifiers\Modifier;
 
class MarkdownFrontMatter extends Modifier
{
public function index($value, $params, $context)
{
$parser = $params[0] ?? 'default';
if (in_array($parser, [true, 'true', ''], true)) {
$parser = 'default';
}
return Markdown::parser($parser)->parseFrontMatter((string) $value);
}
}

You can then call this modifier in your templates to parse the markdown and retrieve an array containing both the content and front the matter values:

{{ my_value | markdown_front_matter }}
<h1>{{ title }}</h1>
{{ content }}
{{ /my_value }}
{{ my_value | markdown_front_matter }}
<h1>{{ title }}</h1>
{{ content }}
{{ /my_value }}
7th June 2022