Laravel Markdown Blog
This blog was born from my idea to create a straightforward markdown-based blog using Laravel. While searching online, I often came across pre-built packages that were either overloaded with unnecessary features or didn’t meet my specific needs.
That’s when I started wondering if it was possible to build something much simpler.
I stumbled upon a blog post on codingwithstef.com, which provided a great starting point, as the author aimed to create a basic model using the filesystem, but I decided to ditch the filesystem approach and instead use the Sushi Model Driver for handling the Posts, since the Filesystem approach would not be easily paginating through all of my posts and felt slow.
For this project, I used spatie/yaml-front-matter to parse the Markdown files and spatie/laravel-markdown to render the content.
With that foundation, here’s how I developed a simple Blog model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\File;
use Spatie\LaravelMarkdown\MarkdownRenderer;
use Spatie\YamlFrontMatter\YamlFrontMatter;
class Blog extends Model
{
use \Sushi\Sushi;
public $incrementing = false;
protected $primaryKey = 'slug';
protected $keyType = 'string';
protected function sushiShouldCache()
{
return true;
}
protected $casts = [
'meta' => 'array',
];
public function getRows()
{
$rows = [];
foreach (File::files(storage_path(env('BLOG'))) as $file) {
$markdown = new MarkdownRenderer;
$yaml = YamlFrontMatter::parse(File::get($file->getRealPath()));
$row['meta'] = json_encode($yaml->matter());
$row['slug'] = str_replace('.md', '', $file->getBaseName());
$row['body'] = $markdown->disableAnchors()
->highlightTheme('github-dark')
->toHtml($yaml->body());
$rows[] = $row;
}
return $rows;
}
}
How you design your views is entirely up to you. You can create a custom template or choose a default one from the web—whatever suits your needs.
I then further decided to add a SEO Package to add the necessary SEO tags.
namespace App\Http\Controllers;
use App\Helpers\Tools;
use App\Models\Blog;
use Illuminate\Http\Request;
class BlogController extends Controller
{
public function index(Request $request)
{
seo()
->title('B65')
->description('a nerdy dev blog')
->twitter();
return view('blog.index', ['posts' => Blog::orderBy('slug', 'DESC')->simplePaginate(5)]);
}
public function post(Request $request, $slug)
{
$post = Blog::where('slug', $slug)->firstOrFail();
seo()
->title($post->meta['title'])
->description($post->meta['excerpt'])
->image($post->meta['image'] ?? '')
->twitter();
return view('blog.post', ['post' => $post]);
}
}
Finally you also will be needing the Routes for your Blog Controller:
Route::get('/', [BlogController::class, 'index']);
Route::get('/{slug}.html', [BlogController::class, 'post']);
I hope this article was helpful. If you have any questions or suggestions please let me know in the comments section below.