Today we will learn where and how to add code outside the templates in our theme. We do this by adding the theme’s functions.php
file. Along the way we’ll also learn how to add your stylesheets and scripts the proper way.
A theme’s functions.php file
A theme needs somewhere to place code that is not part of the templates. There’s always a bunch of code all themes need to add in order to handle functionality. For example enabling WordPress’ featured images feature (did you notice that it was missing?), support for menus, widgets, adding stylesheets and scripts (the proper way), and more.
That file is functions.php
. WordPress automatically and always loads this file if it exists in your theme. It’s always loaded both in admin and in frontend.
Adding a functions.php file to our theme
Let’s create a new, empty file in our root theme folder and name it functions.php
.
In that file, immidiately start with an opening PHP tag (<?php
) and don’t include the closing tag. The functions.php
file is meant for PHP code, not HTML. Your theme can break (or even just act weird) if you have characters or newlines outside PHP tags in this file. You can obviously break out of PHP tags to output HTML, but it must be done inside functions or hooks. Let me explain this with an experiment.
Let’s test this file out to see how it works. Inside functions.php
write an echo of some dummy text:
functions.php
<?php echo 'This is an experiment';
Refresh your frontend. The dummy text appears. But if you inspect or view the HTML source, you will see that the text appears before opening <html>
. This makes for completely invalid HTML!
Go to your admin panel and hit refresh. It does the same thing there as well (it might be hidden behind admin bar, but it’s there in the HTML).
As you can see, any code in your functions.php
loads before anything else in our templates. Therefore, as a rule, any output (HTML outside PHP tags or echo
) must be inside functions that will be run at the right times, normally hooked to actions or filters.
Recall from when we learned about and added hooks in part 3 of the WordPress theme tutorial for beginners. The way we run code on a hook is to attach a function to the hook with add_action()
. Let’s test something else out; let’s make a function hooked to a hook we already have defined in our templates; wp_footer
.
In functions.php
remove the echo
we added for test purposes and instead write:
functions.php
<?php add_action('wp_footer', 'wptutorial_print_footer'); function wptutorial_print_footer() { echo 'This sentence will appear in footer!'; }
Hit refresh in frontend and see that the string appears nicely at the exact place you have defined wp_footer
, right before closing </body>
. Also, notice that this will not echo anything out in admin. This is because wp_footer
is a hook that is only run in frontend.
Let’s do our first proper operations in functions.php
!
The right way to add styles and scripts vs the wrong way
Some of you might remember from part 3 where we added the wp_head
hook in our header.php
. After we did this WordPress was able to load its styles and scripts, including the admin bar. You might be thinking that in order to add our stylesheets we need to make a function hooked onto wp_head
and output the <link>
for the stylesheet… Usually you would be right!
However in WordPress there is a special way to go about adding scripts and styles. This is mainly to manage the load order and to avoid loading duplicate libraries. For example you as a theme author might want to add Javascripts that are dependent on the jQuery
library. Then you need to make sure jQuery
gets loaded before your files. But WordPress and any plugins have the same need, to make sure jQuery
is loaded before their scripts as well. You can’t load the jQuery
library multiple times because that causes problems. So WordPress has a way to manage in which order scripts and stylesheets are loaded.
Adding stylesheets (the right way)
For adding any styles and any javascripts, we use a hook called wp_enqueue_scripts
. Yes, you use this hook for styles as well, despite its name. Adding scripts and styles are referred to as “enqueuing” – as in put in a queue. Let’s enqueue (add) our stylesheet by using the function wp_enqueue_style in our functions.php
:
functions.php
<?php add_action('wp_enqueue_scripts', 'wptutorial_enqueue_scripts'); function wptutorial_enqueue_scripts() { wp_enqueue_style('theme-main-style', get_stylesheet_directory_uri().'/style.css'); }
The wp_enqueue_style
function takes as minimum two parameters. The first is an unique name (handle or “slug ID”), and second the location of the file. The handle needs to be unique as this is the identifier WordPress uses to determine if there are any duplicates.
As for returning the path to your theme, there are plenty of functions available. Above I used get_stylesheet_directory_uri()
which returns the URL to your theme folder, and then I appended the rest of the path to our stylesheet.
PS: WordPress offers a separate function for returning the full URL to your theme’s style.css
: get_stylesheet_uri()
. I used the other function above as it’s more useful to get familiar with. You will use it for any other files you need to enqueue.
The function wp_enqueue_style
accepts more useful parameters, such as dependencies (which other css files must be loaded before), and version number (useful for caching purposes).
Refresh your frontend and see that your stylesheet is loaded in <head>
tag!
If you are one of those who are itching to make your theme look prettier while coding it, here’s your chance. I encourage you to start defining your HTML, classes and wrappers and add some styling in your style.css
. We will add more content that will require styling as we go along in this tutorial series.
Adding scripts (the right way)
Let’s look into how we add javascripts to our theme. It is done using the same hook (so you can put it all inside one function). But for scripts we use a slightly different function.
To enqueue a script, you use wp_enqueue_script()
. The parameters are the same as wp_enqueue_style()
. The first is the unique handle and the second is the path to the script. Third (optional) is the array of dependencies. As fourth (optional) parameter you set the version number. And finally fifth (optional) you define whether or not the script should be loaded in the <head>
tag or at the end of </body>
.
If you add one of WordPress’ included scripts as a dependency, you don’t need to enqueue that script! Let’s do this in practice.
Create a folder assets
and inside it a subfolder js
in our theme folder, and then add a new empty main.js
file. Let’s say this script requires the jQuery
library, so we set it as dependency. We know that WordPress comes with jQuery
bundles and the handle for it is jquery
. We’ll enqueue our script like this:
functions.php
<?php
add_action('wp_enqueue_scripts', 'wptutorial_enqueue_scripts');
function wptutorial_enqueue_scripts() {
wp_enqueue_style('theme-main-style', get_stylesheet_directory_uri().'/style.css');
wp_enqueue_script('theme-main-script', get_stylesheet_directory_uri().'/assets/js/main.js', ['jquery']);
}
If you refresh frontend, and check your source code, you should see that your script, main.js
, is added, but also that jQuery
library is loaded. And jQuery
is loaded before your file!
You have now learned how to add styles and scripts. For adding more files, add a wp_enqueue_style()
or wp_enqueue_script()
for each new file.