This is Part 2 of the 9 part Course about developing a WordPress theme from scratch.
Here is the access to the other parts of the Course in the sequential order:
In this part, We will learn how to load scripts and styles to our WordPress site.
Now before we add our scripts and styles to the <head>
element, let’s clean up the functions.php
file by removing everything that we added in the last part.
I made you add them just for the sake of demonstrating action hooks. Real code that goes inside the functions.php
file starts from this module.
This is my current functions.php
file after removing everything from it except the opening PHP tag.
Yeah! Right now, the file only contains an opening PHP tag.
After the favicon, the next big thing that we have to deal with is our website stylesheets and scripts. These are generally divided into two categories.
style.css
file and our main Javascript code inside the main.js
fileFor the purposes of this project, We will be using quite a lot of third-party stylesheets and scripts.
And to house these scripts and stylesheets, let’s create a new directory inside our nd-dosth
theme and let’s name it assets
.
In other words, its a directory for housing publicly accessible assets like scripts, stylesheets, images and custom fonts like FontAwesome.
So, let’s create four more directories under assets
. And let’s call them:
Here is how assets
directory looks inside Visual Studio Code Editor:
Now that the directory structure in place, let’s go ahead and download the initial stylesheets and scripts we need to proceed forward with this project
1) style.css
We already created this file at the initial stages of our theme development.
2) jquery.js
file
WordPress ships with the latest version of jQuery plugin by default. You don’t have to worry about downloading and including this file manually.
2) main.js
file for housing all our custom javascript code.
Let’s create this file and put it inside assets/js
directory. Also, it is not mandatory to name this file main.js
.You can name it whatever you want, for example, custom.js
3) normalize.css
stylesheet file.
Go ahead and download the latest normalize.css
file from the Necolas’s Github website:
https://necolas.github.io/normalize.css/
And, let’s put it inside assets/css
directory.
4) bootstrap
stylesheet and script file.
Visit https://getbootstrap.com/ and download the latest bootstrap
zip file. Extract it so that you can copy the necessary files to our theme.
copy the bootstrap.min.css
file to the assets/css
directory.
Also, copy the bootstrap.min.js
file to the assets/js
directory.
And here is the updated version of the assets
directory inside visual code editor.
Alright, now that we have our initial scripts and stylesheets in place, it is time to use them.
When it comes to WordPress, although there are a number of ways for linking our scripts and stylesheets to a webpage, WordPress strongly recommends using its enqueue system to manage our scripts and stylesheets.
Simply put, WordPress Enqueue System will help us manage the loading of our scripts and stylesheets, to just about any webpage on our site, only from the functions.php
file, with ease.
You never have to write or copy-paste the <link>
tags or the <script>
tags on every HTML file like we normally do in our HTML/CSS projects. WordPress Enqueue system generates them on every page of your site by taking some basic instructions from you.
Now, the word “Enqueue” is not specific to WordPress. It is just another word in the English Dictionary.
Here is what Google says about the word:
Google says “Add an item to a queue of such items”.
Google hits the bulls-eye with that definition of enqueueing. When we translate that definition to the world of WordPress, enqueuing just means management of our stylesheets and scripts, both on frontend and admin side of a WordPress website.
To be precise, management of our stylesheets and scripts involves:
1) Queueing them one after another so that we can manage their dependencies and generate the markup for them
We need enqueuing because the order in which stylesheets and scripts appear has a huge impact on the functioning of a webpage.
From the perspective of a stylesheet, In our custom stylesheet, it is a common practice to override some styles of third-party CSS stylesheets like Bootstrap. So we must place the Bootstrap CSS stylesheet first in the queue.
And, From the perspective of a script, In our custom script, it is a common practice to initialize some third-party Javascript libraries like Bootstrap, Superfish, Isotope. So we must place all these script files one after another in the queue and we must place our custom script last in the queue so that we can initialize all those third-party libraries.
If you are good with CSS and Javascript you what I mean. If you don’t, worry not, you can grasp it as we progress through this WordPress Theme Development course.
2) Deciding whether to enqueue an individual script or stylesheet on a particular webpage on our website.
We need this because not every webpage needs every script or stylesheet to render or function properly.
So, with the help of the WordPress enqueue system, we can conditionally enqueue a script or stylesheet on a particular page.
For example, Let’s just say our client wants a Masonry layout only for his Website’s Homepage and not for any other page on his site. WordPress Enqueue System counters this problem with ease. You’ll see the “how” in the next section.
When it comes to the frontend, WordPress Enqueue system internally depends on the wp_head and wp_footer
action hooks.
Also, WordPress uses the enqueue system internally. So does every well-written plugin. And, for the following reasons, we ( the theme developers ) have to use it too.
functions.php
file without having to modify multiple files.So, How do we make use of WordPress Enqueue System?
WordPress allows us to make use of the Enqueue system by providing us with two action hooks and two handy functions for generating the proper <script>
and <link>
tags.
1) wp_enqueue_scripts
action hook allows us to enqueue both stylesheets and scripts to a front end webpage of our WordPress website. For example, Homepage, Features page, Blog Archive, Blog Post, etc.
2) admin_enqueue_scripts
action hook allows us to enqueue both stylesheets and scripts to a backend webpage. For example, our Admin Dashboard, Page’s Panel, Theme’s Panel, etc.
3) wp_enqueue_style()
function to register and enqueue our stylesheets. This function also generates a proper stylesheet <link>
tag, for example:
<link rel="stylesheet" id="normalize-css" href="http://localhost:8888/dosth/wp-content/themes/nd-dosth/assets/css/normalize.css?ver=4.9.9" type="text/css" media="all">
4) wp_enqueue_script()
function to register and enqueue our scripts. This function also generates a proper <script>
tag, for example:
<script type="text/javascript" src="http://localhost:8888/dosth/wp-content/themes/nd-dosth/assets/js/main.js?ver=1.0.0"></script>
Now, don’t get confused. wp_enqueue_scripts
action hook just allows us to enqueue scripts and stylesheets. Actual enqueueing is done by the wp_enqueue_style()
and wp_enqueue_script()f
unctions.
And for the purposes of this WordPress Theme Development guide, we will be just focusing on the wp_enqueue_scripts
action hook for enqueuing stylesheets to a frontend web page.
You are not going to see any usage of admin_enqueue_scripts
action hook in this WordPress Theme Development guide.
We usually use admin_enqueue_scripts
action hook if our client demands customizations to the Admin side of WordPress.
Also, the plugin developers use this action hook quite extensively.
Anyway, if you can master the concept of action hooks correctly, you should be able to use admin_enqueue_scripts
action hook quite easily by yourself.
With that being said, let’s learn how to use wp_enqueue_scripts
action hook.
wp_enqueue_scripts
action hook allows you to enqueuing stylesheets and scripts on the frontendIt is just another action hook that allows you to echo some data or HTML markup to a front end webpage. That’s all.
And Just like any other action hook, It has a single and straightforward purpose.
When WordPress is building the final webpage, it fires this action hook to allow us to enqueue our own theme related scripts and stylesheets to the frontend webpage, more precisely to the <head>
element.
Let’s try it out. Go ahead and put the following code inside the functions.php
file.
function nd_dosth_enqueue_styles() {
echo '<link rel="stylesheet" href="http://localhost:8888/dosth/wp-content/themes/nd-dosth/assets/css/normalize.css" type="text/css" media="all">';
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_styles' );
Let’s break it down.
Nothing special going on in here.
We defined a custom action called nd_dosth_enqueue_styles
and hooked it to the wp_enqueue_scripts
action hook. And inside our custom action, we are just echoing out the hard-coded stylesheet <link>
tag. That’s all.
“Hey! You said WordPress will generate that <link>
tag for us? Right?”
Don’t worry! We will replace the hard-coded stylesheet <link>
tag with the wp_enqueue_style()
function in a moment.
For the time being, if we switch back to the Homepage in the Browser, refresh it and view its page source, we can indeed find our stylesheet <link>
tag inside the <head>
element.
See that?
But, how does the wp_enqueue_scripts
action hook work? How does it magically echoes our stylesheet exactly to the <head> element of our Homepage and not anywhere else on a Homepage, for example, the footer portion?
As usual, everything happens for a reason in WordPress, there is no magic!
The wp_enqueue_scripts
action hook relies on the wp_head
action hook. To be precise, wp_head
action hook triggers the wp_enqueue_scripts
action hook.
As I previously mentioned, WordPress internally attaches it’s own core actions to the 'wp_head'
action hook. And one of those core actions is wp_enqueue_scripts
. You can see this if you take a peek into the default-filters.php
file from the WordPress core.
You also know that an action is nothing but a custom PHP function with a single purpose. So, the purpose of the wp_enqueue_scripts
action is to trigger wp_enqueue_scripts
action hook. Just like wp_head()
function triggers the wp_head
action hook. Here is source of wp_enqueue_scripts
action.
Now don’t worry if you did not understand it.
For now, all you have to remember is, If you remove the wp_head()
function from the header.php
file, wp_enqueue_scripts
action hook is not gonna work at all. And, if this action hook doesn’t work, you can not enqueue your stylesheets or scripts dynamically.
At the end of the day, it all tracks back to wp_head()
function in the header.php
file 😛
Anyway, that is all you need to know about wp_enqueue_scripts
action hook. Now let’s replace the stylesheet <link>
tag with wp_enqueue_style()
function.
Once again, The primary purpose ofwp_enqueue_style()
function is to register and enqueue a stylesheet to the <head>
element of a webpage. This function also generates a proper stylesheet <link>
tag.
wp_enqueue_style()
function also relies internally on the wp_head
action hook.
And, It accepts five parameters to give us some fine grain control over the management of the stylesheet.
wp_enqueue_style( $handle, $source, $dependencies, $version, $media );
let’s start with the $handle
and $source p
arameters.
$handle
parameterWith this parameter, you are giving a handle to your stylesheet in a string format, for example:
wp_enqueue_style( 'normalize', $source, $dependencies, $version, $media );
You can use any text which is a valid PHP string. For example, ‘main-style','foundation_grid_11'
are totally valid strings in PHP.
But, we usually name handles in such a way that they convey what a stylesheet is doing. We do this because it makes the life easy for the future developer or maintainer of this project.
Also, Plugin developers use this $handle
parameter quite extensively to conditionally enqueue or de-register stylesheets.
For example, you can conditionally de-register a stylesheet using its handle, for example:
if( is_page( 74 ) ){
wp_deregister_style( $handle );
}
In the above example, we are de-registering a stylesheet only on a page whose id is 74 using the another predefined conditional function called is_page()
. In terms of WordPress Terminology, is_page()
is a conditional tag.
Don’t worry, It is just a fancy name. Anyway, WordPress provides us with a tons of conditional tags and we will learn how to use conditonal tags as we progress through the course.
Back to the topic at hand, From a theme developer’s standpoint, the $handle
parameter is used extensively to specify the dependencies of a particular stylesheet and we will practice this in a moment.
I once had to totally remove the Woocommerce plugin’s stylesheet for an advanced Woocommerce theme and the $handle
parameter of the stylesheet is the real saver of the day.
Simply put, it is rare, but this example tells the exact purpose of the $handle
parameter.
$source
parameterFor the $source
parameter, you need to provide a fully qualified URL of the stylesheet, for example:
wp_enqueue_style(
'normalize',
'http://domain-name.com/wp-content/themes/your-theme/path-to-css-file/normalize.css',
$dependencies,
$version,
$media
);
Now, if you consider yourself as a responsible and standards following theme developer:
You shouldn’t hard-code the URL of the stylesheet like this:
http://domain-name.com/wp-content/themes/your-theme/path-to-css-file/normalize.css
or a relative path like this:
/wp-content/themes/your-theme/path-to-css-file/normalize.css
Both of these does work but increases the maintenance overhead in the long run. So, a big no-no.
To make our lives easier as a developer, WordPress provides a handy function which helps you build the fully qualified URL for just about any publicly accessible asset like image, stylesheets, fonts, javascript plugins etc.
And, the function is:
get_stylesheet_directory_uri()
As the function name suggests, it just returns a fully qualified URL of the active theme directory, in our case, it is:
http://localhost:8888/dosth/wp-content/themes/nd-dosth
Notice that there is no forward-slash ( / ) at the end of the URL. You have to take care of it when you build the rest of the path to the file.
“So, what how we build the rest of the path to the file?”
Simple, we have to use the PHP concatenation technique to build the rest of the path ourselves, for example:
<?php get_stylesheet_directory_uri() . '/assets/css/normalize.css'; ?>
Notice, we are building the rest of the path starting with a forward slash at the beginning.
This tells us a really important thing. We can still use all the core PHP techniques and functions along with WordPress only functions.
WordPress is nothing but a big PHP project. You can still do everything that you usually do inside your custom PHP projects.
so, the WordPress translates the above code to:
http://localhost:8888/dosth/wp-content/themes/nd-dosth/assets/css/normalize.css/
Really Sorry, I can’t stress this enough, please pay attention to the forward-slash ( / ) at the beginning of the blue colored box in the above image.
This is a very common problem when we are getting started as a WordPress developer.
If you notice the yellow boxes in the above image, The get_stylesheet_directory_uri()
function only returns the fully qualified of the active theme directory without the trailing forward-slash.
So, it is our responsibility to put the forward-slash at the beginning of the rest of the URL we are concatenating.
If you can’t keep up with the forward-slashes every time you use the get_stylesheet_directory_uri()
function, that is totally ok.
WordPress provides us with another handy function to handle the forward-slashes for us and the function is
trailingslashit()
It is pronounced as, trailing-slash-it.
To use this function, All you have to do is provide a URL and it gives you back the same URL by attaching a forward-slash to the end of it.
And this is how we use it in the real-world WordPress projects.
<?php trailingslashit(get_stylesheet_directory_uri()) . 'assets/css/normalize.css'; ?>
Get it?
I know I left out the explanation for the remaining three parameters and I did it on a purpose. They are better understood when you try them practically.
Anyway, enough theory, let’s start with enqueuing the normalize
stylesheet.
Open up the functions.php
file inside our theme and replace the hard-coded echo with the following code in it to enqueue the normalize.css
file
wp_enqueue_style(
'normalize',
get_stylesheet_directory_uri() . '/assets/css/normalize.css',
array(),
false,
'all'
);
Here is my full functions.php
file after placing the above code:
And let’s break it down.
If you look at the above wp_enqueue_style()
function call, we already know what is going on with the first two parameters. So, let’s take a look at the remaining parameters.
The third parameter is all about dependencies. We need normalize.css
file to be loaded before any other stylesheet. It doesn’t really depend on any other stylesheet. So, we should leave out $dependencies
parameter as an empty array. Now, I know this is a vague explanation, but bear with me, You’ll know the purpose of the $dependencies
parameter when we enqueue our main style.css
file.
The Fourth parameter is all about the version number of the stylesheet. If you specify, the version number will be added to the end of the final stylesheet URL as a query string for cache busting. A version number as a query string is particularly useful if you are planning to make a lot of changes to the stylesheet once the website goes live and the caching is enabled.
In a real-world scenario, a URL with a version number looks like this:
http://localhost:8888/dosth/wp-content/themes/nd-dosth/assets/css/normalize.css?ver=1.0
When it comes to the normalize.css
file, this is a third-party library and I have no intentions of adding/modifying the styles inside it. So I specified false
for this parameter.
And when you specify false
for this parameter, WordPress will still generate a version number at the end of the URL and it uses the current WordPress Software Version number. At the time of writing this lesson, it’s 4.9.9
Finally, the fifth parameter tells the browser what media ( or device ) the stylesheet is optimized for. I always choose to support all the media types including the print media. Hence, I choose all for this parameter.
Anyway,It is time to test this.
If we go back to the homepage in the browser and refresh it, the normalize.css
file is indeed getting injected to the <head>
element of our homepage.
Fun fact: You are allowed to use wp_enqueue_style()
function only inside the wp_enqueue_scripts,
admin_enqueue_scripts,
and login_enqueue_scripts
action hooks. If you try to use it outside this action hook, WordPress will throw the following error.
To enqueue the Bootstrap stylesheet, you have to use the same technique. Place the following Bootstrap enqueue code right after the Normalize enqueue function.
Here is my current functions.php
file with Bootstrap enqueue code:
function nd_dosth_enqueue_styles() {
wp_enqueue_style(
'normalize',
get_stylesheet_directory_uri() . '/assets/css/normalize.css',
array(),
false,
'all'
);
wp_enqueue_style(
'bootstrap',
get_stylesheet_directory_uri() . '/assets/css/bootstrap.min.css',
array(),
false,
'all'
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_styles' );
If you notice, except for the $source URL and the handle parameters, every other parameter is similar to the enqueue function of normalize
stylesheet.
This is because, just like the normalize
stylesheet, the bootstrap
stylesheet doesn’t depend on any other stylesheet and we are not going to edit the core styles inside the bootstrap.min.css
file.
But those parameters do change when we enqueue our main stylesheet.
To enqueue our main stylesheet, put the following code after the bootstrap
enqueue function.
wp_enqueue_style(
'main-stylesheet',
get_stylesheet_uri(),
array('normalize','bootstrap'),
'1.0",
'all'
);
Ah! We are finally using the full capabilities of the wp_enqueue_style()
function. So, why late? let’s break it down.
As usual, the first parameter is the handle name.
And when it comes to the second parameter, we are using a different function to build the URL of the style.css
file. And if you notice, we are not concatenating anything to the end of it.
get_stylesheet_uri()
Simply put, this function returns the fully qualified URL of the style.css
file.
“Wait! But why this special function just for the style.css
file?”
As you already know, WordPress expects a style.css
file inside every active theme. And it also forces us to put this file at the root level of our theme directory.
So, WordPress knows where this file exists and hence provides the handy get_stylesheet_uri()
function which returns the URL of the file.
This is why I love WordPress!
Anyway, for the third parameter, instead of an empty array, this time we are providing two dependencies by specifying the handle names of already registered stylesheets.
array('normalize','bootstrap')
Does the above handles in the array ring any bell?
“Yep! Those are the handles of Normalize and Bootstrap stylesheets that we enqueued”
Correct! You are smart. So, technically, this is our way telling WordPress “Hey! Only load the style.css
file after loading the normalize.css
and bootstrap.min.css
file”.
“Wait! Why and how our style.css
file is dependent on Bootstrap and Normalize stylesheets?”
Simple, as a CSS developer we might have to overwrite some of the Bootstrap framework’s style rules for better control over the layout of the website. And the best way to do it is overwriting them using the style.css
file.
This way, we don’t have to edit the Bootstrap’s core stylesheet.
If we edit the Bootstrap stylesheet directly, it’s going to bite us back when we have to migrate to a newly released version Bootstrap’s stylesheet. From the maintenance perspective, it is all about how much time you save in long run.
Now, I am not saying that you must add the Bootstrap stylesheet as a dependency. It varies from project to project.
I usually overwrite some of the layout rules of Bootstrap to code a Full-Width website.
And we’ll be coding a full-width page at a later point the course. So, for the purposes of this project, I mentioned it as a dependency for the main stylesheet.
Also, for the fourth parameter, we provided a version number of “1.0”.
Once we launch the website to a live/production server, we will be updating this version number every time we make edits to the style.css
file.
And we do this to bust the cache in the browser. Specifying a different version number for any script or stylesheet will force the browser to re-download the file from the server.
No client never ever said “Hey! Thanks for launching our website. We are done with you.”
Even after the site launch, the client will keep coming back with new changes to website styles. So always use a version number when enqueuing a stylesheet which might get some changes.
Finally, for the fifth parameter, we are using the value “all” once again to tell the browser “Hey! You can use this stylesheet for that media/devices”.
Here is the current functions.php
file.
<?php
function nd_dosth_enqueue_styles() {
wp_enqueue_style(
'normalize',
get_stylesheet_directory_uri() . '/assets/css/normalize.css',
array(),
false,
'all'
);
wp_enqueue_style(
'bootstrap',
get_stylesheet_directory_uri() . '/assets/css/bootstrap.min.css',
array(),
false,
'all'
);
wp_enqueue_style(
'main-stylesheet',
get_stylesheet_uri(),
array('normalize', 'bootstrap'),
"1.0",
'all'
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_styles' );
And if you take a look at the page source of the Homepage, You can see all the stylesheets getting loaded one after the another:
That’s it, we are done with enqueuing our initial stylesheets. As we progress towards the completion of the Dosth project, we will keep coming back to the functions.php
file and the nd_dosth_enqueue_styles()
action function to enqueue more stylesheets as per the requirements of the project.
Now, let’s go ahead and enqueue our initial scripts.
The primary purpose ofwp_enqueue_script()
function is to register and enqueue a script to both <head>
element and the footer portion of a webpage. This function also generates a proper <script>
tag.
wp_enqueue_script( $handle, $source, $dependencies, $version, $in_footer );
First of all, enqueuing a script is totally similar to enqueuing a stylesheet with only one major difference. I highlighted this difference by making it bold in the above line of code.
Thisfunction also accepts five parameters. The first four parameters are exactly same when compared to wp_enqueue_style()
function.
But, If you notice the last parameter, this function ships with an $in_footer
parameter instead of the $media
parameter.
If you are good with HTML, you know that script tag doesn’t support the media
attribute. The media
attribute only applies to the stylesheets.
And, Javascript is render blocking.
That means if we put a crappy script inside the <head>
element and if it is taking too long to get executed, Browser waits until the crappy script is executed to paint our webpage on the computer screen.
So, for a webpage to be performant, and if you want your website visitor to see the webpage as soon as possible, most of the scripts must go just before the closing </body>
tag instead of the <head>
element. That means, in the footer portion of a web page.
And the $in_footer
parameter help us achieve just that.
The $in_footer
parameter controls where on a webpage you can place your script tag. WordPress allows you to place a script either inside the <head>
element or just before the closing </body>
tag.
The $in_footer
parameter can be set to true
or false
. If you specify true
, WordPress places the script tag in the footer and if you specify false
, WordPress places the script tag inside the <head>
element.
You already know that the wp_enqueue_style()
function relies on internally relies on the wp_head
action hook.
But, When it comes to wp_enqueue_script()
function, It relies on both the wp_head
and wp_footer
action hooks.
The wp_enqueue_script()
function relies on wp_footer
action hook to enqueue scripts to the footer portion of a webpage.
Enough said! Let’s start the enqueuing of our scripts.
I have a small exercise for you. You know that enqueuing a script is similar to that of enqueuing a stylesheet.
We also created h main.js
file in the middle of this lesson. So, go ahead and enqueue the main.js
file using the following four pieces of the puzzle:
wp_enqueue_script()
functionwp_enqueue_scripts
action hooknd_dosth_enqueue_scripts()
actionmain.js
file to the footer of a webpage using the $in_footer
parameterDid you?
Please take your time to finish this exercise and only proceed forward after you are done with it.
“Yep! I am done with the exercise. Between why do we need a new action like nd_dosth_enqueue_scripts()
? Can’t we just enqueue the script using the same nd_dosth_enqueue_styles()
action?”
Do you mean like this:
<?php
function nd_dosth_enqueue_styles() {
wp_enqueue_style(
'normalize',
get_stylesheet_directory_uri() . '/assets/css/normalize.css',
array(),
false,
'all'
);
wp_enqueue_style(
'bootstrap',
get_stylesheet_directory_uri() . '/assets/css/bootstrap.min.css',
array(),
false,
'all'
);
wp_enqueue_style(
'main-stylesheet',
get_stylesheet_uri(),
array('normalize', 'bootstrap'),
"1.0",
'all'
);
wp_enqueue_script(
'main-js',
get_stylesheet_directory_uri() . '/assets/js/main.js',
array(),
'1.0.0',
true // load this script in the footer
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_styles' );
“Exactly, Yes. And I guess it also works, right?”
Well, it is totally fine if you do that and yes, it works. But, I give more importance to code organization and code readability.
You should too. Especially, if we are building a Big WordPress project. Once we come out of the project, we never know who will work on top of our code next.
And, from the previous lesson, we also learned that we can attach any number of actions to the same action hook.
WordPress is built with code modularity and readability in mind and this is one of the primary reasons why WordPress allows us to hook different actions to a single action hook. Also, scripts and stylesheets are two different things.
The whole purpose of this exercise is to introduce you to the world of code modularity and readability.
Anyway, here is my current verison of functions.php
file with the main.js
file enqueue code .
<?php
function nd_dosth_enqueue_styles() {
wp_enqueue_style(
'normalize',
get_stylesheet_directory_uri() . '/assets/css/normalize.css',
array(),
false,
'all'
);
wp_enqueue_style(
'bootstrap',
get_stylesheet_directory_uri() . '/assets/css/bootstrap.min.css',
array(),
false,
'all'
);
wp_enqueue_style(
'main-stylesheet',
get_stylesheet_uri(),
array('normalize', 'bootstrap'),
"1.0",
'all'
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_styles' );
function nd_dosth_enqueue_scripts() {
wp_enqueue_script(
'main-js',
get_stylesheet_directory_uri() . '/assets/js/main.js',
array(),
'1.0.0',
true
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_scripts' );
You know what’s happening with every parameter. If the above code works, we will see a script tag with a link to the main.js
file.
And since we specified true
for the fifth parameter, WordPress should enqueue this script in the footer portion of the webpage and just before the closing </body>
tag.
Also, we are not enqueuing the bootstrap.min.js
file because I am not sure if I am going to use it for this project. But I just wanted to keep it ready for a future.
So, let’s test this code by visiting the Homepage in the browser and viewing its page source.
Oh! Something went wrong again. I can not see the main.js
script tag in the footer portion of the webpage.
“Oh common! What is it now?”
Well, Sorry!
This is happening because we did not tell WordPress where to locate the footer portion of a webpage.
If you remember, in the last lesson we had the same problem while enqueuing the stylesheets.
And, we countered the problem by telling WordPress where the header portion of a webpage is located and we did so by placing the wp_head()
function right above the closing </head>
tag inside header.php
file.
Similarly, We should also tell WordPress where is footer portion of the webpage is located.
So, to fix this problem, all we have to do is put wp_footer()
function inside the footer.php
file. So, let’s go ahead and do just that.
Open up the footer.php
file and put the following code in it.
<?php wp_footer(); ?>
“Thats it?”
Yep, That’s it.
Just like wp_head()
function fires wp_head
action hook, wp_footer()
function fires wp_footer
action hook.
And, wp_enqueue_script
function depends on both those action hooks to properly enqueue scripts to the header and footer portion of the webpage.
Get It?
This is our way of telling WordPress “Yo! WordPress! This right here is the footer portion of a Webpage. Feel free to enqueue scripts here”
Anyway, If we go back to the browser and refresh the Homepage’s source again, this time we will see the main.js
script enqueued properly to the footer portion.
And Oh! We almost forgot, let’s enqueue the jQuery library.
Our theme depends on jQuery. And as I mentioned previously, WordPress ships with latest version jQuery library.
WordPress enqueues the jQuery script automatically to a frontend webpage if some other script depends on it.
For example, if we specify jQuery script as a dependency to our main.js
script, WordPress automatically generates the jQuery script tag just before the main.js
script tag.
“Hey! I don’t know the handle of jQuery script, How do I find it?”
Good Question! Its jquery
And you can find the handle of jQuery in the following page of WordPress Codex:
https://developer.wordpress.org/reference/functions/wp_enqueue_script/
As you can see, WordPress also ships with a ton of other scripts. And you can enqueue all of these scripts by using their handles.
Anyway, now that you know the handle for jQuery, go ahead and specify it in the main-js
enqueue call like this:
function nd_dosth_enqueue_scripts() {
wp_enqueue_script(
'main-js',
get_stylesheet_directory_uri() . '/assets/js/main.js',
array('jquery'),
'1.0.0',
true
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_scripts' );
If we view the page source of our Homepage in the browser, WordPress is loading the jQuery library inside the <head>
element.
Surprised? WordPress and so many other expert frontend developers agree that jQuery must go inside the <head>
element rather than the footer portion.
So, WordPress enqueues the jQuery script to the <head>
element.
“Hey! What if I want in the footer?”
Simple, download the jQuery script from the jQuery website and enqueue it just like any other script.
In fact, some clients demand to load jQuery in the footer and from a CDN. In this case, we can enqueue jQuery like this:
wp_deregister_script('jquery');
function nd_dosth_enqueue_scripts() {
wp_enqueue_script(
'jquery',
'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js',
array(), // no dependencies
null, // you don't need to specify version number
true, // load jquery in the footer
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_scripts' );
To avoid any accidental enqueuing of WordPress based jQuery, we must first deregister it. Then we can enqueue our CDN based jQuery just like any other script.
Important Note: The above technique only applies to all the scripts that WordPress ships with.
“I got one more question!”
Shoot!
“I just noticed that WordPress also ships with ImagesLoaded javascript plugin. I use it quite extensively. And none of my other scripts depend on it. How do I enqueue this?”
Simple, you have to use wp_enqueue_script()
function along with the handle of the script, like this:
wp_enqueue_script('imagesloaded');
“That’s all? What about the remaining four parameters?”
WordPress will take care of the remaining parameters. You don’t have to worry about them.
And if you try this out, WordPress enqueues this script inside the footer.
See? WordPress knows where to enqueue. WordPress always takes good decisions for us.
Anyway, I don’t usually use ImagesLoaded javascript plugin, so I am not going to enqueue it. If you want to do it, feel free to.
This is my final functions.php
file for this lesson:
<?php
function nd_dosth_enqueue_styles() {
wp_enqueue_style(
'normalize',
get_stylesheet_directory_uri() . '/assets/css/normalize.css',
array(),
false,
'all'
);
wp_enqueue_style(
'bootstrap',
get_stylesheet_directory_uri() . '/assets/css/bootstrap.min.css',
array(),
false,
'all'
);
wp_enqueue_style(
'main-stylesheet',
get_stylesheet_uri(),
array('normalize', 'bootstrap'),
"1.0",
'all'
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_styles' );
function nd_dosth_enqueue_scripts() {
wp_enqueue_script(
'main-js',
get_stylesheet_directory_uri() . '/assets/js/main.js',
array('jquery'),
'1.0.0',
true
);
}
add_action( 'wp_enqueue_scripts', 'nd_dosth_enqueue_scripts' );
Uff… this marks the end of this lesson. You did a great job.
And trust me, If you are done up to this point in the course, You have learned 50% of the WordPress Theme Development already.
Anyway, now that we are done with the initial stylesheets and scripts that our project depends on, in the next lesson, we will deal with the rest of the header starting with the <title>
tag.
Sir, you are very great person. I have seen many youtube vidios about theme development, but some doubts remain unchanged. After reading the your article my all doubts have gone, Because you teach us with very very good method. You have covered all points of enqueue funcitons such as why and when version should use and what is dependency etc. Thank you sir. I will read your all article now one by one.
Hi.
Many thanks for this brilliant tutorial. I got it now even though I am writing a plugin using admin and front end area. But I was wondering why using this all enqueue-stuff at all. But with this tutorial I really got it now and it does really make sense to use it.
So keep going on writing such brilliant tutorials by explaining also the common errors and mistakes and best practises.
BR from Germany
Thanks for the kind words, Ronny. I am glad it was helpful.