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.

A few things I don't like here. First off, passing $client->theme->name to every view name starts to get tedious very fast. In the views we can hard code the theme name since we're already in the theme, but it's too easy to introduce silent errors by requiring a different theme's view when copy-pasting across themes (which will happen). Finally, all of this could become annoying to refactor if we decide to change our strategy regarding themes.

There aren't any huge issues here, but alltogether it feels like we should be able to do better. There are a few strategies to clean this up, but I just want to talk about vendor namespaces today.

Laravel allows you register a view vendor namespace which points to a specific directory containing Blade files. This feature is intended for package development, but it's a perfect solution to our problem.

By registering a namespace with the current theme's location, we can drop all the dynamic parts of our view names when we're calling them.

Registering a vendor namespace is pretty straightforward. Create a service provider, and call the loadViewsFrom in the boot method. We'll need to pass a directory containing the views, and a name for our “vendor”.