spatie/yaml-front-matter
Parse YAML front matter from Markdown and similar files. Reads metadata wrapped in --- at the top and returns an object with easy access to fields (via matter() or properties) plus the remaining body content. Ideal for static pages, docs, and blogs.
Installation:
composer require spatie/yaml-front-matter
No additional configuration is required.
First Use Case:
Parse a Markdown file with YAML front matter (e.g., content.md):
use Spatie\YamlFrontMatter\YamlFrontMatter;
$content = file_get_contents('content.md');
$parsed = YamlFrontMatter::parse($content);
// Access front matter via magic methods or array
echo $parsed->title; // Direct property access
echo $parsed->matter('author'); // Explicit method call
echo $parsed->body(); // Get the remaining content after front matter
Where to Look First:
Parsing Markdown/HTML Files:
// Parse a blog post template
$post = YamlFrontMatter::parse(file_get_contents('posts/my-post.md'));
$title = $post->title;
$content = $post->body();
// Store in database
Post::create([
'title' => $title,
'content' => $content,
'slug' => $post->slug,
]);
Dynamic Front Matter Handling: Useful for CMS-like systems where content authors define metadata:
// Validate and cast front matter dynamically
$matter = $parsed->matter();
$validated = collect($matter)->mapWithKeys(function ($value, $key) {
return [$key => is_numeric($value) ? (int)$value : $value];
});
Integration with Laravel Views: Parse front matter in Blade templates for dynamic layouts:
// In a controller
$template = YamlFrontMatter::parse(file_get_contents("templates/{$templateName}.md"));
return view('template', [
'content' => $template->body(),
'meta' => $template->matter(),
]);
Batch Processing: Process multiple files (e.g., for static site generators):
$files = glob('content/*.md');
$posts = collect($files)->map(function ($file) {
return YamlFrontMatter::parse(file_get_contents($file));
});
$this->app->bind(YamlFrontMatter::class, function () {
return new YamlFrontMatter();
});
Storage facade to read files:
use Illuminate\Support\Facades\Storage;
$content = Storage::disk('public')->get('posts/example.md');
$parsed = YamlFrontMatter::parse($content);
Validator to enforce front matter structure:
$validator = Validator::make($parsed->matter(), [
'title' => 'required|string|max:255',
'published_at' => 'required|date',
]);
Malformed YAML:
Spatie\YamlFrontMatter\Exceptions\InvalidYamlException for invalid YAML.yaml_parse() (PHP 8.2+).try {
$parsed = YamlFrontMatter::parse($content);
} catch (\Spatie\YamlFrontMatter\Exceptions\InvalidYamlException $e) {
Log::error("Invalid YAML in file: " . $e->getMessage());
// Fallback to default values or skip the file
}
Empty Front Matter:
--- but contains no YAML, matter() returns an empty array.if (empty($parsed->matter())) {
// Handle missing front matter
}
Nested YAML Structures:
key: { nested: value } becomes key.nested).yaml_parse() manually for complex nested structures.File Encoding:
$content = file_get_contents('file.md', flags: FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
dd($parsed->matter()) to debug front matter structure.Log::debug('Parsed matter:', $parsed->matter());
Log::debug('Body preview:', substr($parsed->body(), 0, 100));
Custom Parsing Logic: Extend the parser by creating a decorator:
class CustomYamlFrontMatter extends YamlFrontMatter
{
public function customMethod()
{
// Add custom logic
}
}
Front Matter Transformers:
Use Laravel’s FormRequest or Model events to transform front matter:
// In a FormRequest
public function rules()
{
$matter = YamlFrontMatter::parse($this->input('content'))->matter();
return [
'title' => 'required|string',
// Dynamically add rules based on front matter
];
}
Caching Parsed Files: Cache parsed results to avoid reprocessing:
$cacheKey = 'parsed:'.$filePath;
$parsed = Cache::remember($cacheKey, now()->addHours(1), function () use ($filePath) {
return YamlFrontMatter::parse(file_get_contents($filePath));
});
YamlFrontMatter class.yaml_parse() (PHP 8.2+) or symfony/yaml (older PHP). Ensure compatibility:
composer require symfony/yaml --dev # For PHP < 8.2
How can I help you explore Laravel packages today?