Develop an E-Commerce Website With Laravel 5.4 - Part 3
In part 2 we discussed how to transfer HTML of a page in Laravel system. I am now going to tell how to optimize your page by reducing unnecessary requests into one and how to create a master layout that could be used for other inner pages. Right now if you visit the main page on your local machine, it looks like this:
It looks OK if you compare with the original source. If you check the source of it you find multiple <script>
tags and multiple .css
and .js
requests. We are going to eliminate that by taking advantage of another awesome Laravel tool called Laravel Mix.
What is Laravel Mix?
From Laravel's website:
Laravel Mix provides a fluent API for defining Webpack build steps for your Laravel application using several common CSS and JavaScript pre-processors.
Basically Laravel Mix is built on top of Webpack which goes through differnt dependency modules(CSS or JS) and produce static resources so that you can use on your web pages. You don't need to get worried about which JS file is being used in other JS as webpack takes care of dependency graph. Take look at it to learn concepts. If you are coming from Gulp world then it should not so alien for you.
Anyways, now go to app/resources/saas/app.scss
, here you will find some initial entries like:
// Fonts
@import url(https://fonts.googleapis.com/css?family=Raleway:300,400,600);
@import "variables";
// Bootstrap
@import "bootstrap";
I removed all unnecessary inline css link
tags and called @import
to include required libs and other files. Final app.scss
will look like this:
// Variables
@import "variables";
// Bootstrap
@import "bootstrap";
@import "../../../node_modules/font-awesome/scss/font-awesome";
@import "../../../node_modules/flexslider/flexslider";
@import "style";
@import "site";
Now let's open webpack.min.js
file which looks like this:
const { mix } = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
Since Laravel Mix is ES6 based, it is using destructuring assignment here to assign mix
variable. Read further elsewhere about it as this is not the scope of this article.
The next couple of lines doing entire magic; mix.js('resources/assets/js/app.js', 'public/js')
says to read app.js
contents, pull them and put them up in public/js
after mixing them up. Same is for mix.sass
. Since it is using SAAS compatible so you may use CSS or SAAS based syntax to define your layouts. Webpack compiled them to a single CSS anyway. Now in master.blade.php
, all I have to make these two calls for JS and CSS resources respectively:
<script src="{!! asset('js/app.js') !!}"></script>
and
<link rel="stylesheet" href="{!! asset('css/app.css') !!}">
Cool, no? No more hassle of taking care of multiple URLs in your page. In future if you want to add a new library or css file, all you have to do add in relevant entry point file.
Similarly, the final app/resources/js/app.js
looks like this:
require('../../../node_modules/jquery/dist/jquery.min')
require('../../../node_modules/bootstrap-sass/assets/javascripts/bootstrap.min')
require('./move-top')
require('./easing')
require('../../../node_modules/flexslider/jquery.flexslider-min')
require('./minicart.min')
require('./site')
Now, in order to mix them up and put in public/
folder you gotta run a command. Go to your project's root folder and run the following command:
npm run dev
It will read the stuff and put the final output in respective /public/
files. In our case it is app.css
and app.js
If you notice the content, it is simply merging the file which is good if you are in development mode but for final deployment it is still not so good. Mix comes up with a command:
npm run production
which minify all the resources for optimal performance.
OK, so far so good, now it's time to create our master layout a layout by emptying the middle part of it. On inspecting I figured out that I have to make the content of w3l_banner_nav_right
dynamic as surrounding is something which will be repeated on other pages. I cut the markup and shifted to index.blade.php
. In master.blade.php
, <div>
with the class w3l_banner_nav_right
now look like this:
<div class="w3l_banner_nav_right">
@yield('content')
</div>
@yield
is a directive of Laravel Blades,a template engine offered by Laravel. If you are coming from other MVC frameworks then this should not be alien for you. Templates make things easier to manage when their is a repetitive HTML like header, footer and sidebars etc. Template engine also helps to render the output which is being prepared at Controller level. Now before I explain @yeild
further, let's open to index.blade.php
file which after making changes will look like this:
@extends('layout.master')
@section('content')
<section class="slider">
<div class="flexslider">
<ul class="slides">
<li>
<div class="w3l_banner_nav_right_banner">
<h3>Make your <span>food</span> with Spicy.</h3>
<div class="more">
<a href="products.html" class="button--saqui button--round-l button--text-thick" data-text="Shop now">Shop now</a>
</div>
</div>
</li>
<li>
<div class="w3l_banner_nav_right_banner1">
<h3>Make your <span>food</span> with Spicy.</h3>
<div class="more">
<a href="products.html" class="button--saqui button--round-l button--text-thick" data-text="Shop now">Shop now</a>
</div>
</div>
</li>
<li>
<div class="w3l_banner_nav_right_banner2">
<h3>upto <i>50%</i> off.</h3>
<div class="more">
<a href="products.html" class="button--saqui button--round-l button--text-thick" data-text="Shop now">Shop now</a>
</div>
</div>
</li>
</ul>
</div>
</section>
@stop
On top there is a directive @extends('layout.master')
which tells that this inner page, the index.blade.php
is actually extends it's parent, the master.blade.php
which resides in layout
directory. Dot notation is being used to refer the folder itself. It is not necessary that you put in layout
folder, it's all about code management and I prefer to make things modular and manageable as much as I can.
Ok, the next line is @section('content')
, this directive tells that there is a section named content
, whatever you find in it it should be placed in the content
placeholder of master.blade.php
whih is then rendered and displayed by @yield('content')
directive. Now you learnt what @yield
does. @@stop
tells to halt here and don't include further of it. Check the docs to learn further about it.
Alright! that's it for now. This post should help you to gain some confidence to transfer and HTML layout in Laravel system and getting idea of basics of of Laravel Mix. In next post I will touch some basics of Database features offered by Laravel. Stay tuned!
The repo of this project is being maintained here.
Everything what is in node_modules can’t resolve for compiling
Module not found: Error: Can’t resolve ‘…/…/…/node_modules/flexslider/jquery.flexslider-min’ in ‘c:\xampp\PROJEKTY\golmarket\resources\js’
Module not found: Error: Can’t resolve ‘…/…/…/node_modules/jquery/dist/jquery.min’ in ‘c:\xampp\PROJEKTY\golmarket\resources\js’
Shouldn’t that flexslider be included in package.json? Sole jquery included is in package.json as well node_modules but still can’t resolve
EDIT I see that it should go 2 folder ago instead of three so …/…/ instead of …/…/…/
Now jquery is loading
Hi only index.html is converted to index.blade.php in this tutorial.
What about the other pages in the theme?
Thank you for your posting.
I am very glad to insert your detail to revise minor word.
From=>“@@stop tells to halt here and don’t include further of it. Check the docs to learn further about it.”
To=>“@stop tells to halt here and don’t include further of it. Check the docs to learn further about it.”
I wish to help everyone!