Published Apr 23, 2024

Last Updated Apr 23, 2024

WordPress Development With TypeRocket #1

Categories: WordPress

Tags: #PHP , #TypeRocket

When other devs hear about PHP, a lot of them think of WordPress—and rightfully so. It's the grandpa old man of the PHP world.

I've been doing a lot of WordPress dev lately, but I've been missing Laravel. TypeRocket has just enough of that Laravel-like feel to make dev in WordPress more pleasant, so I finally decided to introduce it to the biggest WordPress-based project I'm working on right now.

So... What is TypeRocket?

TypeRocket is an MVC-like toolkit for WordPress, including familiar things like: a Laravel-like folder structure, models and an ORM, migration files, controllers, and a nice router.

It even comes with an Artisan-like CLI: galaxy.

There's lots more in the docs.


First, you'll need to be running at least WordPress 6.1 and PHP 8.0.

TypeRocket comes in a few forms: a composer package, a dedicated WordPress plugin, and also a MU plugin—a type of plugin that can only be manually added to and removed from the wp-content/mu-plugins folder, not managed from the WordPress dashboard like other plugins.

On the project I've been working on, I started out with the plugin. Follow the directions there to get started.

Override Folders

The instructions for this are included at the link above. In my case, I copied them into the active theme as mentioned in the directions.

Galaxy CLI

Galaxy CLI is optional, but it's nice to have. Make sure to use the galaxy CLI configuration described on the Install page. You'll want to place it at the root of your WordPress website.

From the site root, listing available commands is as simple as running:

php galaxy list

Like Laravel's artisan CLI, there are a number of make: commands for custom commands, controllers, models and many other framework components.

Using a child theme?

In the directions on that page, there's a caveat mentioned that TypeRocket doesn't properly detect child themes. If your active theme is a child theme, configure this constant below in your wp-config.php file to point to your child theme's folder:

define('TYPEROCKET_OVERRIDE_PATH', __DIR__ . '/path/to/my/child/theme/folder');

Is it working?

Let's see! Start by creating a controller:

php galaxy make:contoller base TestController

Inside your theme, this will create a controller at app/Controllers/TestController.php.

Since we chose to make a base controller, you'll notice this controller is scaffolded with method stubs for each CRUD-style action you may use. We only need 1 method though (index() for this article), so feel free to delete the others if you want.

Inside that method, let's return a view:

public function index()
	return tr_view('tr.test');

Next let's create that view. Like Laravel, TypeRocket uses dot notation for resource files. Also like Laravel, view file paths start at resources/views.

So let's create a basic HTML file at resources/views/tr/test.php:

<html lang="en">
		<title>Hello World!</title>
		<h1>We're live!</h1>

Lastly, let's register a route. Open your routes/public.php file and add this:

	->do([\App\Controllers\TestController::class, 'index']);

Then visit your site's new /tr/test/ URL. You should see a page saying "We're live!"

There it is, that easy!

As you can see in our example route, TypeRocket's router gives you a fluent syntax to work with, similar to Laravel's. It does this with its models and some other tools as well.

One last example: using models

Like Laravel, TypeRocket also has a Models concept for database entities. You can create custom models and migrations for them. Using them is also similar to using Eloquent models, just with different methods and no facade-like static calls to query builder methods. If you want to call them fluently like with Laravel models, you'll need to start the chain with <model>::new().

Also unlike Laravel, TypeRocket ships several base model types out of the box rather than 1. This is to provide extra compatibility with WordPress's built-in data types. For example:

  • the User model, which extends the base model WPUser
  • the Post model, which extends the base model WPPost
  • the Page model, which also extends WPPost

To demonstrate, let's get all of our posts to display in our test view. WordPress always starts out with a Hello World post, so there will only be 1 for now.

In our TestController, update the index() method like this:

public function index()
	$posts = Post::new()

	return tr_view('tr.test', [
		'posts' => $posts,

The findAll() method can be used similarly to Eloquent's all(), except for 2 differences:

  • It doesn't run the query immediately; you still have to call get().
  • You can pass an array of IDs for models to be retrieved: findAll([1, 2, 3]).

And like with Laravel's views, you pass the data to the view as an array. The array keys will be extracted to local variables in the view, like $posts.

In our view, let's add some of our post data into a basic table:

		<?php foreach ($posts as $post): ?>
			<td><?= $post->ID ?></td>
			<td><?= $post->post_title ?></td>
			<td><?= $post->post_name ?></td>
		<?php endforeach; ?>

And there you go, a list of posts!

A note to avoid a non-Composer install pitfal...

Before ending, I wanted to mention an issue I ran into recently so it hopefully doesn't happen to you.

Remember that we covered using the TypeRocket plugin instead of installing TypeRocket with Composer? This can result in Composer package conflicts later on if you install Composer packages at the project level.

In my case, I later installed spatie/ignition just so I'd have better-looking error pages to work with, which brings in symony/console 7 as a dependency.

TypeRocket uses symfony/console 6 for its custom console commands though. Ignition does support version 6 as well, but it pulls in version 7 if something else hasn't pulled in 6 as a project-level Composer dependency.

If you do actually want to use the plugin instead of installing via Composer and you do want to use Ignition or anything else depending on symfony/console, you can avoid this issue by installing symfony/console 6 first at the project level.

Wrapping up

There's plenty more to talk about, so maybe I'll write another post on TypeRocket later—better-covering MVC, models, migrations and working with custom post types.

Hope you enjoyed and that you'll want to come back for the next part!

Please confirm whether you would like to allow tracking cookies on this website, in accordance with its privacy policy.