Checklist for setting up a new Laravel app

My selfie

James Turner,

Tags: Laravel

In this post:

Recently, I wanted to start a new Laravel project. It had been a couple of months since the last one, and it took my brain a while to get into gear. Time is money, so for next time, this post is a basic checklist of the steps involved. I'm assuming familiarity with Laravel, PHP and the command line interface. If you're not familiar with Laravel and want to get started, I can recommend DevMarketer's YouTube playlist, How to build a blog with Laravel. I haven't done any collaborative projects with Laravel yet, so there might be additional steps for teams. I use WampServer, so there might be differences if you're using some other AMP stack. At time of writing, the current version of Laravel is 5.4.

Create new project

Set up your new project by navigating to the root file in your projects folder and running the following:

$> cd \wamp64\www
$> laravel new appname

Set up database

Create a new database and set up a new user with a random name and password (if you're stuck, try random.org). Here are the commands for MySQL:

$> cd \wamp64\bin\mysql\mysql5.7.9\bin
$> mysql --user=root -p
mysql> CREATE DATABASE mydatabase;
mysql> CREATE USER '{username}'@'localhost' IDENTIFIED BY '{password}';
mysql> GRANT ALL PRIVILEGES ON mydatabase.* TO '{username}'@'localhost';
mysql> exit;

Add the database name, username and password to your .env file. You'll need to repeat this process for your production site.

First model and migration

Set models and migrations up at the same time with this command:

$> cd \wamp64\www\appname
$> php artisan make:model ModelName --migration

Run first migration

Run your first migration(s). This will set up the authentication tables as well as whatever you created in the above step:

$> php artisan migrate

When I run my first migrations, I sometimes get error 1071 Specified key was too long. This is caused by my version of MySQL being out of date (must add to todo list!). The solution is to add this code to /app/Providers/AppServiceProvider:

use Illuminate\Support\Facades\Schema;

public function boot()
{
	Schema::defaultStringLength(191);
}

It may take a few refreshes to get it working. See full solution: Laravel 5.4 Key Too Long Error.

First controller

To set up a controller with stubs for the seven basic resource methods (create, store, edit, update, index, show and destroy), run the following command:

$> php artisan make:controller SomeController --resource

I wrote about DRY resource controllers. To use this, create a new controller, GenericResourceController, and copy-paste the sample code. Use this as the parent class for your app's controllers.

Quick reminder: to use a controller, assemble any data you need, then send to view:

public function create() {
	$foo = $this->getFoo();
	return view('bar.create')
		->withFoo($foo)
		;
}

Don't forget to include your model at the top, and you may need Auth, too (see Set up auth), below:

use App\MyModel;
use Auth;

First route

To set up URLs for a new resource type, in routes/web.php add:

Route::resource('photos', 'PhotoController'); // url, controller name

In a resource route, you can omit specific routes like so:

Route::resource('photos', 'PhotoController', [
	'except' => [
		'index',
		'show',
		// etc.
	]
]);

Just a quick reminder, individual routes need a name, and parameters are passed in through curly brackets, e.g.:

Route::post('/myResource/{id}/doMyThing', 'MyController@myMethod')->name('myResource.doMyThing');

You can now output this route as a URL in views and controllers with the function route('myResource.doMyThing'). The command for checking which routes are available in your app is:

$> php artisan route:list

For more on routes, including groups, middleware, regex constraints and so on, see Routing in the Laravel documentation.

Set up auth

Rather than writing your own HTML template from scratch, you can use the one that Laravel creates when you set up auth. Using this template saves a bit of time, and it's easy enough to customise later. After you've run the command below, find the template at /resources/views/layout/app.blade.php:

$> php artisan make:auth

When you've set up authentication, you can add the following function to controllers to make sure only logged-in users can access private areas:

public function __construct(){
	$this->middleware('auth');
}

First view

Create a new view folder for your first resource type, /resources/views/myresource, and your first Blade file for a view, create.blade.php.

Just to get started, here's a basic template for Blade views:

@extends('layouts.app')

@section('title', '| Page Title')

@section('content')
  // content goes here
@endsection

NOTE: To get the page title to appear, add this to /resources/views/layout/app.blade.php:

<title>{{ config('app.name') }} @yield('title')</title>

Add HTML form helpers

You can skip this step if you want. Summary:

$> composer require "laravelcollective/html":"^5.2.0"

Next, add your new provider to the providers array of config/app.php:

'providers' => [
	// ...
	Collective\Html\HtmlServiceProvider::class,
	// ...
],

Finally, add two class aliases to the aliases array of config/app.php:

'aliases' => [
	// ...
	'Form' => Collective\Html\FormFacade::class,
	'Html' => Collective\Html\HtmlFacade::class,
	// ...
],

To use the form helpers, you need to open a form in a view. You can use the open() method for a new record:

{!! Form::open(['route' => ['route.name', $user], 'method' => 'POST', 'class' => 'form', 'files' => true]) !!}
// ...
{!! Form::close() !!}

You can use the model() method to edit an existing record:

{!! Form::model($object, ['route' => ['route.name', $user], 'method' => 'POST', 'class' => 'form', 'files' => true]) !!}
// ...
{!! Form::close() !!}

Read more at Forms & HTML on Laravel Collective.

Install Node packages

Before you start, you might want to make sure NPM is up to date:

$> npm update npm -g

And you might also need to update Node.js.

For your project, decide which packages you want to install. By default, packages.json includes a lot of extras that you might not need. In particular, laravel-mix causes problems for Windows because of the insane folder structure (see discussion at How to deploy Node.js application with deep node_modules structure on Windows?). Edit the list under devDependencies as needed. You can always keep a backup or just comment out the ones you don't need.

When you're happy, install Node packages (this may take a while, so do something else while it's running in the background):

