Backpack for Laravel

Backpack for Laravel

A collection of Laravel packages to build a custom admin panel.

Documentation    Support

How to use (full example)

This page will help you understand how Backpack\CRUD works, how you can use it and ends with a tip of how you can do it all very very fast.

The easiest way to read this:

  1. Read everything except the blue bubbles. They go in a bit of detail.
  2. Read the blue bubbles. If you don't understand what they're talking about, re-read that section.
  3. You got this. Start coding!

Introduction

Backpack\CRUD is a fast way to build admin panels with Create, Read, Update, Delete functionality. One panel provides functionality for CRUD operations on one Eloquent Model.

Most of the times, a CRUD Panel consists of:

  • a database table (and maybe connection tables for relationships);
  • a Model;
  • a Controller for the CRUD operations;
  • 0, 1 or 2 Request files (if form validation is needed);
  • a route;

Simple example

Let’s take the Tag entity and create a CRUD Panel for it. We're going to create the CRUD Panel manually, which will take some time but is useful in order to understand how it works. At the end of this page you'll be presented with a way to do it all in under a minute, using generators.

Its CRUD interface consists of:

  • a database table (tags)
  • a model (app/Models/Tag.php)
  • a controller (app/Http/Controllers/Admin/TagCrudController.php)
  • a request (app/Http/Requests/TagCrudRequest.php)
  • a route

The database table

Of course, any entity stored in a database needs at least a table. The tag entity needs one too, “tags”, which looks like this:

Nothing fancy here.

The model

On your standard Eloquent model, make sure you:

  • use the CrudTrait;
  • properly define your relationships to other Models (to be able to use them in the CRUD interface);
  • define either $guarded or $fillable for the CRUD to know which columns are editable;
  • [optional] store it in app/Models (because you may end up having a lot of them);
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Backpack\CRUD\CrudTrait;

class Tag extends Model {

	use CrudTrait;

    /*
	|--------------------------------------------------------------------------
	| GLOBAL VARIABLES
	|--------------------------------------------------------------------------
	*/

	protected $table = 'tags';
	// protected $primaryKey = 'id';
	// protected $guarded = [];
	// protected $hidden = ['id'];
	protected $fillable = ['name'];
	public $timestamps = true;

	/*
	|--------------------------------------------------------------------------
	| FUNCTIONS
	|--------------------------------------------------------------------------
	*/

	/*
	|--------------------------------------------------------------------------
	| RELATIONS
	|--------------------------------------------------------------------------
	*/

	public function articles()
    {
        return $this->hasMany('App\Models\Article', 'article_tag');
    }

	/*
	|--------------------------------------------------------------------------
	| SCOPES
	|--------------------------------------------------------------------------
	*/

	/*
	|--------------------------------------------------------------------------
	| ACCESORS
	|--------------------------------------------------------------------------
	*/

	/*
	|--------------------------------------------------------------------------
	| MUTATORS
	|--------------------------------------------------------------------------
	*/
}

The controller

As an official convention:

  • the controller is stored in app/Http/Controllers/Admin
  • its filename is EntityCrudController.php

But you can can use another location/name if you want to. Take a look at it:

<?php namespace App\Http\Controllers\Admin;

use Backpack\CRUD\app\Http\Controllers\CrudController;

// VALIDATION: change the requests to match your own file names if you need form validation
use App\Http\Requests\TagCrudRequest as StoreRequest;
use App\Http\Requests\TagCrudRequest as UpdateRequest;

class TagCrudController extends CrudController {

	public function setup() {
        $this->crud->setModel("App\Models\Tag");
        $this->crud->setRoute("admin/tag");
        $this->crud->setEntityNameStrings('tag', 'tags');

        $this->crud->setColumns(['name']);
        $this->crud->addField([
	'name' => 'name',
	'label' => "Tag name"
	]);
    }

	public function store(StoreRequest $request)
	{
		return parent::storeCrud();
	}

	public function update(UpdateRequest $request)
	{
		return parent::updateCrud();
	}
}

