Loading Google Fonts from Theme Options

Posted

Providing font options in a WordPress theme can be a significant design challenge.

It’s not quite as simple as just outputting a bit of inline CSS for font-family. Every font has unique meanlines and x-heights- so the font size, line heights and paddings for every font selector may need to be adjusted as well. A 1.2 line-height could be perfect in body text for “Helvetica Nueue”, but appear cramped with “Georgia”.

Unless you want to offer hundreds of options so that the user can also adjust these other css properties, it’s probably best to whittle down the font choices to a couple that look really great. I’d recommend adjusting the line heights and sizes automatically when the user makes a switch, which unfortunately, is a ton of extra work.

On a recent project I’ve been working on, I decided it wasn’t worth it. I kept the font face defaults and decided just give the user control over font colors and sizes. However, if you do want to offer your users that option, good on you.

What We’ll Cover

In this tutorial I won’t show how to adjust all the font properties- but I will suggest some ways to set up font options, and conditionally load Google fonts when a user has selected one.

In these examples I assume you’re using the Options Framework (theme or plugin version), but it should be fairly easy to use this code even if you’re building your own options panel from scratch.

Define the Font Arrays

I’d recommend selecting a limited number of fonts you think will look good with the theme. If you offer hundreds of fonts, your users will have to spend a long time finding which ones are the best. They might even select “Papyrus” or “Comic Sans“- and no one wants that.

When you have your font selections made, build out two arrays- one with the Google fonts, and another with system fonts. You should also supply fallback fonts in case the Google font doesn’t load or the user doen’t have the specific font on their system.

The reason I recommend building one array for system fonts and another for google fonts, is so we can easily check if the user select font is a Google font by comparing it against the Google array you’ve set.

In this example I also built a function that returns each of the font arrays. This is so I don’t have to redfine them in different functions or use a global variable.

Here’s how I set it up:

System Fonts

/**
 * Returns an array of system fonts
 * Feel free to edit this, update the font fallbacks, etc.
 */
function options_typography_get_os_fonts() {
	// OS Font Defaults
	$os_faces = array(
		'Arial, sans-serif' => 'Arial',
		'"Avant Garde", sans-serif' => 'Avant Garde',
		'Cambria, Georgia, serif' => 'Cambria',
		'Copse, sans-serif' => 'Copse',
		'Garamond, "Hoefler Text", Times New Roman, Times, serif' => 'Garamond',
		'Georgia, serif' => 'Georgia',
		'"Helvetica Neue", Helvetica, sans-serif' => 'Helvetica Neue',
		'Tahoma, Geneva, sans-serif' => 'Tahoma'
	);
	return $os_faces;
}

Google Fonts

/**
 * Returns a select list of Google fonts
 * Feel free to edit this, update the fallbacks, etc.
 */
function options_typography_get_google_fonts() {
	// Google Font Defaults
	$google_faces = array(
		'Arvo, serif' => 'Arvo',
		'Copse, sans-serif' => 'Copse',
		'Droid Sans, sans-serif' => 'Droid Sans',
		'Droid Serif, serif' => 'Droid Serif',
		'Lobster, cursive' => 'Lobster',
		'Nobile, sans-serif' => 'Nobile',
		'Open Sans, sans-serif' => 'Open Sans',
		'Oswald, sans-serif' => 'Oswald',
		'Pacifico, cursive' => 'Pacifico',
		'Rokkitt, serif' => 'Rokkit',
		'PT Sans, sans-serif' => 'PT Sans',
		'Quattrocento, serif' => 'Quattrocento',
		'Raleway, cursive' => 'Raleway',
		'Ubuntu, sans-serif' => 'Ubuntu',
		'Yanone Kaffeesatz, sans-serif' => 'Yanone Kaffeesatz'
	);
	return $google_faces;
}

Setting Up the Options

Since I’m using the Options Framework, I’ll simply pass the font array to the ‘faces’ parameter in a typography option. If you’re setting up your own from scratch, it’s the same idea, you’ll just need to set up the select box html manually to output the fonts.

You’ll probably want to use a mix of Google and system fonts. To do this, you’ll need to combine the two arrays you defined in options_typography_get_google_fonts and options_typography_get_os_fonts, and then resort them into alphabetical order. Here’s how to do that:

$typography_mixed_fonts = array_merge( options_typography_get_os_fonts() , options_typography_get_google_fonts() );
asort($typography_mixed_fonts);

Now, set up the actual options.

