Lewis Raggett here. I create useful web-based software and applications for a variety of different clients with the rest of my team at...
Lewis Raggett here. I create useful web-based software and applications for a variety of different clients with the rest of my team at Sprechen. I’m used to building out different custom pieces of functionality that extend Backpack to meet a client’s needs but occasionally there comes a more complex need such as, recently, a Kanban board.
This interface has become popular with applications such as Trello, Asana, and GitHub projects as they allow a user to quickly move items between different columns and manage state in a natural and interactive way.
To incorporate this into a Backpack for Laravel admin panel, I needed to write a custom operation to handle the different actions that stem from the user interacting with the front end. This is a Backpack feature that not many people know about, which is a shame, as it can be very powerful. They allow you to segment features of your application, so that functionality can be applied to different controllers without the need to repeat yourself.
Cool right? Here I’ll go through how I used custom operations and how others can do the same to really get the most out of Backpack.
First of all, here’s how the front end that will use my operation looks.
All of the backend functionality it uses comes from a single operation and is applied to two different CRUD controllers and I expect more soon.
To start off, I made a new directory for operations to sit in. I tend to put it within
App\Http\Controllers to keep it close to the controllers that will use it.
Next up is creating the operation file. Operations are PHP traits, so I start by creating a simple trait with a function called
setupKanbanRoutes. If your operation is called KanbanOperation then there’s no need to change the name but if you had NamingOperation, you’d need to call it
setupNamingRoutes for it to work.
This function is incredibly useful as it means that routes can be defined for a specific purpose and don’t need to be repeated for each different model. It saves having to write out routes repeatedly for each use of the operation. I’ll come back to this function, first I’ll write out the functions which make the operation work.
Operations can hold any functions and code you need them to and keep CRUD controllers free of anything that isn’t CRUD related, in my case I wrote functions that would:
Within these functions you have access to all the data you would inside a CRUD controller such as the associated model, its resource route, as well as the request.
Now that the functionality has been written, I can define routes so that they can be called.
To do this, I go back to the first function
setupKanbanRoutes and define routes in the same way as I would within a routes file. This function is given the controller name, segment name, and route name, which can be used for defining the routes.
Using the segment name in the URI means that it will use the entity name as the prefix for the route and so can be applied to any model. For example, if I added this to a CRUD controller for a model called Lead, it would prefix the routes with ‘lead’. You can add any middleware or prefixing to these routes as you would in a standard routes file.
With that, the operation can now be added to the desired controller:
When you list out the application’s routes using
php artisan route:list, you’ll see that routes have been generated for that CRUD controller through the operation!
If the operation was a ‘one size fits all’ set of functions, that would finish it off. However, most functionality needs some sort of configuration. To set this up, I use a global variable that is defined within the operation.
This variable should be public so it can be accessed by the CRUD controller.
Data can be added to this variable as needed within the CRUD controller’s setup function. Simply assign the data you need to the variable and it will be available within the operation functions. In my Kanban example, I add in the model that will be used to define each column of the board.
That’s all there is to it! For this same client I’ve ended up building an inbound email parser, data imports, and a global search all through extending Backpack.
If you would like to know about any of those as well or anything else about operations, let me know in the comments below. Of course, if you’d rather have me build it for you, go ahead and get in touch! I’d love to have a chat.
Full stack developer at Sprechen
What do you think about this?
Wondering what our community has been up to?