After so many years as a developer I thought it's about time to share a bit more about my work. So I started a blog, where I plan to blog about development, linux/unix, security, life as a freelancer and more. Tutorials, tips & tricks, or just things that stick with. But first something about my shiny new blog.
Underlying technology
I could have just started another wordpress blog. I have done it before, for employers, clients, and for myself. Years ago I blogged about my travels in Dutch at farenji.net. But I have seen enough of the wordpress source code. It has made me cry. So I decided to build my own platform. More fun and no need to reinvent every wheel. Just combine the right libraries and packages.
Laravel Nova
Laravel has been my framework of choice for many years. I know it inside out. I also have good experiences with Laravel Nova. Though it has its quirks and limitations, it is a fine product, and it lets you build a custom CMS in no time. Nova is not free, but I think it's worth the investment. It will pay for itself, because time is money.
Markdown
I don't really like WYSIWYG editors. "What You See Is Almost Never What You Get". There are many different implementations, with their own limitations, and in fact I never found one that did everything I wanted. And the generated html code is often terrible. But on the other hand, I did not really feel like typing all html by hand, so I opted for the Markdown format.
Using the excellent library laravel-markdown combined with nova-markdown setting up the base of the platform was almost a breeze. Markdown is rendered by league/commonmark which can be customized entirely.
Code syntax highlighting
A development blog is about code, so that code needs to look good. The laravel-markdown library takes care of that by integrating Shiki. Quite nice. I added some CSS based line numbering myself, et voila:
<?php
namespace App\Http\Controllers;
use App\Models\BlogEntry;
use Artesaos\SEOTools\SEOTools;
use Illuminate\Contracts\View\View;
class BlogController extends Controller
{
protected SEOTools $seo;
public function __construct(SEOTools $seo)
{
$this->seo = $seo;
}
public function entry(BlogEntry $blogEntry): View
{
$imageUrl = url($blogEntry->image_url);
$this->seo->setTitle($blogEntry->title);
$this->seo->setDescription($blogEntry->excerpt);
$this->seo->twitter()->setImage($imageUrl);
$this->seo->opengraph()->addImage($imageUrl);
$this->seo->opengraph()->setType('article');
$this->seo->opengraph()->setArticle([
'article:published_time' => $blogEntry->published_at->toIso8601String(),
]);
return view('blog.entry', [
'blogEntry' => $blogEntry,
]);
}
}
This snippet takes care of automatic line numbers:
code {
counter-reset: step;
counter-increment: step 0;
}
code .line::before {
content: counter(step);
counter-increment: step;
width: 1rem;
margin-right: 1.5rem;
display: inline-block;
text-align: right;
color: rgba(135,158,168,.4)
}
SEO
The PHP code fragment above hinted to it: even as a backend developer you will need a bit of SEO, or actually: taking care that links you share on social platforms look good. To help with the myriad of different meta tags I used artesaos/seotools which makes it easier.
I18N and L10N
My site and blog started as single language, Dutch only. But I prepared internationalization and localization using mcamara/laravel-localization. The hard work was translating all Dutch content, which took some time. Finally, almost everything has been translated, and the entire blog is multi language as well. Blogging in English gives me a potentially larger audience than just Dutch.
Comments
A blog needs some interactivity, at least comments. If you want to build that yourself, that can take a lot of time, especially if you want to do it right. Avatars, profile pages, maybe threaded discussions, emoji, single sign on, and so on. There are a lot of "plug and play" solutions, like Disqus. That is a paid service, which is not a problem, but there are other disadvantages.
I found several alternatives, and utteranc.es seemed a nice fit, and easy to implement. Neat about this solution is that all comment data is stored in GitHub Issues, using the API. That means it instantly provides all functionality you have there. To comment you do need a GitHub account, but I am guessing that most of my target audience will have one.
Finally
If you made it this far, please leave a comment!