© 2024 Flywheel Co.
At Flywheel we build a lot of different types of software for the web. That could be anything from a single html page to a full-featured web application. A good portion of the programming and development we do is built using Laravel so naturally we were pretty interested in Laravel Nova and how we could use it for our internal projects and projects with our clients.
To understand what Nova is you need to have at least a basic understanding of what the PHP framework Laravel is. Nova is a layer of code that sits alongside your Laravel application and lets you easily build an administration panel using the underlying application structure. Nova doesn’t (with some small caveats) communicate with your database directly. It relies on your application's models and services for all of the heavy lifting. To gauge what we like and don't like about Laravel Nova we need to understand how we might use it and how it would fit into our workflow at Flywheel. It really depends on the type of project we're building. There's no one single solution to the content management problem (for us, at least). From a development perspective, no matter what tools we use to get the job done we find ourselves heavily customizing solutions. After a long enough time customizing things you realize that you're spending as much time building those tools that as you are actually building the project. Part of what has drawn us to Nova is that it meets us in the middle.
If you're a fan of Laravel you'll likely find that integrating what you have already built is a familiar and straight forward process. The first step is understanding the language around Nova. Resources, Tools, Lenses, Fields, Cards, Actions, etc… Once you get those it starts to clear up. I think you can get started by just knowing what Resources and Fields are. I’ll touch on the very basics here.
With those two tools alone you can build a very, very basic CMS from your existing Laravel application.
We recently did an overhaul on an existing customer application. This was a relatively non-complex application and we wanted to use it as a test-case for Nova as a real, customer-facing content management system. It fit perfectly in line with some upgrades that we were already doing and gave us the chance to unify an older code-base. We took the dive and found some things that made a lot of sense and others that miss the mark so far.
Diving into Nova the first time was a pretty smooth experience. We already had the application built. The models existed, migrations existed, controllers, views... all of it. There was a front-end that is public facing and there was a back-end that is accessed via email and password. This back-end was built and maintained but adding to it over the years made it a prime candidate for the re-build.
Unless you start customizing Nova you won't touch a single view file or blade template. Everything (just about) is controlled via the Resource file. The front end of Nova is almost entirely controlled through the ->fields()
method by returning an array of Laravel Nova Field objects. Like I mentioned before, these Nova Fields are classes that represent columns in your Eloquent Models. That means that when you want to create a title for your blog article you would create something like Text::make(‘title’)
and when you want to write content for your blog article you could use a Textarea::make(‘body’)
or some of the fancy built-in rich-text editors like Trix and Markdown.
Let's say that your application is for a local baseball team. Right now, you are hard-coding all of the team members into a template file. Every time a team member changes, you or one of your co-workers is changing the blade template to show the team member change rather than having the team captain make the update. (Silly example, I know). With Nova it's really, really easy to migrate that type of scenario into a content management scenario that anybody with a valid username and password could control. At its most basic level, Nova is an admin panel for CRUD interactions.
We'll use the example baseball team above to create a Model
and Migration
like we normally would. No Nova involved. To get started you can use Artisan to build out the model and migration in one command.
php artisan make:model TeamMember -m
This will create a TeamMember.php
file in your app
directory and a new migration in your database/migrations
directory. Let's open that migration file and create a simple team members table for our local baseball team.
public function up()
{
Schema::create('team_members', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('position');
$table->integer('number');
$table->text('bio')->nullable();
$table->boolean('starter')->default(false);
$table->timestamps();
});
}
Now we can save our migration and run php artisan migrate
to add the table to our database.
Up until now everything we’ve done has been all Laravel. We have a new database table for team_members
and we can interact with the App/TeamMember
model like we would any other time. Now, though, we want to make all of these new members and their fields editable via an administration panel. This is where Nova comes into the example. We'll create a Nova Resource to interact with the new team member table. To build the Nova Resource that uses our App/TeamMember
model we run the Nova Resource artisan command.
php artisan nova:resource TeamMember
This command will create a file in your app/nova
directory and allow us to start adding fields that coincide with the fields we created in our Team Member migration file. Open up your new nova resource file and look for the public function fields(Request $request)
method. This is where everybody meets on the dance floor. This function returns an array of Nova Field objects that define how Nova should display a Team Member. Remember, Nova is using your application's TeamMember model.
public function fields(Request $request)
{
return [
Text::make('First Name')->rules('required'),
Text::make('Last Name')->rules('required'),
Text::make('Position')->rules('required'),
Number::make('Player Number', 'number')->rules('required'),
Boolean::make('Starter'),
Textarea::make('Biography', 'bio'),
];
}
With only these few lines of code we're able to create, read, update and delete all team members for our baseball team. The various fields returned define how that field will interact in table views (listing all team members), forms (adding or editing a team member) and detail views (looking at a single team member). These fields are smart, too. Fields like Textarea
are smart enough to know that that typically you wouldn't want to see every player biography in your list of team members but you would want to see that if you were looking at an individual team member.
Note : This is a very, very basic example of what Nova can do in a short amount of time. We've only touched a very small part of what's possible.
The easy parts of Laravel Nova are really easy. I am a pretty biased opinion, though. I have enjoyed working with Laravel for years and love how it feels to build things quickly and use a syntax that, to me, makes a lot of sense. In a few hours/minutes you can get a fully functioning admin panel that would have potentially taken days to build in the past. It's really great to see things come together quickly and have it look great and work well. But... If you can't get exactly what you want to happen, you need that one extra feature, or just want to extend past the basics then you're going to start down a little bit of a steeper slope.
In my opinion, customizing Nova is unnecessarily complex. You'll (probably) have to be familiar with front end build tools. You'll definitely have to have an understanding of how Vue and Vue Components work. You'll (probably) have to be familiar on some level of API best practices. You’ll (probably) have to have a more-than-basic understanding of Composer. It can be intimidating.
Customizing Nova and how those customizations get shared with other developers is going to be key to Nova's success. That's part of why it chose to do customization the way it did. Creating seemingly small customizations through Nova’s command line scaffolding will create an entire composer package that you can share with the world via composer. You aren't re-inventing the wheel every time and Nova isn't promising too much out of the box. Win-win, right? It's yet to be seen if developers will create the really, truly useful things that almost every content management system needs (and then make them open source for a licensed piece of software) or if Nova will stay somewhere between a content management system and an application dashboard.
tail
command or use a profiler. Small grumble, but there it is.There's plenty of room for competition in the administration dashboard / content management system world and we’ll certainly find our use-cases for Nova even in it's early stages. I would love to see the ecosystem around Nova grow. I would also love to see a more streamlined way to creating customized features of Nova. In the end, to get more than the basics you'll still find yourself building quite a bit outside of Nova's default documentation.
We're left with some questions.
As a business that does a lot of work in Laravel, we really like it as an option when it makes sense. It's a case-by-case basis and, at the time of this writing, it's still in its v1.1.x
stages. The early signs are promising and considering how quickly we can drop it into an existing Laravel application it's pretty hard to beat.
We have another Laravel Nova blog post if you want to keep reading. Check out how we're using Larvel Nova in 2020.
Matt Higgins
Matt is a co-founder, creative director, and programmer at Flywheel. He's made literally tens of people laugh in his lifetime and is always looking for the next problem to solve.