Get up to 80 % extra points for free! More info:

Lesson 7 - Simple CMS in Laravel - Article listing

In the last lesson, Simple CMS in Laravel - Migration, we focused on migrations and created a model layer for articles.

As I promised, in today's lesson we will continue to create a controller and start displaying the article.

Routing

Let's start by defining routes for articles. We will open the file routes/web.php and remove the default route for the main page, as we will not need it in our project yet. Instead, we define that the CRUD controller created by us will process requests for articles:

Route::resource('article', 'ArticleController');

We used the resource() method to define routes for all CRUD controller actions. We already know that these are actions for adding, viewing, editing and deleting an article. We can verify the result with the command php artisan route:list:

+--------+-----------+------------------------+-----------------+------------------------------------------------+------------+
| Domain | Method    | URI                    | Name            | Action                                         | Middleware |
+--------+-----------+------------------------+-----------------+------------------------------------------------+------------+
|        | GET|HEAD  | api/user               |                 | Closure                                        | api        |
|        |           |                        |                 |                                                | auth:api   |
|        | GET|HEAD  | article                | article.index   | App\Http\Controllers\ArticleController@index   | web        |
|        | POST      | article                | article.store   | App\Http\Controllers\ArticleController@store   | web        |
|        | GET|HEAD  | article/create         | article.create  | App\Http\Controllers\ArticleController@create  | web        |
|        | GET|HEAD  | article/{article}      | article.show    | App\Http\Controllers\ArticleController@show    | web        |
|        | PUT|PATCH | article/{article}      | article.update  | App\Http\Controllers\ArticleController@update  | web        |
|        | DELETE    | article/{article}      | article.destroy | App\Http\Controllers\ArticleController@destroy | web        |
|        | GET|HEAD  | article/{article}/edit | article.edit    | App\Http\Controllers\ArticleController@edit    | web        |
+--------+-----------+------------------------+-----------------+------------------------------------------------+------------+

In addition to the article actions, the table above contains the API action defined in the routes/api.php file. For us, it's currently irrelevant route, so we will ignore it.

The routing table describes the following properties:

  • Domain - For which domain the given route is intended. If the value is empty, the default domain applies.
  • Method - HTTP method of action. Since HTML forms do not support PUT, PATCH or DELETE methods, we will have to modify them a bit. But we will show this in the next lesson.
  • URI - URI of the action (in our case the part in the URL address after the domain).
  • Name - The name of the action used in the code to create the link via the helper route() function (for example, route('article.index') will generate http://localhost:8000/article).
  • Action - The controller method that handles the action.
  • Middleware - A list of middleware through which the request passes.

Also note that in actions, such as views, the {article} parameter is defined in the URI. If we use the same parameter name as the variables in the controller method, we can then obtain an instance of the article only thanks to dependency injection, more further in this lesson.

Pre-prepared article

We will add an introductory article to our table of articles so that we have something to work with before we create anything.

According to the official procedure, we should prepare so-called seeders. But I want to save you that for now. Instead, we'll show you a new Artisan command - the tinker. It's a PHP console through which we can perform any operation, even with framework classes. Then we insert the following code into the console, through which we create a new article:

$article = new App\Article();
$article->title = 'Introduction';
$article->url = 'introduction';
$article->description = 'Introductory article on the web in the Laravel framework.';
$article->content = '<p>Welcome to our website!</p><p>This site is built on <strong>simple content management system in the Laravel framework</strong>. This is an introductory article retrieved from the database.</p>';
$article->save();

Finally, the save() method returns a boolean success value:

Using the PHP console in the Laravel framework to create an article - Laravel Framework for PHP

Controller

Now we move to the controller. There we only modify the show() action to return the view along with the article data:

/**
 * Obtain the article and pass its data to the template.
 *
 * @param  Article $article
 * @return Application|Factory|View
 */
public function show(Article $article)
{
    return view('article.show', ['article' => $article]);
}

We will not forget to add imports for the classes mentioned in the documentation:

use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;

Views

In order to view the article, we will need a view to do so. However, before we start creating one, please remove the generated view resources/views/welcome.blade.php, because we will not need it :)

