The revamped Spatie guidelines
I created the original Spatie guidelines site three years ago. Last month, we consolidated a few of our subsites to our main spatie.be site, including the guidelines.
Highlighting code blocks with league/commonmark
Since the first iteration of my blog—some time around 2016—I've used highlight.js to highlight code blocks. With highlight.js being so popular, I never really second guessed the idea. It was a given to use JavaScript.
A few weeks ago, TJ Miller introduced me to highlight.php by writing a Parsedown extension for it. Highlight.php does the exact same thing as highlight.js: they both add tags and classes to your code
blocks, which enables them to be highlighted with CSS. The difference is, highlight.php does this on the server.
Server side rendering JavaScript from PHP
Server side rendering is a hot topic when it comes to client side applications. Unfortunately, it's not an easy thing to do, especially if you're not building things in a Node.js environment.
I published two libraries to enable server side rendering JavaScript from PHP: spatie/server-side-rendering and spatie/laravel-server-side-rendering for Laravel apps.
Let's review some server side rendering concepts, benefits and tradeoffs, and build a server renderer in PHP from first principles.
Blade component aliases in Laravel 5.6
Laravel 5.6 adds the ability to register alias directives for Blade components. Let's review some background information and examples.
↗ Christoph Rumpel on rebuilding his site with Laravel
Christoph Rumpel published his revamped site last week, built with Laravel and Tailwind CSS. He based the site's architecture on my personal site (yeah, the one you're reading now). I open sourced it about a year ago, and I'm glad to see that it provided value to someone!
Read the full article on Christoph Rumpel's new blog.
Passing data to layouts in Blade through extends
Laravel quick tip! The @extends
Blade directive accepts a second (undocumented) parameter to pass data to the parent layout.
Debugging the dreaded "Class log does not exist" error in Laravel
Every now and then I come accross a Class log does not exist
exception in Laravel. This particular exception is thrown when something goes wrong really early in the application, before the exception handler is instantiated.
Whenever I come across this issue I'm stumped. Mostly it's related to an invalid configuration issue or an early service provider that throws an exception. I always forget how to debug this, so it's time to document my solution for tracking down the underlying error.
Theme-based views in Laravel using vendor namespaces
I'm building a multi-tenant Laravel application. One of the requirements of the project is that every client can have their own theme based on their corporate guidelines. By default a few css adjustments will suffice, but some clients request a completely different template.
Conditionally loading a different stylesheet per client is pretty trivial, but in order to use a completely different view per theme you quickly end up typing the same thing over and over across various parts of your application.
↗ Is snapshot testing viable in PHP?
Christopher Pitt wrote a pretty comprehensive article on one of our latest packages, which is one of my favorite packages I've written at Spatie to date, phpunit-snapshot-assertions.
Ah-ha moments are beautiful and rare in programming. Every so often, we’re fortunate enough to discover some trick or facet of a system that forever changes how we think of it. For me, that’s what snapshot testing is.
Read the full article on SitePoint, or check out phpunit-snapshot-assertions
on GitHub.
The list function & practical uses of array destructuring in PHP
PHP 7.1 introduced a new syntax for the list()
function. I've never really seen too much list()
calls in the wild, but it enables you to write some pretty neat stuff.
This post is a primer of list()
and it's PHP 7.1 short notation, and an overview of some use cases I've been applying them to.
Automatically running PHPUnit with Watchman
A little bash script to run tests when a file has been changed.
A package for snapshot testing in PHPUnit
The gist of snapshot testing is asserting that a set of data hasn't changed compared to a previous version, which is a snapshot of the data, to prevent regressions. The difference between a classic and an is that you don't write the expectation yourself when snapshot testing.
When a snapshot assertion happens for the first time, it creates a snapshot file with the actual output, and marks the test as incomplete. Every subsequent run will compare the output with the existing snapshot file to check for regressions.
Snapshot testing is most useful larger datasets that can change over time, like serializing an object for an XML export or a JSON API endpoint.
Non-breaking, SEO friendly urls in Laravel
When admins create or update a news item—or any other entity—in our homegrown CMS, a url slug is generated based on it's title. The downside here is that when the title changes, the old url would break. If we wouldn't regenerate the url on updates, edited titles would still have an old slug in the url, which isn't an ideal situation either.
Our solution: add a unique identifier to the url that will never change, while keeping the slug intact. This creates links that are both readable and unbreakable.
Using a database for localization in Laravel
When building a website for a client that wants to be able to manage content, Laravel's language files aren't ideal since you can't edit them without diving into a bundle of text files. We recently decided to drop all the lang files in our custom CMS in favor of persisting translations in the database, which allows us to build a custom interface for managing them.
This post is a quick overview on overwriting Laravel's default translation loader, which means you can keep using the lang
method while fetching the translations from a database. Writing a custom loader is easier than it sounds. First we'll set up our translation models, then we'll write our loader, and finally register it in our application.