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.phpuse Statamic\Facades\Markdown;use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;Markdown::addExtension(function () {return new FrontMatterExtension;});
# app/Providers/AppServiceProvider.phpuse 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.phpuse 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.phpuse 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.phpnamespace 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.phpnamespace 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 }}