Lesson 11 - Simple CMS in Laravel - Working with the date
In the last lesson, Simple CMS in Laravel - Laravel Mix, we focused on the front-end part of our project. We also added Font Awesome
In today's lesson we will explain the work with the date and then we move on to developing a back-end. We will create the main page.
Working with the date
Surely you have already noticed that the data in our application is listed in
the default form from the database in the format Y-m-d H:i:s
.
However, this is something we really don't want to have as it's not exactly
intuitive for users. In addition, the data is stored in UTC format. The time
zone should also be best localized where we live.
In pure PHP, we would always have to call the date()
function
and set the time format ourselves. At best, we would use a library for that.
However, someone for us has already taken care of that, as Laravel uses the
Carbon library by default. This library contains many useful
methods and translations for countless languages. If you are interested in more,
visit the official website of the Carbon
Library.
Application locale settings
Carbon gets the values for the settings from the application configuration
file, which is, as you probably already know, in the config/
folder, more precisely in the app.php
file. In this case, we are
interested in the following values:
timezone
- Defines the time zone for our application. The default value isUTC
. For Central Europe, we could easily useCET
(C entral E uropean T ime), but unfortunately there is a problem with summer time. Therefore, we will use the opportunity to define a continent with a city. If you live for example in New York, setAmerica/New_York
, if you live in Paris, setEurope/Paris
and so on.locale
- Abbreviation for the language that our application should use. The default value isen
. However, if you speak for example French, set locale tofr
. This will change the language configuration for the framework, but also for the given library. If a phrase cannot be found for that language, the default is used. The fallback language is defined by thefallback_locale
configuration value. This value is set as the default to English (en
).
If you don't know how is your timezone or locale abbreviation exactly called, check the time zones or language codes on Wikipedia.
The changes in the file can look like this:
/* |-------------------------------------------------------------------------- | Application Timezone |-------------------------------------------------------------------------- | | Here you may specify the default timezone for your application, which | will be used by the PHP date and date-time functions. We have gone | ahead and set this to a sensible default for you out of the box. | */ 'timezone' => 'America/New_York', /* |-------------------------------------------------------------------------- | Application Locale Configuration |-------------------------------------------------------------------------- | | The application locale determines the default locale that will be used | by the translation service provider. You are free to set this value | to any of the locales which will be supported by the application. | */ 'locale' => 'en',
The changes are now applied to our application. If we try to edit an article, we will see that the date of the last change also fits the local time. But what doesn't fit yet is the date listing, as it still uses the default format. Let's fix it.
If these changes do not affect your application, run the
php artisan config:cache
command in the project root folder. This
is because the configuration values are cached and populated with new values
using this command.
Outputting data in views
Let's start by the view for an article, which can be found in the
resources/views/article/
folder and file named
show.blade.php
. There we list only the date of the last change of
the specific record in the footer of the article. So we will create a new object
of the Carbon
library class and then print the time difference
compared to the last change using the localized diffForHumans()
method:
@php $updatedAt = new Carbon\Carbon($article->updated_at); @endphp <footer> <p class="small text-secondary border-top pt-2 mt-4"> <i class="fa fa-calendar"></i> {{ $updatedAt->diffForHumans() }} </p> </footer>
In addition to the classic PHP tags, the Blade directive
@php ... @endphp
can be used. There is no difference between them,
only (and perhaps other developers will forgive me for this comment) it is a
matter of beautifying the code of a given view.
If we display an article now, we'll see output similar to this in the footer of the article:
Our application looks a little more professional again. Unfortunately, our solution is no longer so good. The procedure is, of course, flawless and works exactly as we would like. For example, imagine that you have 10 different data on one page, and you always have to create a new Carbon class object for all that data. This would be a bit lengthy and at the same time the code would become confusing.
Data of the record as an instance of the Carbon library
As you have probably noticed in previous lessons, everything can always be
simplified. The same is true for data of the record, which is always represented
in the model instance as an object of the Carbon
class inheriting
the PHP DateTime
class. So we don't have to bother creating a new
object and we can immediately access the methods of this library.
Other dates that should work on the same principle in a given
model are defined in the $dates
variable. The
created_at
and updated_at
attributes are already
automatically included. Therefore, if you want to define additional data, it is
unnecessary to specify it again.
So we can adjust the part of the view with the footer to the following form:
<footer> <p class="small text-secondary border-top pt-2 mt-4"> <i class="fa fa-calendar"></i> {{ $article->updated_at->diffForHumans() }} </p> </footer>
Localized date
We will probably agree that the exact date should be displayed to the user in
the article. We can use one of the many available methods,
isoFormat()
, because one of the advantages is localized output
(which does not apply, for example, to the format()
method):
<footer> <p class="small text-secondary border-top pt-2 mt-4"> <i class="fa fa-calendar"></i> {{ $article->updated_at->isoFormat('LLL') }} </p> </footer>
The output may look similar to this:
More options for localized output can be found in the official Carbon library documentation.
Subsequently, we will also adjust the display of data in the article
administration so that these outputs are unified. So we open the view
resources/views/article/index.blade.php
and modify the following
part of the table:
<td>{{ $article->description }}</td> <td>{{ $article->created_at->isoFormat('LLL') }}</td> <td>{{ $article->updated_at->isoFormat('LLL') }}</td> <td>
Main page
We will end the improvement of our application by creating a main page (homepage) for our website. For now, it will suffice for us to contain only a list of the latest articles.
Let's start with the controller first.
Single action controller
As we have already said, the controller for displaying the main page will
define only one action. However, we pause at the method name for the given
controller action. What should we name it? Names like show()
or
index()
are not very suitable, as it is not a CRUD controller
working with one instance of the model (on the main page we do not have to
display only a list of articles and we also have one CRUD controller for the
given model). You may come up with something like getHome()
, but
that's not the best approach either.
For such cases Laravel defines so called Controllers single
action (Single
Action Controllers). These controllers are characterized by the fact that
they define only a single __invoke()
method, which can accept
parameters just like any other action.
Let's now create such a controller via the Artisan
make:controller
command. But before that, let's look at its
possibilities:
php artisan help make:controller
We already know the --model[=MODEL]
option from previous
lessons. However, this time we will be interested in the
--invokable
option, which will create a single action controller.
We will call it WelcomeController
:
php artisan make:controller --invokable WelcomeController
The newly generated controller can be found in the folder with the
controllers app/Http/Controllers/
and contains only the mentioned
method __invoke()
:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; class WelcomeController extends Controller { /** * Handle the incoming request. * * @param Request $request * @return Response */ public function __invoke(Request $request) { // } }
We will use this method to display the main page. So it will be enough for us
to return the view to which we pass the collection of the latest articles using
the Eloquent method latest()
:
/** * Display the main page of the site. * * @param Request $request * @return Response */ public function __invoke(Request $request) { return view('welcome', ['articles' => Article::latest()->get()]); }
We must not forget to import our model and classes mentioned in the documentation:
use App\Article; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\View\Factory; use Illuminate\View\View;
Routing
The routing of single-action controllers is a bit different - we do not
define the method of the given controller, but only its name. To display the
main page using this controller, we need to add the following call to the
get()
method of the routing class Route
to the
routes/web.php
routing file:
Route::get('', 'WelcomeController');
As you can see, we only define an empty string as a URI action. Thus we
achieve that when you view the site without any other parameters in the URL
executes method __invoke()
controller for the main page
WelcomeController
.
We must also not forget to link the main page in the menu of our main
template resources/views/base.blade.php
. To do this, we use the
helper function url()
:
<nav class="my-2 my-md-0 mr-md-3"> <a class="p-2 text-dark" href="{{ url('') }}">Main page</a> <a class="p-2 text-dark" href="{{ route('article.index') }}">Articles</a> <a class="p-2 text-dark" href="#">Contact</a> </nav>
View
We end the main page by creating a view named welcome.blade.php
in the folder with views resources/views/
. At the moment, he will
not be in charge of anything other than listing all the articles from our
database that we have submitted in the event controller method:
@extends('base') @section('title', 'Simple content management system in Laravel') @section('description', 'Sample tutorial for a simple content management system in the Laravel framework from the programming social network itnetwork.cz') @section('content') <h1 class="text-center mb-4">Simple content management system in Laravel</h1> @forelse ($articles as $article) <article class="article mb-5"> <header> <h2> <a href="{{ route('article.show', ['article' => $article]) }}">{{ $article->title }}</a> </h2> </header> <p class="article-content mb-1">{{ $article->description }}</p> <footer> <p class="small text-secondary"> <i class="fa fa-calendar"></i> Last modified {{ $article->updated_at->diffForHumans() }} </p> </footer> </article> @empty <p>There are no articles yet.</p> @endforelse @endsection
If we now open the main page via a link in the menu or by entering the URL of
our application (in the case of the built-in web server
http://127.0.0.1:8000/
), we will see a list of the latest articles
along with a link to them and their last modified date:
Now we completed the improvement of our project. If you did not succeed, you can download the project from the attached archive or ask in the comments below.
In the next lesson, Simple CMS in Laravel - Contact form, we will create a new page, more precisely a contact form. Let's see how you can work with emails in the Laravel framework.
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 10x (49.77 MB)
Application includes source codes in language php