Resource Hints in WordPress

Resource hints are a relationship used to indicates that a given origin or resource should be acted upon before they are loaded.

Doing this in WordPress is more complicated. While we could add the resources directly to the templates it would require changing the templates whenever we change fonts or any detail of the type of resource hint.

The code below is taken from the Twenty Seventeen theme and with some modifications will work on any theme running on recent versions of WordPress.

It requires enqueuing the fonts generated through twentyseventeen_fonts_url(), which is outside the scope of this post but is available on their Subversion repository

The enqueuing script is similar to how we normally enqueue scripts and fonts to use with WordPress but the second parameter calls a theme function rather than a static asset. The modified code looks like this.

function twentyseventeen_scripts() {
    // Add custom fonts, used in the main stylesheet.
  wp_enqueue_style( 'twentyseventeen-fonts', twentyseventeen_fonts_url(), array(), null );

add_action( 'wp_enqueue_scripts', 'twentyseventeen_scripts' );


We then create resource hints in twentyseventeen_resource_hints(). It takes two parameters:

  • @param array $urls URLs to print for resource hints.
  • @param string $relation_type The relation type the URLs are printed.

And returns an array of URLs of resource hints to print.

 function twentyseventeen_resource_hints( $urls, $relation_type ) {
  if ( wp_style_is( 'twentyseventeen-fonts', 'queue' ) && 'preconnect' === $relation_type ) {
    $urls[] = array(
      'href' => '',

    return $urls;
add_filter( 'wp_resource_hints', 'twentyseventeen_resource_hints', 10, 2 );

We choose what URL to create by checking if the style has been enqueued and if the type of relation (indicated in the $relation_type variable) is preconnect.

Finally, we add the wp_resource_hint filter with the function we just defined.


Javascript Godies: Intl.DisplayNames

There are times when our applications need to reference information such as languages, regions, scripts, and currencies. Some of these may be easier and some may be hard but either way, we shouldn’t hardcode them into the apps themselves, this makes them brittle and harder to localize.

Rather than download a fresh copy of the locale data every time there is a change, we can leverage the versions available in JavaScript runtimes. The Intl.DisplayNames API gives JavaScript developers direct access to those translations, allowing applications to more easily display localized names.

The following example creates four constants reflecting the languages, regions, scripts, and currency as used in Chile (es-cl as the first parameter to DisplayNames).

const LanguageNames = new Intl.DisplayNames(['es-cl'], { type: 'language' });
const RegionNames = new Intl.DisplayNames(['es-cl'], { type: 'region' });
const ScriptNames = new Intl.DisplayNames(['es-cl'], { type: 'script' });
const CurrencyNames = new Intl.DisplayNames(['es-cl'], {type: 'currency'});

We then use the constants to query the CLDR data based on our locale.

The values that we use for each type of query are different:

The first group of examples queries the names of the languages.


"español de España"



Same with the name of regions and countries. Some regions don’t appear in the listings for region names and where they appear they don’t work with the code.

"Reino Unido"


"Unión Europea"

The currency values are, to me, the most confusing as they use only the first two letters of the country and then the name of the currency itself, which is not an intuitive name if you don’t look at the table.


"Peso Chileno"

"libra esterlina"

"dólar estadounidense"


The names for scripts and languages are a little more complicated. The names of the scripts/languages are not as intuitive as the names of languages or regions and not all regions have names available to us.

Entering an unknown script name will return either the string you entered or a syntax error when you use them.





This gives you a lot of flexibility when building multilingual applications. I need to fully learn how to use it but even as I stumble along, the possibilities for international e-commerce sites are awesome.



Rivendellweb Theme: Work So far

This is my first attempt in a while to create a fully customized WordPress theme without using Genesis or other theme frameworks. The idea is to use modern web technologies like CSS Grid, Variable Fonts and others to experiment with what it takes to add these technologies to a WordPress theme using Underscores as the starter theme.

It is also a playground for working with progressive enhancement, responsive design and how to accommodate multiple screen sizes in the same WordPress theme.

Some aspects that I think are important to highlight and also some areas where further work is needed.

Variable Fonts

The theme uses a single variable font, Recursive for everything from monospaced code examples to the casual font face used for the title header and everything in between, replacing 6 font files with a single 523KB WOFF2 one.

Yes, it’s over 500KB of fonts, but we’ve taken care of not interrupting the page loading experience by using several tools and techniques:

  • subsetting the font using [Glyphhanger](
  • Using Font Face Observer to add classes based on font loading results
  • Use font-display to swap the font in after it has finished loading.

To make everything work in WordPress we need to:

  • Enqueue the font or load it a local CSS stylesheet
  • Enqueue FontFace Observer
  • wrap the inline script that uses Fontface Observer in a PHP function and then use add_action to add the script to the footer of all documents.

The process is documented in Using Variable Fonts in a WordPress theme

The biggest disadvantage of variable fonts is that they require fairly recent browsers and operating systems to work so they must be treated as an enhancement and alternative fonts must be built into the stacks, preferably fonts that are close in size so that the text will not shift too much when the web font loads.

Another disadvantage is that, as I write this, Recursive is still in beta and there will be several more releases before it is deemed ready for production. I will continue to track the changes and will update the font when needed.

Adapting third-party libraries to use variable fonts

As documented in Modifying Prism.js to use a variable font I’ve tweaked the Prism.js CSS stylesheet to also use Recursive and its MONO axis

Yes, this ties me down to a specific version of Prism but, unless there are major changes in the Prism codebase or they add a new language that I must have, eliminating another potential font download is worth the effort.


One of the earliest decisions I made was to use CSS Grid for the layout and it works amazingly well.

Theme Structure

I have added the minimum necessary to make the theme work as designed. It usually involves adding styles, adding templates or modifying existing templates.

I’ve also used the WordPress Unit Test Data to validate that the content works as intended with as many types of content available on WordPress as possible.

To Gutenberg or not to Gutenberg

I’ve struggled with supporting Gutenberg on my theme or not until I realized that it doesn’t matter what I choose, it’s the people using the theme that get to choose whether to use it or not.


The header uses the following items:

The custom logo and menu are conditional. If the corresponding setting on the appearance admin menu is not selected, then it will not appear in the front end.


Content is pretty much untouched from the original Underscores sources.

There are a few edge cases that I need to address like full-bleed images in a grid when they are not direct children of the grid element but they don’t seem to impact the code appearance or the readability of the content itself.


The footer area uses two widget areas laid out using flexbox rows. Each area is also a flexbox laid using columns.

This may be more work than what’s needed but it gives me the flexibility to add multiple widgets in whatever order I choose.

Javascript build system

I’ve adopted a build system I originally crafted for SASS-based workflows. It works but SASS itself is starting to not support the workflows I’ve been using for a while.

There are other libraries that I’m evaluating as potential replacements for SASS and they would require minimal effort as far as the build system is concerned.

See PostCSS deep dive

Javascript still runs through Babel but some code still depends on jQuery to work. jQuery is useful but it takes away a lot of the newer functionality available to Javascript.

So one thing I may evaluate going forward is whether the tradeoff between browser support and language features is worth it.

Some things still outstanding

Some things I’m thinking about and considering as I move forward completing the theme. Some of these things are nice to have while others are things I’ve never attempted before when working on a theme.

Full-bleed figures

Full bleed images, with or without captions, are one of the few things that don’t work.

I’m researching what it would take to fix the issue.

jQuery or Javascript

Evaluate if the tradeoff between Javascript features and browser support is worth it, particularly in light that some features already require modern browsers and operating systems.

Plugging things to the customizer

Right now the theme and the customizer have little or no relationship. One of the next tasks is to figure out how to hook the theme into the customizer.

We do this to make sure that users don’t need to tweak the HTML/PHP and CSS directly.

AMP compatibility

What, if anything, we need to do to make sure the site is AMP-ready?



WordPress conditional tags

One of the things I like the most about working with WordPress, although it can be frustrating at times, is the number of conditional tags available. This post will explore what they are, and some examples of how we use them.

What they are

Conditional tags are pre-packaged PHP functions that allow you to customize your WordPress theme based on whether the current item matches a condition or not Conditional Tags usually work with PHP if /else Conditional Statements.

The if/else code checks if a statement is true or false. The example uses the is_single() conditional tag.

If the statement is found to be true, the first set of code is executed and we echo This is a single post!.

If it’s false, we skip the first block of code, and execute the else block and echo This is not a single post! instead.

if ( is_single() ):
    echo 'This is a single post!';
    echo 'This is not a single post!';

How do they work?

Expanding on the example in the previous section we can use one or more conditional tags and one or more logical operators in either a template or in a function that hooks to a trigger or action for later execution.

We’ll walk through some examples as a means to explain what they do.

Are we on the home page?

WordPress makes a difference between the front page (the main page of the site) and the main page (the index page for the blog). They may be the same or they may not; in this particular case we only want to output something if the

<?php if ( ( is_front_page() && is_home() ) ) :
  echo "This is front and home page";
  echo "do something cool";

Likewise, WordPress makes conditional tags for different types of content like single posts or pages. The next example will branch out and check if the user is visiting a single post or a page and echo different outputs depending on what we visited.

<?php if ( is_single() ) :
  echo "Visiting Single Post";
elseif ( is_page() ) :
  echo "Visiting Page";

The final example is to check whether a user is logged in and display different content to them than to anonymous visitors.

<?php if ( is_user_logged_in() ):
  echo "Show secret for logged in users";
else :
  echo "Shhh, user is not logged in!";

We’ve used echo statements in the example; in real production code, we’d use more complex code, including WordPress specific functions.

The last example will work through actual WordPress code to, hopefully, fully illustrate how conditional tags work.

The code uses conditional tags in two places:

  1. The first one is to check if we’re in the site’s front page and the blog home page (they are the same)
    • IF the condition matches we use h1 for the title
    • If not then we use p elements for the title since we want to style it differently
  2. Check if we have a description of the blog (another name for the tag line) or we’re looking at the customizer view of the page
    • If neither condition are met we don’t show the description
<div class="site-branding">
  <?php the_custom_logo(); ?>
  <?php if ( is_front_page() && is_home() ) : ?> <!-- 1 -->
    <div class="site-branding__text">
      <h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
    else :
      <p class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></p>
    $rivendellweb_description = get_bloginfo( 'description', 'display' );
    if ( $rivendellweb_description || is_customize_preview() ) :
      ?> <!-- 2 -->
      <p class="site-description"><?php echo $rivendellweb_description; /* WPCS: xss ok. */ ?></p>
    <?php endif; ?>
  </div> <!-- .site-branding__text -->
</div><!-- .site-branding -->

There is a huge number of conditional tags available. If you want to see the full list, check the List of Conditional Tags at

Links and Resources


Animating variable fonts

One of the things I find the most interesting about variable fonts is that you can animate them between different values.

This post will explore how to create animations using Variable font axes, both default axes like weight and custom axes like casual available in Recursive

I will be using the following HTML:

<h1 class="weight">Hello World</h1>

<h1 class="casual">Hello World</h1>

The CSS is broken in multiple blocks for readability and ease of explanations.

The first block performs the following tasks

  1. Load the variable font using a modified @font-face syntax
    • The format for the font changes to reflect that it’s a variable font
    • We repeat the URL to accommodate two values for the format attribute
    • font-weight takes two values representing the boundary values for the attribute
  2. Define the default values for the variable fonts in the :root attribute. We use :root rather than html because :root has a higher specificity
  3. Add a set of default attributes to the universal selector. This will match all elements on the page so we don’t have to add them individually to all elements
  4. We add padding to the HTML and enlarge h1 elements
@font-face {
  font-family: "Recursive VF"; <!-- 1 -->
  src:  url("fonts/recursive.woff2") format("woff2 supports variations"),
        url("fonts/recursive.woff2") format("woff2-variations");
  font-weight: 300 1000;
  font-display: swap;
:root { <!-- 2 -->
  --recursive-mono: 0;
  --recursive-casual: 0;
  --recursive-weight: 400;
  --recursive-slant: 0;
  --recursive-italic: 0.5;

* {
  font-family: "Recursive VF", Verdana, sans-serif; <!-- 3 -->
  font-weight: var(--recursive-weight);
    "MONO" var(--recursive-mono),
    "CASL" var(--recursive-casual),
    "slnt" var(--recursive-slant),
    "ital" var(--recursive-italic);

body { <!-- 4 -->
  padding: 2em;

h1 { <!-- 4 -->
  font-size: 3em;

Then for each animation, we need to do two things:

  1. Define the animation using the animation using either the shorthand or individual attributes
    • Both examples use the shorthand syntax
  2. Create the keyframes sets using the @keyframes at-rule
    • The name must match the animation property defined in the previous step
.weight {
  opacity: 0;
  animation: weightAnim linear 2s forwards; /* 1 */

@keyframes weightAnim { /* 2 */
  from {
    opacity: 0;
  to {
    font-weight: 1000;
    opacity: 1;
.casual {
  animation: casualAnim linear 4s forwards; /* 1 */

@keyframes casualAnim { /* 2 */
  from {
    font-variation-settings: "CASL" 0;
  to {
    font-size: 8em;
    font-variation-settings: "CASL" 1;

Tools like Splitting.js, Lettering.js or its jQuery-less counterpart (in this Gist) allow for more complex effects targetting portions of a sentence or even individual characters.

See Mandy Michael’s Interactivity and Animation with Variable Fonts for more in-depth coverage of how to animate variable fonts and examples of what this looks like.