In this example, you’ll notice the first option is only Google fonts, and the second two are a mix:

	$options[] = array( 'name' => 'Selected Google Fonts',
		'desc' => 'Fifteen of the top google fonts.',
		'id' => 'google_font',
		'std' => array( 'size' => '36px', 'face' => 'Rokkitt, serif', 'color' => '#00bc96'),
		'type' => 'typography',
		'options' => array(
			'faces' => options_typography_get_google_fonts(),
			'styles' => false )
		);
	$options[] = array( 'name' => 'System Fonts and Google Fonts Mixed',
		'desc' => 'Google fonts mixed with system fonts.',
		'id' => 'google_mixed',
		'std' => array( 'size' => '32px', 'face' => 'Georgia, serif', 'color' => '#f15081'),
		'type' => 'typography',
		'options' => array(
			'faces' => $typography_mixed_fonts,
			'styles' => false )
		);
	$options[] = array( 'name' => 'System Fonts and Google Fonts Mixed (2)',
		'desc' => 'Google fonts mixed with system fonts.',
		'id' => 'google_mixed_2',
		'std' => array( 'size' => '28px', 'face' => 'Arvo, serif', 'color' => '#ee9f23'),
		'type' => 'typography',
		'options' => array(
			'faces' => $typography_mixed_fonts,
			'styles' => false )
		);

If you’ve done this correctly, you should now see something like this in the options panel:

Loading the Google Font

There are a couple ways to load Google fonts for a theme, but I think the stylesheet method is the easiest.

Since we have a couple typography options, with a mix of Google fonts and system fonts, we’ll need to check each of those options to see if a Google font has been selected. If it is a Google font, we’ll need to load the enqueue the font stylesheet from Google.

Here’s how I approached it:

/**
 * Checks font options to see if a Google font is selected.
 * If so, options_typography_enqueue_google_font is called to enqueue the font.
 * Ensures that each Google font is only enqueued once.
 */
if ( !function_exists( 'options_typography_google_fonts' ) ) {
	function options_typography_google_fonts() {
		$all_google_fonts = array_keys( options_typography_get_google_fonts() );
		// Define all the options that possibly have a unique Google font
		$google_font = of_get_option('google_font', 'Rokkitt, serif');
		$google_mixed = of_get_option('google_mixed', false);
		$google_mixed_2 = of_get_option('google_mixed_2', 'Arvo, serif');
		// Get the font face for each option and put it in an array
		$selected_fonts = array(
			$google_font['face'],
			$google_mixed['face'],
			$google_mixed_2['face'] );
		// Remove any duplicates in the list
		$selected_fonts = array_unique($selected_fonts);
		// Check each of the unique fonts against the defined Google fonts
		// If it is a Google font, go ahead and call the function to enqueue it
		foreach ( $selected_fonts as $font ) {
			if ( in_array( $font, $all_google_fonts ) ) {
				options_typography_enqueue_google_font($font);
			}
		}
	}
}
add_action( 'wp_enqueue_scripts', 'options_typography_google_fonts' );
/**
 * Enqueues the Google $font that is passed
 */
function options_typography_enqueue_google_font($font) {
	$font = explode(',', $font);
	$font = $font[0];
	// Certain Google fonts need slight tweaks in order to load properly
	// Like our friend "Raleway"
	if ( $font == 'Raleway' )
		$font = 'Raleway:100';
	$font = str_replace(" ", "+", $font);
	wp_enqueue_style( "options_typography_$font", "http://fonts.googleapis.com/css?family=$font", false, null, 'all' );
}

In this example I manually defined each of the options and their defaults: google_font, google_mixed, google_mixed_2. If you have a dozen of these options that might get a bit tedious- I’m sure you could find a better way to do it.

Once the fonts are set in the $selected_fonts array, we get rid of any duplicates with array_unique.

Then loop through the remaining fonts and check if they are a google font (e.g. in_array( $font, $all_google_fonts )).

If font is in the Google font array, the options_typography_enqueue_google_font function is called to enqueue the font stylesheet.

You’ll notice that the “Raleway” font gets some special treatment. Although the majority of fonts in the Google library are loaded in the same format, a couple have special needs. You’ll want to test all the fonts you set up to make sure they work. You’ll also want to make sure that the appropriate italic and bold fonts are loaded if they’ll be required.

Setting the Font Style

There’s a number of ways to set the styles that have been selected in an options panel. I’ve found the easiest and most efficient is to generally load inline styles.

Here’s a quick example which outputs the inline styles for the first option:

/*
 * Outputs the selected option panel styles inline into the <head>
 */
