The one thing we’re not short on in the Divi interface, is places to put code. There are modules built specifically to house code, there are theme options for housing code, there are ‘Advanced’ panels everywhere for housing code that can be run theme, page or section-wide. This gives you an irregular (and welcome) amount of control of things like HTML, CSS and jQuery, or what we might refer to as client-side code languages (code that runs in the browser, or on the end user’s machine), but it doesn’t do too much for server-side code such as PHP. If we want to make PHP adjustments we are most likely going to revert to using a child theme in order to add and execute our changes.
The Problem With Child Themes
The golden rule of WordPress is ‘don’t touch core’. That is to say, none of the edits your making for an individual site should be implemented in the core files. There are so many hooks and filters and other ways to extend WordPress, that there really isn’t any requirement for you to make edits to these files anyway. The most common ways senior Developers and Designers interact with and extend WordPress, is through the creation of Themes and Plugins. As someone building sites with WordPress, you’ll likely find that you can do 90% of what you need to do, through the use of these extensions. You’ll probably even use the majority on multiple sites that serve different niches and purposes.
But each of these sites will likely need a few lines (or maybe more than a few lines) of code to finish them off. It’s likely that in this case, the code is going to be useful on the site it is written for, but probably not anywhere else exactly as is. You shouldn’t add code to premium theme and plugin files, for the same reason you shouldn’t add to core: you’ll lose all of your changes if and when the codebases are updated, which happens regularly in the WordPress ecosystem.
That’s where a child theme usually comes in; to house those lines of codes that are not shared with other sites, the code that is specific for the build at hand. I say usually, because the Divi sector is a little different.
Divi Child Themes
The Divi Theme itself, is a blank canvas, and much more akin to a framework for WordPress, than a regular theme. You couldn’t install Divi as is, add a caching plugin and declare your site ready. It needs a little more work, usually through the implementation of layouts. A large number of third-party developers and designers (including ourselves) have created layouts that are designed for specific niches. In many cases these are packaged along with code to manipulate the header and footer of a site, and sold as ‘premium child themes’. They’re more than a couple of lines of code. They behave more like a traditional WordPress theme, taking you from a blank canvas, to a point where you could feasibly swap out text and images and have a site ready to go.
If you’re using a premium child theme, then you won’t want to store personal customisations there as many have the same update functionality as a standard theme or WordPress core, meaning you could update one day and lose your changes. So if child themes aren’t a guaranteed safe place to store site-specific code, where is?
Functionality Plugins
If you’ve used WordPress a while then you’ll be more than familiar with what plugins are. They’re extensions that add a plethora features and benefits to your site. Most plugins in the WordPress repository are huge assets with thousands of lines of code, a couple of dozen files and are your first port of call for making your site fast, secure, SEO friendly or compliant. But at a much more basic level, all a plugin is, is a place to put code and have it run on your site. If you’re following along with a tutorial and it suggests adding code to the functions.php file of your child theme, in most cases you can add the same code directly to a plugin.
The main differences between standard plugins and functionality plugins are:
- Functionality Plugins are not designed to be shared or sold, they’re designed to be a place to make site-specific changes safely.
- Functionality Plugins are unlikely to require settings pages, as you’re the only one interacting with your code.
- Standard plugins are complex and likely add instances to the databases and require an install/uninstall process. Functionality plugins are not that complicated.
The best feature of a functionality plugin, at least in our user case, is that nothing is going to override it or force you to lose your changes. If it’s in a functionality plugin,
How To Build A Functionality Plugin
Fundamentally, a functionality plugin can be a simple as you need it to be. It requires only a name, to work. Create a folder called my-functionality-plugin in your plugins folder directory. Inside this folder create a file called functions.php and add the following code to the top.
<?php
/*
Plugin Name: My Functionality Plugin
*/
Believe it or not, you just created an activatable plugin. Go ahead and take a look at your list of installed plugins and you’ll see it there.
However, it’s likely that you’ll want to pass on a little more information than that into your plugin header. Here’s a more common example:
/*
Plugin Name: My Functionality Plugin
Description: Adds cool stuff to Divi & WordPress
Version: 1.0
Author: SJ James
Author URI: https://aspengrovestudios.com/
*/
You can see in this example, we’ve chosen to include a description and also make our title a little more descriptive to what we’re going to be doing. We’ve added an author and a link to the author’s website. We’ve also included a version number which will help us keep track of our changes.
We can now activate this plugin just as before and any code added to this page will be run correctly. Let’s test that…
// Let’s make sure it’s working…
function cta_testing_output(){
echo "TESTING OUTPUT";
}
add_action("wp_footer","cta_testing_output");
This function is going to output the words “TESTING OUTPUT” in the WP footer. This uses the “wp_footer” hook. There are hundreds of hooks built into WordPress, Divi and other major themes and plugins. They help you control where your code runs. In the above example we told it to run in the footer and that’s exactly what it did. Moving forward in this tutorial, we’ll use some other hook examples
Once we’ve tried and tested this code to ensure our plugin file has been correctly added, we can confidently move on with adding more useful code. For this tutorial, we’re going to add a box above all post content with a CTA included.
Adding HTML
For this we’re going to use the same approach above, a simple bit of code inside a function, that we’ll hook into our posts.
// CTA Output
function cta_post_output (){?>
<div class="ag-cta-box">
<p>Support this post and others like it. Become a paid subscriber.</p>
<a href="###" class="cta-button">Subscribe</a>
</div>
<?php
}
add_action("et_before_content","cta_post_output");
Here we have a div element with a paragraph and a link inside it. We’re using the “et_before_content” hook this time as that’s where we want out code to run. You can see an extensive list of the hooks baked into Divi in the developer’s section of the Elegant Themes website. You’ll notice that before we swap to writing HTML, we have closed off the php tags (?>) and then opened them again (<?php) before carrying on with our PHP function. This is the simplest way to add HTML to a template using a function.
Adding CSS
Add the following CSS to that file:
background: #f1f1f1;
margin-bottom: 30px;
padding: 16px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.ag-cta-box a {
background: coral;
color: #fff;
padding: 16px;
border-radius: 4px;
margin-left: 20px;
text-align: center;
min-width: 120px;
}
So now a path to that file should be:
Plugin Folder / Assets Folder / Stylesheet
And here is the function we’re adding to functions.php to run code in that file.
function cta_load_css() {
wp_enqueue_style( 'styles', plugin_dir_url( __FILE__ ) . 'assets/style.css' );
}
add_action( 'wp_enqueue_scripts', 'cta_load_css' );
Adding jQuery
wp_enqueue_script( 'script-name', plugin_dir_url( __FILE__ ) . 'assets/jquery.js' , array('jquery'));
So our function should now look like this…
function cta_load_css() {
wp_enqueue_style( 'styles', plugin_dir_url( __FILE__ ) . 'assets/style.css' );
wp_enqueue_script( 'script-name', plugin_dir_url( __FILE__ ) . 'assets/jquery.js' , array('jquery'));
}
add_action( 'wp_enqueue_scripts', 'cta_load_css' );
We’re calling a file called jquery.js from the assets folder, so we’ll have to make sure that we’ve added that file. We’re not using any jQuery for this example so you can check the file has been added correctly by adding the following:
alert("hello there…");
If you’ve done it correctly then you’ll get a browser alert window on your next refresh:
If you’re adding lots of snippets to your plugin, then that functions.php file is going to quickly become convoluted. Here’s a tip for keeping things readable.
Including Files in Your Functionality Plugin
Create a new folder called ‘snippets’ inside of your main plugin folder. Inside this folder, create a new file called ctabox.php.
Now we can remove our original ‘cta_post_output’ function from the functions.php and move it into this file instead. Creating a file for each snippet like this, is a great way to keep things organised.
In order for that to work though, we need to ‘include’ that file in our functions.php. This only requires one line.
This way, you can include as many files as you need to without things getting messy.
And that’s it! You now have a great way to store your own code without touching theme, or child theme files.
Download A Working Functionality Plugin Example!
If you’d like to get a jump start on your functionality plugin development, then download this tutorial’s working example using the opt-in below!
Thanks for this tutorial, as it is always cool to learn new ways to do things.
Thanks SJ, this is excellent!
Wonder how (if possible) I can get the css to load after the DIVI main css files..?
Great tutorial SJ, was so easy to follow and so useful.
Do you think a plugin that added CSS would fall into this category? In other words, it would be a simple plugin that added styling for let’s say contact forms and the user could enter the class in the module that fits their taste like .style-1.
SJ, I don’t have enough words to thank you! This post is so rich and inspiring! Thank you so much for opening people’s mind to the next level!