Web template

We will start by modifying the overall appearance of our application. This will provide the main view of base.blade.php:

<!DOCTYPE html>
<html lang="en-US">
    <head>
        <meta charset="utf-8" />
        <meta name="csrf-token" content="{{ csrf_token() }}" />
        <meta name="description" content="@yield('description')" />
        <title>@yield('title', env('APP_NAME'))</title>

        <link href="{{ asset('css/app.css') }}" rel="stylesheet" />

        <script src="{{ asset('js/app.js') }}"></script>
    </head>
    <body>
        <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
            <h5 class="my-0 mr-md-auto font-weight-normal">{{ env('APP_NAME') }}</h5>
            <nav class="my-2 my-md-0 mr-md-3">
                <a class="p-2 text-dark" href="#">Main page</a>
                <a class="p-2 text-dark" href="#">Articles</a>
                <a class="p-2 text-dark" href="#">Contact</a>
            </nav>
        </div>

        <div class="container">
            @if ($errors->any())
                <div class="alert alert-danger mb-4">
                    <ul class="mb-0">
                        @foreach ($errors->all() as $error)
                            <li>{{ $error }}</li>
                        @endforeach
                    </ul>
                </div>
            @endif

            @yield('content')

            <footer class="pt-4 my-md-5 border-top">
                <p>
                    Sample tutorial for a simple content management system in the Laravel framework from a programming social network
                    <a href="http://www.ict.social" target="_blank">ict.social</a>
                </p>
            </footer>
        </div>

        @stack('scripts')
    </body>
</html>

In the lesson Simple CMS in Laravel - Project Structure, we imported the CSS framework Bootstrap into the project. I used Bootstrap when I was creating this template. I downloaded one of their examples and modified it a bit so that our site looks at least a little good. :)

Also notice these Blade Directives on the template above:

  • @yield('hodnota') - One value is expected to be passed from the view that inherits that view. For example, the title from the current subpage template is passed to the main template. We can also define a default value, which we use for the page title. The block value is assigned by the Blade directives @section (or @endsection).
  • @stack - This is a collection stack unlike @yield. This is useful for adding scripts, as we can pass them in multiple views for one page. Values are added to the stack using the Blade directives @push (or @endpush)

View article

In the view for displaying the article, which we will create in the resources/views/article folder named show.blade.php, we will inherit our main template and then use the blocks we have defined:

@extends('base')

@section('title', $article->title)
@section('description', $article->description)

@section('content')
    <h1>{{ $article->title }}</h1>
    {!! $article->content !!}
@endsection

Since the framework protects us from XSS attack by escaping the output text, we must use {!! !!} instead of {{ }}. It also contains HTML code.

However, if we now try to view our introductory article via the web page /article/introduction, we will get a 404 error even though everything looks functional. So where is the mistake?

Defining an attribute for the parameter of the route

By default, Laravel retrieves data from the database using its ID. To view the introductory article, we would have to use the address /article/1. However, this is unwanted behavior of the application, as each of our articles has its own unique URL and we want to use it.

In order to apply the article url value in routes using the Article model (parameter {article}), we will need to override the contents of the getRouteKeyName() method in our model, which is inherited from the Model class:

/**
 * Return the name of the attribute by which the article is retrieved from the parameter of the route.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'url';
}

Now when you visit the page /article/introduction we will see our introductory article:

The introductory article in the Laravel PHP framework - Laravel Framework for PHP

We now have the complete basis of the articles.

In the next lesson, Simple CMS in Laravel - Article creation, we'll look at articles creation and viewing its list in the administration.


 

Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.

Download

By downloading the following file, you agree to the license terms

Downloaded 46x (44.44 MB)
Application includes source codes in language php

 

Previous article
Simple CMS in Laravel - Migration
All articles in this section
Laravel Framework for PHP
Skip article
(not recommended)
Simple CMS in Laravel - Article creation
Article has been written for you by Lishaak
Avatar
User rating:
No one has rated this quite yet, be the first one!
Author is interested in programming mostly at web development, sometimes he does funny video edits from his vacations. He also loves memes and a lot of TV series :)
Activities