follow up: wordpress webfont delivery via own domain
Yesterday (I started the draft of this post on may 13 2018, 12 days before GDPR got applicable in the EU) I wrote about how to deliver webfonts from your domain and noticed, that wordpress themes need insights on this topic too.
Today (january 13 2020) I write about replacing a third party webfont in a wordpress theme, which I did the day before yesterday at a wordpress blog.
starting point
You run a wordpress blog and notice that your webfonts is hosted by google/typekit/fonts.com. This font providers do a great job in font variety, delivery-speed and a worldwide cdn for you. But these services are able to track your users, with every website using their font service. In countries following the GDPR or DSGVO this can be a problem and thatways you might want to host the fonts yourself‽
preparations
This post will walk you through
* creating a child theme
* finding which webfonts are in use
* finding webfonts on google fonts or an alternative font
* converting font from ttf to woff/woff2
* overwriting original theme webfont with self hosted one
* and as bonus: how to prevent google maps from loading google fonts
All steps assume you have shell access to your wordpress server, but you can do everyhting vie a gui-driven file manager too.
For this example I create a google webfont free version of the yoko theme.
creating a child theme
ssh on to your webserver and navigate to wp-content/themes
and create a folder with this name: original-theme-child
. For example, if you use yoko
as theme, you mkdir yoko-child
in your wp-content/themes
folder.
cd yoko-child
and touch style.css
. Now you take your command line editor of choice and put the following in to that style.css
:
/*
Theme Name: λoko (no google fonts)
Description: Copy of Yoko, but without Droid Sans and Droid Serif
Author: Raoul Kramer
Author URI: https://raoulkramer.de
Template: yoko
Version: 0.1
Text Domain: yoko-child
*/
Really important is the correct spelling of the Template: yoko
part in this css file. Otherwise wordpress will not get the link between your child theme and the original theme.
Create a functions.php too in this folder and put this code in it:
<?php
function child_theme_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-theme-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style'));
}
add_action( 'wp_enqueue_scripts', 'child_theme_styles');
?>
finding which webfonts are in use
Navigate into the original theme directory cd ../yoko
and type the following in your console: grep -rni 'fonts.google' *
or search for the font name itself like grep -rni 'Droid' *
:
wp-content/themes/yoko$ grep -rni 'fonts.google' *
functions.php:57: $fonts_url = add_query_arg( $query_args, "//fonts.googleapis.com/css" );
or
wp-content/themes/yoko$ grep -rni 'Droid' *
functions.php:40: $droid_sans = _x( 'on', 'Droid Sans font: on or off', 'yoko' );
functions.php:42: $droid_serif = _x( 'on', 'Droid Serif font: on or off', 'yoko' );
functions.php:44: if ( 'off' !== $droid_sans || 'off' !== $droid_serif ) {
functions.php:47: if ( 'off' !== $droid_sans )
functions.php:48: $font_families[] = 'Droid Sans:400,700';
functions.php:50: if ( 'off' !== $droid_serif )
functions.php:51: $font_families[] = 'Droid Serif:400,700,400italic,700italic';
…
Open functions.php
and look around line 40, what is injecting the google fonts:
function yoko_fonts_url() {
$fonts_url = '';
/* Translators: If there are characters in your language that are not
* supported by PT Sans or Raleway translate this to 'off'. Do not translate
* into your own language.
*/
$droid_sans = _x( 'on', 'Droid Sans font: on or off', 'yoko' );
$droid_serif = _x( 'on', 'Droid Serif font: on or off', 'yoko' );
if ( 'off' !== $droid_sans || 'off' !== $droid_serif ) {
$font_families = array();
if ( 'off' !== $droid_sans )
$font_families[] = 'Droid Sans:400,700';
if ( 'off' !== $droid_serif )
$font_families[] = 'Droid Serif:400,700,400italic,700italic';
…
}
And than look which wordpress hook calls this function:
function yoko_scripts() {
…
// Add Google Webfonts
wp_enqueue_style( 'yoko-fonts', yoko_fonts_url(), array(), null );
…
}
That is all we need for this theme. Other themes may use @import https://fonts.google...
for embedding webfonts, this post will not touchthis scenario.
finding webfonts on google fonts or an alternative font
This theme is somekind special, since it uses Droid Sans and Droid Serif, but both are not downloadable via fonts.google.com anymore. You can not legally host this fonts yourself, so you need to find an alternative font you can host yourself. I choose Public Sans and PTSerif.
Choose a font you like, check that you can legally host this font yourself and download it.
converting font from ttf to woff/woff2
How to convert a font file from ttf to woff/woff2, I already wrote here, but if you follow this post, you do not want to change the page right now, so here is a repost.
Install npm install -g ttf2woff ttf2woff2
on your local machine, navigate into the unzipped webfont folders and execute the following command:
for f in *.ttf
do
ttf2woff $f ${f%.ttf}".woff"
cat $f | ttf2woff2 >> ${f%.ttf}".woff2"
done
Every woff and woff2 file you need to copy on to your server to your child-theme folder: wp-content/themes/yoko-child/fonts
.
overwriting original theme webfont with self hosted one
This is a two step doing. On the one hand you need to deregister the yoko_fonts_url()
call in your child theme, on the other hand you need to overwrite the font usage.
deregister webfont hook
Open the functions.php
in your child-theme and insert this code into the file:
// deregister google font loading
function deregister_yoko_fonts() {
wp_deregister_style('yoko-fonts');
}
add_action( 'wp_enqueue_scripts' , 'deregister_yoko_fonts', 100);
With this unhook you simple remove the call to the function, that put the google font url into the head.
overwrite font usage
Up above, you have seen how often the font-family
is used in the original css, and now we use another font for both sans and serif fonts.
We do not want to override every font-family declaration, we read the @font-face
spec and see that we can delcare our new font to be accessible as Droid Sans
or Droid Serif
.
@font-face {
font-family: 'Droid Sans';
font-style: italic;
font-weight: 400;
src: local('Droid Sans Regular'),
url('./fonts/PublicSans-LightItalic.woff2') format('woff2'),
url('./fonts/PublicSans-LightItalic.woff') format('woff');
}
@font-face {
font-family: 'Droid Sans';
font-style: normal;
font-weight: 700;
src: local('Droid Sans Bold'),
url('./fonts/PublicSans-Bold.woff2') format('woff2'),
url('./fonts/PublicSans-Bold.woff') format('woff');
}
@font-face {
font-family: 'Droid Sans';
font-style: italic;
font-weight: 700;
src: local('Droid Sans Regular'),
url('./fonts/PublicSans-BoldItalic.woff2') format('woff2'),
url('./fonts/PublicSans-BoldItalic.woff') format('woff');
}
@font-face {
font-family: 'Droid Serif';
font-style: normal;
font-weight: 400;
src: local('Droid Serif Regular'),
url('./fonts/PTSerif-Regular.woff2') format('woff2'),
url('./fonts/PTSerif-Regular.woff') format('woff');
}
@font-face {
font-family: 'Droid Serif';
font-style: italic;
font-weight: 400;
src: local('Droid Serif Regular'),
url('./fonts/PTSerif-Italic.woff2') format('woff2'),
url('./fonts/PTSerif-Italic.woff') format('woff');
}
@font-face {
font-family: 'Droid Serif';
font-style: normal;
font-weight: 700;
src: local('Droid Serif Bold'),
url('./fonts/PTSerif-Bold.woff2') format('woff2'),
url('./fonts/PTSerif-Bold.woff') format('woff');
}
@font-face {
font-family: 'Droid Serif';
font-style: italic;
font-weight: 700;
src: local('Droid Serif Regular'),
url('./fonts/PTSerif-BoldItalic.woff2') format('woff2'),
url('./fonts/PTSerif-BoldItalic.woff') format('woff');
}
And that's it.
bonus: how to prevent google maps from loading google fonts
In fact, this is a copy and paste part from Stack Overflow, but I rewrote his code in plain javascript, since he used jQuery. Take the following code and put it into your functions.php - this will block any JavaScript add a fonts.googleapis.com url to your page, all props go to Thommy Tomka:
function dont_load_google_fonts() { ?>
<script>
(function() {
var isGoogleFont = function (element) {
// google font download
if (element.href
&& element.href.indexOf('https://fonts.googleapis.com') === 0) {
return true;
}
return false;
}
// we override these methods only for one particular head element
// default methods for other elements are not affected
var head = document.querySelector('head');
var insertBefore = head.insertBefore;
head.insertBefore = function (newElement, referenceElement) {
if (!isGoogleFont(newElement)) {
insertBefore.call(head, newElement, referenceElement);
}
};
var appendChild = head.appendChild;
head.appendChild = function (textNode) {
if (!isGoogleFont(textNode.innerText)) {
appendChild.call(head, textNode);
}
};
}());
</script>
<?php
}
add_action ('wp_print_scripts', 'dont_load_google_fonts');
I do not like the <?php function name() { ?> plain html code <?php } ?>
syntax, but in this case, it really comes in handy.
final step
Copy the screenshot file from the original theme into your child-theme: cp ../yoko/screenshot.png .
Now you can keep your original wordpress theme up to date and your child theme will bring a little bit more privacy to your visitors.
Happy blogging!
Article Image from Syd Wachs via unsplash and ghost ❤.