Because your controller (TagCrudController) extends the default CrudController class, every CRUD functionality is available for you to use. If you don't like a functionality, you can:

  1. take a look at how it's done in CrudController;
  2. place a method with the same name in your TagCrudController, with the custom logic you need.

Notes

For most cases, your entire panel's logic will be in the setup() method; this is called in the constructor, so anything you customize there will be applied to all CRUD operations; you have access to all variables you need here (the request, the crud, etc); this is where you'll define the basics for the CRUD and specify columns, fields.

The store() and update() functions are needed in each EntityCrudController because the Request needs to be type-hinted in Laravel in order for validation to happen; it's also where you can do custom operations before or after the item is inserted/updated - no callbacks needed.

The requests

This is where you write your validation rules for the Create/Update operations. The app/Http/Requests/TagCrudRequest.php file:

<?php namespace App\Http\Requests;

use App\Http\Requests\Request;

class TagCrudRequest extends \Backpack\CRUD\app\Http\Requests\CrudRequest {

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // only allow updates if the user is logged in
        return \Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|min:5|max:255'
        ];
    }

}

Validation not necessary?

If you need form validation on the create/update views, this request file is necessary. Otherwise, just point the controller to the Backpack\CRUD\app\Http\Requests\CrudRequest class instead, which has no validation rules on it, but does require the user to be logged in.

Differences between the Create and Update validations?

If your Update operation requires a different validation than the Create operation, you can create separate request files and use them in you TagCrudController, for ex: UpdateTagRequest.php and CreateTagRequest.php.

The route

The CRUD routes are based on RESTful controllers, so you only need to define one line for each CRUD Panel, in app/Http/routes.php. Most likely you'll put all routes inside a group, because you'll be using a prefix and middleware:

<?php

// Admin Interface Routes
Route::group(['prefix' => 'admin', 'middleware' => 'admin'], function()
{
  // Backpack\CRUD: Define the resources for the entities you want to CRUD.
    CRUD::resource('tag', 'Admin\TagCrudController');
  
  // [...] other routes
});

Best practice: it’s defined in the “admin” prefix and it uses the “admin” middleware. So the route will be “your_app_name/admin/tag”.

Note: if you want the item to appear in the top admin menu, it’s as easy as including it in the views/vendor/backpack/base/inc/sidebar.php file:

<!-- ================================================ -->
<!-- ==== Recommended place for admin menu items ==== -->
<!-- ================================================ -->
<li><a href="{{ url('admin/tag') }}"><i class="fa fa-tag"></i> <span>Manage Tags</span></a></li>

The result

The table (or list) view:

The insert (or add) view:

The edit (or update) view:

Congratulations, you now understand how Backpack\CRUD works! This is a very very basic example, but the process will be identical for tables with 50+ columns, complicated logic, etc.

Scroll through the stock functionality

Doing it all very fast

December 21st Notice

If you have Backpack\Base 0.7.10+ (you installed Backpack after Dec 21st) you can just install the packages below in your local environment using:

$ composer require backpack/generators --dev
$ composer require laracasts/generators --dev

Backpack\Base will autoload them in your local env, no need to place them inside your config/app.php as service providers.

Here's what you can use, to create each file for the CRUD interface very fast:

So when you use generators, the entire process is:

php artisan make:migration:schema create_tags_table --schema="name:string:unique" --model=0
php artisan migrate
php artisan backpack:crud tag #use singular, not plural
# then manually add this to your routes.php file (under the admin prefix and auth middleware):
# CRUD::resource('tag', 'TagCrudController');

That's blazing-fast, right? You still have to go through the created files, check everything's alright and customize them to your specifications, but a lot of the heavy-lifting is already done. Most notably, you'll need to go in the generated Model and define the $table, $primaryKey and $fillable.

Note: You probably want to place all your admin routes in a route group, where you check if the user is authenticated and use the Admin namespace so your route definitions will be shorter. Here's an example, with the CRUD resource above:

Route::group([
    'prefix' => config('backpack.base.route_prefix', 'admin'),
    'middleware' => ['admin'],
    'namespace' => 'Admin'
], function() {
    // your CRUD resources and other admin routes here
    CRUD::resource('tag', 'TagCrudController');
});

How to use (full example)