function options_typography_styles() {
     $output = '';
     $input = '';
     if ( of_get_option( 'google_font' ) ) {
          $input = of_get_option( 'google_font' );
	  $output .= options_typography_font_styles( of_get_option( 'google_font' ) , '.google-font');
     }
     if ( $output != '' ) {
	$output = "\n<style>\n" . $output . "</style>\n";
	echo $output;
     }
}
add_action('wp_head', 'options_typography_styles');

In the Options Framework, typography options also have size, color and style associated with them. So, that same CSS can be outputted every time by re-using the options_typography_font_styles function:

/*
 * Returns a typography option in a format that can be outputted as inline CSS
 */
function options_typography_font_styles($option, $selectors) {
		$output = $selectors . ' {';
		$output .= ' color:' . $option['color'] .'; ';
		$output .= 'font-family:' . $option['face'] . '; ';
		$output .= 'font-weight:' . $option['style'] . '; ';
		$output .= 'font-size:' . $option['size'] . '; ';
		$output .= '}';
		$output .= "\n";
		return $output;
}

Wrap Up

In my opinion, typography options are among the most difficult options to support. Has anyone else done it? Is your approach similar?

If you want to see working code, I’ve also included this demo in the Options Kit and the Options Theme Kit, which are paid demo packages for the Options Framework.

About Devin

I'm a WordPress developer based in Austin, Texas. Follow my projects on GitHub, or more general WordPress ramblings as @devinsays on twitter.

