Laravel: Organizing your sea of Views

Order above all things

Italo Baeza Cabrera
5 min readMar 23, 2020

Most normal applications use a lot of views. When you’re over a dozen, you start to make Blade views in your application wherever you can to not refactor the whole views paths. And then you lose it: Where are the components? And the layouts? Does this layout should be put here, or there?

I always think ahead of using views, and after many iterations, I ended up with this directory tree.

views/
├── mail
│ └── ...
├── components
│ ├── post-card.blade.php
│ ├── user-card.blade.php
│ ├── password-input.blade.php
│ └── image-container.blade
└── web/
├── layout
│ ├── header
│ │ ├── links.blade.php
│ │ ├── css.blade.php
│ │ └── js.blade.php
│ ├── header.blade.php
│ ├── head.blade.php
│ └── footer.blade.php
├── sections
│ ├── static
│ │ ├── home.blade.php
│ │ ├── about.blade.php
│ │ ├── contact.blade.php
│ │ └── layout.blade.php
│ ├── profile
│ │ ├── show.blade.php
│ │ ├── security.blade.php
│ │ ├── preferences.blade.php
│ │ └── layout.blade.php
│ ├── comment
│ │ ├── index.blade.php
│ │ ├── show.blade.php
│ │ ├── edit.blade.php
│ │ └── layout.blade.php
│ ├── user
│ │ ├── index.blade.php
│ │ ├── show.blade.php
│ │ ├── edit.blade.php
│ │ └── layout.blade.php
│ └── post
│ ├── subviews
│ │ ├── comment.blade.php
│ │ ├── author.blade.php
│ │ └── tags.blade.php
│ ├── index.blade.php
│ ├── show.blade.php
│ ├── edit.blade.php
│ └── layout.blade.php
└── layout.php

My take on organizing the Views directory is relatively simple. As you can see, in my Blog application I have multiple views: static views like the Home, a profile page for the authenticated user, and more views related to comments, users and posts.

Web Views

To separate Web Views from others, like Mails and other Vendor Views, I use the web directory . I consider this directory my starting point for anything that goes over the web, like a truthful HTML page.

This allows me to know where my web views are. I just use it to separate it from the others kinds of channels for the views. For example, if in the next year I need a way push HTML through AJAX, then I can use the ajax folder:

views/
├── mail
│ └── ...
├── components
│ └── ...
├── web
│ └── ...
└── ajax
└── ...

The “Master” Layout

There is a layout.blade.php file in the root folder of the web views, and this is the HTML skeleton for all others.

I usually define in this file the main sections of the whole HTML skeleton, like the <head>, along the <header>, <footer>, and the <main> parts. Depending on the complexity, I leverage the code directly to separate subviews in the layout directory.

While sections are almost mandatory to let views put content inside each part of the view, using stacks in these subviews is very useful to allow other views to inject CSS or JS they need:

// resources/views/web/layout/header.balde.php
<header>
<title>@yield('title')</title>
<link rel="stylesheet" type="text/css" href="/app.css">
<script src="/app.js"></script>
@stack('head-css')
@stack('head-scripts')
</header>

I also put there CSS and JS from other frontend frameworks. This gives me a centralized way to handle and update these when I need to, instead of shoving everything into one view.

Most of the layouts I make end up like this, because I delegate each part of the application into its appropriate section.

Directory Sections

Creating a directory section is useful to categorize what the view is all about, and (hopefully) be the same as the route name.

// routes/web.php
Route::get('post/{post}', 'PostController@show')
->name('post.show');
// PostController.php
public function show(Post $post)
{
return view('web.post.show', ['post' => $post]);
}

Trying to have everything using the same name makes locating and editing them a breeze since you don’t have to guess where your views are and where they are used.

My recommendation is to make directory sections for each model you have, and also for each part of your application where you need to put views that share the same concept: managing posts, show the authenticated user his information…

Section subviews

Everything that uses @include is a subview that mostly depends on the data passed to the parent view itself, so I push them inside it’s own directory to avoid polluting the big views.

These subviews are not meant to be reusable, but can be if another view can call them without further modification. If I need subviews shareable between directory sections, then I would remake them into components.

Doing subviews is a good way to lean the view from too much code. Consider the post.edit view with the following structure:

@extends('web.post.layout')@section('main')
<form method="post">
@csrf
@method('patch')

<input type="text" name="title" value="{{ old('title'}}">
<textarea name="body" value="{!! old('title' !!}">
@include('web.post.subviews.tags')
@include('web.post.subviews.cover')
<button type="submit">Update post</button>
</form>
@endsection

Seems very simple, specially when the tags and cover image management are done separately in their own subview. You don’t have to bloat the view with something you will barely edit or uses 30 lines of code.

Components

By default Laravel finds Components inside the resources/views/components. I consider Components as self-contained views that can injected into anything and won’t break unless you pass something you shouldn’t.

For example, the post-card.blade.php requires a App\Post model instance, and shows something like the post resume:

To render this card there is no need to issue anything more than the post with the needed information, like the title, cover image and excerpt. I can use this component everywhere, like inside post.index, in the sidebar of post.show, or inside a Mail view.

Frontend vs Backend

Sometimes it’s better to separate your Frontend (aka, public facing views) from the Backend (admin app-breaking panel).

This would allow your views to exclude logic related from the frontend area, and have more freedom on what you can do in the backend, specially taking away the role/permission architecture away from the frontend.

views/
└── web/
├── frontend
│ ├── layout
│ ├── components
│ ├── profile
│ └── post
└── backend
├── layout
├── user
├── post
└── comments

The same principles apply, since you are only one additional directory deep now. You are free to separate the layout for the frontend and backend if you need to, may be because you can change and update the frontend separately from the backend.

And that’s practically it. Happy organization of your views.

--

--

Italo Baeza Cabrera

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor. https://italobc.com