$> npm install

Sass and Bootstrap

If you've installed bootstrap-sass via npm, go to resources/assets/sass/app.scss, and update the Bootstrap section:

// Bootstrap
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap";

It may be that you want to customise Bootstrap, for example, by omitting the grid stuff (especially now that CSS Grid is on the rise). Editing _bootstrap.scss directly in the node_modules folder isn't a good idea because it could get accidentally overwritten. Instead, make a copy in resources/assets/sass, adjust the file locations, and import this into your app.scss. For example:

// resources/assets/sass/_bootstrap_custom.scss
// Core variables and mixins
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables";
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins";

// Reset and dependencies
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/normalize";
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/print";
@import "../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/glyphicons";
// etc.

I hate these fragile relative filepaths. I tried adding a $sass-bootstrap-filepath variable to tidy it up, but but it turns out you can't use Sass variables in an @import command. I'm sure there's a better way, so answers in the comments, please!

Add your custom CSS at the end of the file. I tend to prefer an ITCSS structure:

// Custom Styles (ITCSS)
@import "custom/settings";   // variables
@import "custom/tools";      // functions, mixins
@import "custom/generic";    // resets, body & html styles
@import "custom/elements";   // global, un-classed elements
@import "custom/objects";    // site-wide objects, e.g. .wrapper
@import "custom/components"; // individual pieces of UI
@import "custom/trumps";     // !important

When you're happy with app.scss, run Sass in a new CLI window:

$> start sass resources/assets/sass:public/css --style=compressed --watch

Read more: Laravel and Bootstrap setup (July 2015)

Custom JS

I don't tend to use frontend build tools for JS, so I just add my project's JS scripts to /public/js, then add a <script> tag in resources/layouts/app.blade.php. I may also add public/js/app.js, which includes jQuery, Bootstrap, Vue.js, and a few other libraries. I try to be careful about forcing site users to download unnecessary crap, and at 285KB, app.js is off-limits unless I'm really going to use all of it. If not, individual components can be downloaded separately.

Git Ignore

Before your first commit, make sure you update .gitignore. In addition to the default .gitignore, you might also want to add:

/bootstrap/compiled.php
/vendor
/build/logs
/build/coverage
/app/tests/_log
composer.phar
composer.lock
.DS_Store
/.idea
/.sass-cache
/_ide_helper.php
/app/config/packages
/public/packages
/node_modules
.env

The guiding principles are to version control only those files which a developer is likely to touch, and to avoid committing anything that could jeopardise security or that's specific to your dev environment. The list of files to ignore includes Laravel's core files, third-party packages, database credentials, and other guff like logs and IDE indicies. Read more: Version controlling Laravel: Which files should I ignore? (August 2016) and .gitignore what should be ignored? (2015).

First commit and push

Some basic commands to get started. First, initialise the project:

$> cd \path\to\project
$> git init

Link to Git repo:

$> git remote add origin /path/to/origin.git

Add untracked files:

$> git add .

First commit:

$> git commit -m "Initial commit"

First push:

$> git push -u origin master

Conclusion

Final step: give yourself a doughnut. This post is mainly for my benefit, to improve my muscle memory, but I just thought it might be useful to somebody, somewhere. If you've got this far, I've no doubt you'll find there are other steps that I've missed. For example, I'm not particularly sophisticated when it comes to build tools like JS post-processors and image compressors, and I haven't built a Laravel app using a JS framework yet, although that's on my radar. If you feel I've missed anything really crucial, though, do leave a comment.

Skip to navigation