54 thoughts on “Loading Google Fonts from Theme Options

  1. Towfiq wrote:

    Awesome! thanks Devin.

  2. Luke Burford wrote:

    Is indeed awesome, and I’d like to +1 using a selection of the best Google fonts. The overhead of including more than a handful of the best probably isn’t worth it when you look at the quality of the fonts available (although I’ll probably add Lato to my list which I’ve found quite useful).

    Rockitt seemed to have disappeared a while ago though?

  3. Rifki wrote:

    Awesome! What about sanitation? it will be sanitized as well as typography default option?

    • Devin wrote:

      Yes.

  4. ramzesimus wrote:

    As we know some of Google fonts have different font-weight (100, 200 and so on) but other don’t have.
    Do you have any idea how to set font-weight depend on particular font?

    • Devin wrote:

      There’s no way I know of to do that programmatically. You’ll just have to do if else statements to load the custom font weights.

    • Beppe wrote:

      I added this code in the options-sanitize.php file (line 342) and it works for me. Now i can add 100, 200, 300, etc value for the css font-weight.

      function of_recognized_font_styles() {
      $default = array(
      ‘normal’ => __( ‘Normal’, ‘options_framework_theme’ ),
      ‘italic’ => __( ‘Italic’, ‘options_framework_theme’ ),
      ‘bold’ => __( ‘Bold’, ‘options_framework_theme’ ),
      ‘bold italic’ => __( ‘Bold Italic’, ‘options_framework_theme’ ),
      ’100′ => __( ’100′, ‘options_framework_theme’ ),
      ’200′ => __( ’200′, ‘options_framework_theme’ ),
      ’300′ => __( ’300′, ‘options_framework_theme’ ),
      ’400′ => __( ’400′, ‘options_framework_theme’ ),
      ’500′ => __( ’500′, ‘options_framework_theme’ ),
      ’600′ => __( ’600′, ‘options_framework_theme’ ),
      ’700′ => __( ’700′, ‘options_framework_theme’ ),
      ’800′ => __( ’800′, ‘options_framework_theme’ ),
      ’900′ => __( ’900′, ‘options_framework_theme’ ),
      );
      return apply_filters( ‘of_recognized_font_styles’, $default );
      }

  5. Lukas wrote:

    Hi Devin,

    I’ve been using your options framework for a few weeks now and it is absolutely amazing.

    I also want to support Google Webfonts, but I have no idea, where to put the code snippet, that actually loads the font from Google’s API. Could you tell me, where to place the code?

    Thanks
    Lukas

    • Devin wrote:

      Hi Lukas. You’re referring to the part under “Loading the Google Font”. The actual google fonts get loaded with that wp_enqueue_style call. You can put that code in functions.php, or any other file you’ve included from functions.php.

  6. Jonathan wrote:

    Is there a way to actually load the fonts dynamically or fo you have to manually list each one??

    • Devin wrote:

      There is an API to get all the fonts, but it seems a bit clunky for actually loading that into an option. And it’s difficult to output since the naming isn’t consistent. So, yes, I recommend curating a list of fonts you want for the theme, and only displaying those.

  7. David wrote:

    Thanks for posting. Looking at building Google webfonts into a new theme and this has been invaluable.

  8. Sara wrote:

    Pardon me if I didn’t really get this, but does your framework include an option to add like ALL Google fonts in it and thus give the client the ability to choose any font they want from the options panel?
    I mean I’m a beginner theme developer and I see many WP themes saying they have “hundreds of Google web fonts” included, I’m sure they don’t include them manually one by one, so is there a way to load all the Google fonts into your framework? It would be great to have everything included in one framework.
    I just wanted to say that I just followed u on twitter, and that this framework is a genius thing and I can’t believe I ran into your site and learned about it.
    Thank you :)

    • Devin wrote:

      There is way to dynamically get a list of all Google fonts, but it requires an API key. My guess is that most developers who include hundreds of fonts pull those down with a script and convert them into an option programmatically. My best suggestion would be to download one of them and see how they do it.

      This plugin, for instance, says they push updates as new fonts are released:
      http://wordpress.org/extend/plugins/wp-google-fonts/

      Here’s some information on the API: https://developers.google.com/webfonts/docs/developer_api

      • Sara wrote:

        I understand. Thank you for your reply, Devin. I’m looking forward to buying and using your framework in my next WordPress theme project. Thank you for replying, again, and for such a great job on this framework.
        Sara.

  9. Jonah Brown wrote:

    Is there a good way to show a distinction between Google and system fonts. So that in the drop down it is obvious which is which.

    Thanks

    • Devin wrote:

      You could give system fonts an asterisk (*), and in the description explain what that means.

      • Jonah Brown wrote:

        What would be the best way to make a function that can add a google font to this. that way I have a default list but then hook in a font my client may want.

        thanks

  10. Mel wrote:

    Hi Devin,

    The option framework is awesome.

    anyway i am having an issue with this functions for fonts.

    the google fonts drop down was good it has an output inside the THEME OPTIONS in admin area but the two other drop down (the mixed fonts) it has no output.

    I checked all the codes and are all the same I actually copy paste the codes..

    Please help.

    Thanks
    Mel

    • Devin wrote:

      Hi Mel. As far as I know the code is good. You could try doing some debugging (try a var_dump of the array) to see if you can track down why that field isn’t getting filled.

  11. Bilal Erdinc wrote:

    Hi Devin,
    what about a demo of the selected font? It is built in or have we do some modification?
    Amazing framework by the way!

    • Devin wrote:

      You mean to see the font in the options panel? I haven’t built a way to do that, though you are welcome to add it in yourself. There’s also the UP Theme Options Framework, which I believe allows you to do this.

  12. Dean wrote:

    Hi Devin

    I am having some trouble getting the Google Fonts Tutorial to work. I am probably missing something completely obvious here.

    I can successfully output the stylesheet in the head of my template, but how do you go about getting the font options to change the css selectors in the stylesheet?

    Thanks

    • Devin wrote:

      It’s covered under “Setting the Font Style” in this post. You’d output an inline style.

      • Dean wrote:

        Ok – so should this be included in the functions.php ? i’m having no luck with getting it to output the inline styles.

  13. amjad wrote:

    First i am really thanksful for it i used this code in my theme and its working great but on my client website (server) its showing error .

    Warning: Illegal string offset ‘face’ in /homepages/45/d459633490/htdocs/wp-content/themes/e-simple/inc/google-fonts.php on line 558
    Warning: Illegal string offset ‘face’ in /homepages/45/d459633490/htdocs/wp-content/themes/e-simple/inc/google-fonts.php on line 560

    On line 558 and 560 those are code

    $google_font['face'],
    $google_mixed_2['face'] );

    So waht should i to do.

  14. amjad wrote:

    Error showing on PHP 5.4.0 and PHP 5.4.0 PHP: 5.4.7
    but working fine on PHP: 5.3.18

    Warning: Illegal string offset ‘face’ in /homepages/45/d459633490/htdocs/wp-content/themes/theme/inc/google-fonts.php on line 558
    Warning: Illegal string offset ‘face’ in /homepages/45/d459633490/htdocs/wp-content/theme/e-simple/inc/google-fonts.php on line 560

    On line 558 and 560 those are code
    $google_font['face'],
    $google_mixed_2['face'] );

    please help to fix it

    • Devin wrote:

      Are you using the version purchased in the Options Kit with no customizations and getting that error? If so, glad to dive in. If not, you likely have a bug in your code. I’d var_dump all the arrays to see how they are filling.

      • amjad wrote:

        NO it’s your code that you give in this article

        [Code Redacted]

    • ramzesimus wrote:

      Having same errors on PHP 5.4 with this code
      $google_font['face'],
      $google_mixed_2['face'] );

      Warning: Illegal string offset ‘face’

      Any help will be appreciated.

      • Devin wrote:

        var_dump them and make sure they have the values you expect.

    • ramzesimus wrote:

      Solved! Problem appears when you’re first time activating theme (for me it was child theme).
      I’ve changed default value with array
      this
      $google_font = of_get_option('google_font', 'Rokkitt, serif');
      with this
      $google_font = of_get_option('google_font', array( 'size' => '12px', 'face' => 'Rokkitt, serif', 'style' => 'normal', 'color' => '#5c5c5c'));
      and it works like a charm without warnings!

  15. Mel wrote:

    What i did..

    I didn’t mixed the google and system fonts. to make it work

    when a tick box was check it will show the google font then created a functions to get the font family, color, size of the font.

  16. WPExplorer wrote:

    Made some tweaks, but this works great. Thanks!

    • But its not working on PHP 5.4.0. Showing error on two lines.

      • ramzesimus wrote:

        Wrote above. Works on PHP5.4 without warnings.
        Hope it will help.
        Cheers

  17. Carmelo wrote:

    I’m sorry, I want to draw the fonts in the theme, such as dynamically set the font page?

    thanks :)

  18. Spacechimp wrote:

    I can’t make it enqueue the google fonts.

    I have dropdowns with all the fonts from both the google and os lists when selected the style is called but there is no link to googleapis

    I assume when i get it right something like this:

    Should appear in the header?

    My options.php file looks like this:

    the inc folder remains exactly the same as the Options Framework Theme on Github
    and I have copied

    if ( !function_exists( 'optionsframework_init' ) ) {
    define( 'OPTIONS_FRAMEWORK_DIRECTORY', get_template_directory_uri() . '/inc/' );
    require_once dirname( __FILE__ ) . '/inc/options-framework.php';
    }

    into my functions.php file.

    Any pointers would be welcome
    Thanks in advance

  19. Spacechimp wrote:

    Hi again,

    Was also wondering is it possible to set font sizes in % rather than px, I tried changing line 247 of inc/options-interface.php but it had odd effects.

    Thanks

    • Devin wrote:

      Yes, this option isn’t ideal. Changing it directly there is fine. You can also use the of_recognized_font_sizes filter.

  20. Andreea wrote:

    Hi Devin,

    Great theme options framework! It’s absolutely amazing!

    I’ve tested the plugin first and went as far as including the google fonts you explain in this tutorial. All went well so I decided to purchase the option theme kit so I can have the theme options without the plugin activated.
    But when I tried to paste my adapted code for google fonts it breaks the theme options dashboard (it only shows the tab headings and nothing underneath). I’ve tried even to start fresh but when I copy the first bunch of code from your above tutorial and save, it breaks again.
    Is there something I have to do different than for the plugin?

    Many thanks,
    Andreea

    • Devin wrote:

      No, code is pretty much the same. Do you have WP_DEBUG on so you can see where the error is happening?

  21. ingegni wrote:

    Hi,
    google fonts are enqueue only if I are logged in as admin.
    Otherwise the code to include CSS don’t work.
    So what should I to do?

      • ingegni wrote:

        I have included the code in option.php instead of functions.php
        Now I have pasted the code in functions.php and it works correctly
        thank’s

  22. zoran wrote:

    hey Devin, good stuff as always. A newb question – where would the code under System Fonts and Google Fonts be placed? Thanks man, you rock.

    • Devin wrote:

      functions.php or a file that you include from functions.php.

      • zoran wrote:

        Thanks for the reply man. I thought that would go in functions.php and I’ve placed it there. In Theme Options instead of the 3 dropdowns with Google and System fonts I’m instead getting what looks to be the of_recognized_font_faces() array defined in options-sanitize.php instead, in all 3 dropdowns. Am I using an older version of Theme Options or missing something else? Thanks for your time.

      • Devin wrote:

        That should all work. Have you looked at the version in the Options Kit? That might be helpful.

      • zoran wrote:

        I should check that out. I’ll grab the Options Kit and go from there. Thanks man

  23. Tara wrote:

    Hello Devin! Again, thanks for the great plugin!

    Quick question. I followed this tutorial and I think I put my code in all the right places. However, the inline style is outputting

    color: g;
    font-family: g;
    font-weight: g;
    font-size: g;

    Why might that be?

    • Devin wrote:

      Looks like it’s not being output correctly. Can you var_dump the array and see the saved values?

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>