Fontastic!

Namaste!

Web development is a moving target. I think it is important to try and imagine what might be a problem in the future and then solve it. One possible scenario that I came up with involves fonts. Google has a ton of great fonts and Divi has included most of the popular ones. But, what if your design calls for a specific pairing of fonts that aren’t on the list? (I mean, come on, Comic Sans isn’t even included!) Being able to change the list of fonts available would be great, right? PHP and WordPress filters to the rescue!

For this tutorial, it is mandatory that you have a child theme installed because we will be altering the ‘functions.php’ file. Before we dig into the Divi goodness, a quick word about hooks in WordPress, and specifically about filters. Peppered throughout every WordPress theme are a variety of ‘hooks’. Basically, they are placeholders that allow you to change the page content or insert your own code during the loading of each page. 

The screenshot above shows several of the ‘action hooks’ that are on a standard Divi post page. So before the menu bar loads in, for example, there is an action hook called ‘wp_print_styles’ that is shown in a darker green and currently has two actions hooked to it. Within the header there is an action hook, ‘et_header_top’ that the nice people at Elegant Themes has left there for us. In this case, it has a function called ‘et_add_mobile_navigation’ hooked to it. That little function adds in some HTML markup for the hamburger menu. If we wanted to have a little bit of markup on every page before the rest of the content we could hook to the ‘et_before_content’ action hook at the bottom of the picture above.

Okay, so those are action hooks, what about filters? The main difference between the two is that action hooks are a placeholder and the hooked function executes the output, whereas filters typically contain content that you want to alter before presenting it on the page and functions hooked to them return the output for execution in another function. They can be used in a very similiar way to action hooks, but come with their own parameters. In order to change our font list, we are going to take advantage of the ‘et_builder_google_fonts’ filter. If we dig into the Divi theme ‘/includes/builder/core.php’ file we can find a reference to this filter. What this line of code does is set up the filter that we want to use. It tells the WordPress core that we want to set-up a filter called ‘et_builder_google_fonts’ and populate it with the variable ‘$google_fonts’. The ‘apply_filters’ function exposes that filter hook for us to use.

Okay, what about ‘$google_fonts’? If we look further up in that same function we see that it is an array of arrays that define each of the fonts that are available. So the first font on the list is ‘Abel’ and the 400 weight style is geting loaded. The character_set defines that we are using a latin language font, which is used during language localization, and finally defines a type of ‘sans-serif’ for fallback purposes.

So, now we know the structure and what filter we want to use, let’s write our custom function. First up, I’ll show the entire thing for easy cut-and-paste into your child theme ‘functions.php’ file. 

Starting with the first line:

This tells WordPress that we want to tap into that ‘et_builder_google_fonts’ filter and basically take the value of that filter (an array of arrays, remember?) and put it through our custom function ‘shd_add_custom_font’. A quick sidebar on custom functions. First, we need to make sure they are going to be unique in name. I prefixed with shd (for Spring Hill Design), but if I were releasing this as a plugin I would likely add another prefix since I can see myself using the last part on multiple plugins. Second, I’m electing to use the function before actually defining it. This is a stylistic choice since the php file is essentially completely compiled before it is executed. This means that functions defined anywhere within the file will be available, not just ones defined before your usage. I think writing in this style makes debuging easier.

Okay, the next set of lines does a little check to see if we have defined this function previously using the ‘!’ (not) operator. So our ‘if’ statement says that if the ‘shd_add_custom_font’ function does not exist, run the code following the ‘:’ all the way down to the ‘endif;’. This is an alternative syntax – we could have written it if(test) {}. I like the alternative syntax because if you have a lot of logic in your php, keeping track of the braces can get difficult.

In the function call, we pass in the variable ‘$google_fonts’. This is the variable that was defined and populated by the original ‘apply_filters’ call in the Divi core. Now our custom function has access to that variable for modification.

This next section defines a new variable, ‘$new_font’, and then populates it with three different arrays. Each array corresponds to a font I want to add. I went to the google fonts page, searched for the fonts I wanted and the weights I wanted to make this array. So for ‘Vibur’ I chose to only load the 400 weight, whereas the ‘El Messiri’ is loading in the 400 and 500 weight. Note: do not add any spaces between your different styles, only a comma. None of the fonts I selected have an italics form, but that is usually loaded in by appending an ‘i’ to the font weight, like ‘500i’. 

This line of code modifies the original variable we brought in by adding our new arrays to the beginning. That way our fonts end up first on the list! If you want, you can switch the order of ‘$google_fonts’ and ‘$new_font’ in the array_merge() to put them last in the list.

Finally, we send our new font array back to the original function where the ‘apply_filters’ was called using the same name. If we wanted to eliminate all of the other Google fonts (for example if we have a client that will always forget if given too many choices) we could choose to wrap our $new_font array in an outer array wrapper and send it back without doing an ‘array_merge’, but remember it has to be passed back named ‘$google_fonts’.

So that wraps up this tutorial. One caveat – this will work fine for the front end builder, but not fully for the ‘Theme Customizer’. The fonts will be listed as ‘Default’ and getting that changed is a whole other tutorial! Also, getting rid of the non-google fonts (the first 5 on the font list) is also another challenge, but it does have its own filter, ‘et_websafe_fonts’! As usual, reach out in the comments or shoot me an e-mail if you see a mistake, or want help/further clarification.

Metta!

2 thoughts on “Fontastic!”

  1. Hey Bob, that post is really helpful. I come across your blog a couple of months ago while desperately searching for some tips how to use Scrollmagic in Divi. (You remember that post of yours, don’t you?). And you where the only guy in the whole bloody internet talking about implementing this cool JS-biblioteque in Divi  :). That one was so helpful to me, that I follow your blog since that day. And even when blogs about Divi-related stuff become more and more nearly every day, yours stays unique, because unlike most of the other ones you seem to  have no commercial interest in blogging about Divi. And isn’t that what blogging once was all about: sharing Knowledge with the community? So, with all these words I just want to say thank you and: Keep on blogging about Divi! Cheers, Mike from Hanover, Germany

    1. Aufrichtigen Dank!
      You are correct. I just like teaching people to do things for themselves. My SEO on this site is crap. The titles are non-sensical and I rarely have keywords that work. You have to be “in the know” to find my tutorials. A lot of the Divi Facebook pages have become a little commercial (looking at you Elegant Marketplace) where every question is answered with buy my plugin. At any point, thanks for your words of encouragement! I will keep blogging about Divi and hope the product keeps improving. If you need any programming advice, please feel free to reach out.
      Metta,
      Bob

Leave a Reply

Your email address will not be published. Required fields are marked *