Try Tuts+ Premium, Get Cash Back!
Changing the Fonts of Your WordPress – Part 2: Theme Integration

Changing the Fonts of Your WordPress – Part 2: Theme Integration

Tutorial Details
  • Program: WordPress
  • Version: 3.2.1+
  • Difficulty: Intermediate
  • Estimated Completion Time: 20 - 30 minutes
This entry is part 2 of 2 in the series Changing the Fonts of Your WordPress Site

WordPress continually proves itself time, time, and again that it has very few limitations, and is rapidly pushing itself to being, if not the best, but certainly the most versatile CMS available. Out of the box it is certainly not perfect, but you can change it however you want. In the previous tutorial, we went over how to add fonts to your theme via a plugin. Now, we’ll integrate font options directly into the theme’s options.

Again, we will be using Google Web Fonts because it’s easy, fast and, most importantly, free. With Google Web Fonts there is no need to worry about using the proper font formats, everything is handled by Google.


Step 1 Add a Settings Page

First, make sure you have a theme options page. If you don’t know how to make one, I suggest reading Create a Settings Page by Jarkko Laine. In this tutorial, I’m going to assume that you know the basics and build from there. So let’s go into our functions.php file and add a simple typography settings page:

add_action( 'admin_menu', 'my_fonts' );
function my_fonts() {
    add_theme_page( 'Fonts', 'Fonts', 'edit_theme_options', 'fonts', 'fonts' );
}

Step 2 Add the Form

Now that we’ve added a settings page, we have to code the callback function we’re using to render the page itself, which would be typography. All we need is a basic form that shows a dropdown of all the fonts that users can choose from and allow them to change it.

function fonts() {
?>
    <div class="wrap">
        <div><br></div>
        <h2>Fonts</h2>

        <form method="post" action="options.php">
            <?php wp_nonce_field( 'update-fonts' ); ?>
            <?php settings_fields( 'fonts' ); ?>
            <?php do_settings_sections( 'fonts' ); ?>
            <?php submit_button(); ?>
        </form>
    </div>
<?php
}

Okay, we’ve added our fonts form to the page, just some basic settings_fields, but WordPress has no idea. Now we use the admin_init action to initialize our settings and add the callbacks:

add_action( 'admin_init', 'font_init' );
function font_init() {
    register_setting( 'fonts', 'fonts' );

    // Settings fields and sections
    add_settings_section( 'font_section', 'Typography Options', 'font_description', 'fonts' );
    add_settings_field( 'body-font', 'Body Font', 'body_font_field', 'fonts', 'font_section' );
}

All we’re doing here is creating a settings section for our fonts forms and the field for a single font, you can add more if you want, in this tutorial I’m only going over the body tag. Just add more by copying that field and replace body with something else like h1. We also now have a setting called fonts, where we will be storing our font data/options. Let’s go ahead and define the callback functions, font_description and body_font_field.

function font_description() {
    echo 'Use the form below to change fonts of your theme.';
}
function body_font_field() {
    $options = (array) get_option( 'fonts' );
    $fonts = get_fonts();

    if ( isset( $options['body-font'] ) )
        $current = $options['body-font'];
    else
    	$current = 'arial';

    ?>
        <select name="fonts[body-font]">
        <?php foreach( $fonts as $key => $font ): ?>
            <option <?php if($key == $current) echo "SELECTED"; ?> value="<?php echo $key; ?>"><?php echo $font['name']; ?></option>
        <?php endforeach; ?>
        </select>
    <?php
}

We have to get the font options that we just made in the init action and the fonts we have available, get_fonts(). Set the current font in the form to whatever is in the options, otherwise it’ll default to Arial. Then, use a foreach loop to go through our array of available fonts. You can also add a description or make it a brief tutorial on how to use it.


Step 3 Getting the Fonts

As you noticed in the previous snippet of code, we need to define the get_fonts() function to retrieve the fonts we need. You can either include the Google Webfonts or just stick with the basic CSS fonts. We’ll just use an array to store all of the fonts, and then distinguish them by their font name. You can do this with any fonts, but for the purposes of this tutorial, we’ll just be using Arial, Ubuntu and Lobster.

function get_fonts() {
    $fonts = array(
        'arial' => array(
            'name' => 'Arial',
            'font' => '',
            'css' => "font-family: Arial, sans-serif;"
        ),
        'ubuntu' => array(
            'name' => 'Ubuntu',
            'font' => '@import url(https://fonts.googleapis.com/css?family=Ubuntu);',
            'css' => "font-family: 'Ubuntu', sans-serif;"
        ),
        'lobster' => array(
            'name' => 'Lobster',
            'font' => '@import url(https://fonts.googleapis.com/css?family=Lobster);',
            'css' => "font-family: 'Lobster', cursive;"
        )
    );

    return apply_filters( 'get_fonts', $fonts );
}

Note: You are not limited to only using Google Webfonts. If you want to use a custom font that is hosted on your FTP or on Amazon S3, then replace @import with @font-face and change the url to where your font file is hosted.


Step 4 Add the CSS

Before you apply any of fonts in your CSS, you should remove all instances of Google Webfonts of in your CSS files. This way when we make the import call to get the Ubuntu font, we’re not wasting an extra 100 ms getting the Lobster font too.

Now that we have all of our fonts set, we have to create a wp_head action that adds the styling to your WordPress. If you are using this script for multiple tags, simply duplicate the code, just changing “body” to whichever tag you’re editing.

add_action( 'wp_head', 'font_head' );
function font_head() {
    $options = (array) get_option( 'fonts' );
    $fonts = get_fonts();
    $body_key = 'arial';

    if ( isset( $options['body-font'] ) )
        $body_key = $options['body-font'];

    if ( isset( $fonts[ $body_key ] ) ) {
        $body_font = $fonts[ $body_key ];

        print_ '<style>';
        echo $body_font['font'];
        echo 'body { ' . $body_font['css'] . ' } ';
        echo '</style>';
    }
}

We start by checking if a font is chosen in our options, if not, then set the font to our default, Arial. Now we print out the style tag, the import statement and our CSS code.

What You Get in the End

This is what you should’ve ended up with:

The final font options page.


Full Source Code

For anyone who is having some trouble putting it all together. Here is the full source code, ready to just paste into the functions.php file:

<?
// Changing the Fonts of Your WordPress - Part 2: Theme Integration 
// Tutorial on WP Tuts
// by Fouad Matin
// Please credit this tutorial, by putting a link back to http://wp.tutsplus.com/tutorials/changing-the-fonts-of-your-wordpress-site-part-2-theme-integration/
// Enjoy!
add_action( 'admin_menu', 'my_fonts' );
function my_fonts() {
    add_theme_page( 'Fonts', 'Fonts', 'edit_theme_options', 'fonts', 'fonts' );
}
function fonts() {
?>
    <div class="wrap">
        <div><br></div>
        <h2>Fonts</h2>

        <form method="post" action="options.php">
            <?php wp_nonce_field( 'update-fonts' ); ?>
            <?php settings_fields( 'fonts' ); ?>
            <?php do_settings_sections( 'fonts' ); ?>
            <?php submit_button(); ?>
            </form>
        <img style="float:right; border:0;" src="http://i.imgur.com/1qqJG.png" />
    </div>
<?php
}

add_action( 'admin_init', 'my_register_admin_settings' );
function my_register_admin_settings() {
    register_setting( 'fonts', 'fonts' );
    add_settings_section( 'font_section', 'Font Options', 'font_description', 'fonts' );
    add_settings_field( 'body-font', 'Body Font', 'body_font_field', 'fonts', 'font_section' );
    add_settings_field( 'h1-font', 'Header 1 Font', 'h1_font_field', 'fonts', 'font_section' );
}
function font_description() {
    echo 'Use the form below to change fonts of your theme.';
}
function get_fonts() {
    $fonts = array(
        'arial' => array(
            'name' => 'Arial',
            'font' => '',
            'css' => "font-family: Arial, sans-serif;"
        ),
        'ubuntu' => array(
            'name' => 'Ubuntu',
            'font' => '@import url(https://fonts.googleapis.com/css?family=Ubuntu);',
            'css' => "font-family: 'Ubuntu', sans-serif;"
        ),
        'lobster' => array(
            'name' => 'Lobster',
            'font' => '@import url(https://fonts.googleapis.com/css?family=Lobster);',
            'css' => "font-family: 'Lobster', cursive;"
        )
    );

    return apply_filters( 'get_fonts', $fonts );
}
function body_font_field() {
    $options = (array) get_option( 'fonts' );
    $fonts = get_fonts();
    $current = 'arial';

    if ( isset( $options['body-font'] ) )
        $current = $options['body-font'];
    ?>
        <select name="fonts[body-font]">
        <?php foreach( $fonts as $key => $font ): ?>
            <option <?php if($key == $current) echo "SELECTED"; ?> value="<?php echo $key; ?>"><?php echo $font['name']; ?></option>
        <?php endforeach; ?>
        </select>
    <?php
}
function h1_font_field() {
    $options = (array) get_option( 'fonts' );
    $fonts = get_fonts();
    $current = 'arial';

    if ( isset( $options['h1-font'] ) )
        $current = $options['h1-font'];

    ?>
        <select name="fonts[h1-font]">
        <?php foreach( $fonts as $key => $font ): ?>
            <option <?php if($key == $current) echo "SELECTED"; ?> value="<?php echo $key; ?>"><?php echo $font['name']; ?></option>
        <?php endforeach; ?>
        </select>
    <?php
}

add_action( 'wp_head', 'font_head' );
function font_head() {
    $options = (array) get_option( 'fonts' );
    $fonts = get_fonts();
    $body_key = 'arial';

    if ( isset( $options['body-font'] ) )
        $body_key = $options['body-font'];

    if ( isset( $fonts[ $body_key ] ) ) {
        $body_font = $fonts[ $body_key ];

        echo '<style>';
        echo $body_font['font'];
        echo 'body  { ' . $body_font['css'] . ' } ';
        echo '</style>';
    }

    $h1_key = 'arial';

    if ( isset( $options['h1-font'] ) )
        $h1_key = $options['h1-font'];

    if ( isset( $fonts[ $h1_key ] ) ) {
        $h1_key = $fonts[ $h1_key ];

        echo '<style>';
        echo $h1_key['font'];
        echo 'h1  { ' . $h1_key['css'] . ' } ';
        echo '</style>';
    }
}
?>

Conclusion

By now, you should know how to add a font settings page, get fonts from the Google Webfonts directory, and apply those fonts to the theme. If you have any additional suggestions or questions regarding custom typography, feel free to leave a comment!


Other parts in this series:Changing the Fonts of Your WordPress Site – Part 1: Using a Plugin
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Pingback: My Stream » Changing the Fonts of Your WordPress – Part 2: Theme Integration

  • http://www.nomad-one.com nomadone

    Nice one, I like the way you’ve broken it down into bite sized chunks.

    I noticed you have fonts for body and H1 in the final code exmaple, but the setting option only shows body?
    Does this apply both settings?

    • Fouad Matin
      Author

      Thanks! I wrote it in a way I thought was easiest to understand.

      In the tutorial, I mention that it is possible to add functionality for other tags. You’re right, in the settings section I only show you how to add set a custom font for the body tag. In the final source code, I just added an example to show how its done.

  • http://webdesignhabits.com/ Joefrey Mahusay

    Very useful tutorial. This is what I need for my theme options.

  • supprof

    is there any one who could make us a video wordpress theme tutorial.!!!
    thank you very for your efforts

  • http://www.gateway-studios.net/ Euclides

    Thank you for charing this Joefrey, I needed to do this for a client and it worked perfect! Cheers!

  • Daniel Piechnick

    You’d think they’d build in an easier way to do this.

    Daniel Piechnick

  • http://www.webguide4u.com Vivek Parmar

    Perfect, well explained by breaking into parts. Even though anyone with little knowledge can easily implement it. Thanks for share

  • Jacek Jagiełło

    Thanks for awsonome tutorial! :)
    In day 3, I would like to know how user template can add google font, with a link to this font. Without having to open any template file, using only this simple font management panel.

    • http://wp.tutsplus.com/author/fouad Fouad Matin
      Author

      Well, what you could do is just add all of the Google Webfonts into the options, but I felt that would be unnecessary for just a tutorial.

  • http://www.burceboran.com Burçe

    Is there a possibility to make this user-driven? I want this to be in front-end which users can change the font of the site for their likings and store that choise in a cookie.

    • http://wp.tutsplus.com/author/fouad Fouad Matin
      Author

      Indeed there is. You just add the same type of options form to the footer or wherever you want it, and then instead of changing the options array, you would just set a cookie with the font name. Then in the functions.php file, add a wp_head action that checks if the cookie is set, if it is, add the style snippet.

      Hope I helped.
      Fouad

  • http://www.windkr89.nl Erik

    Thank you, this is very useful. Had a client who has a problem with rendering in Chrome (very strange, I am using even Google fonts). This way, I can let the client choose the fonts, if there’s a problem with one of them. Another good example of the functionality that’s possible with WordPress.

  • http://affanruslan.com Affan Ruslan

    Nah!
    Awesome tutorial. Accidentally found the tutorial here in wp.tutplus. Bookmarked this to be added to my first ever wordpress theme.

  • Pingback: The A to Z of Wordpress Typography - WPKewl!

  • http://youtube.com/izvarzone AntoxaGray

    Do not use cursive as a backup font. Because it will be Comic Sans for the people who disabled js (NoScript plugin for Firefox disables js by default).

  • http://apadong.com/ ARS

    not exactly what I need (input custom font without using any plugins or google webfonts). but, this trick also cool. maybe I’ll implemented this into my next theme. thanks!

  • surferboy

    There was an error :

    Warning: Cannot modify header information – headers already sent by (output started at C:\xampplite\htdocs\wordpress\wp-content\themes\twentyeleven\functions.php:735) in C:\xampplite\htdocs\wordpress\wp-includes\pluggable.php on line 881

    could you help me? I am using wordpress 3.4.1

    Thanks

  • Pingback: How to change fonts in WordPress? | My Tech Blog

  • Ankit Chaudhary

    IS plugin not supported by wordpress 3.5??. I tried to implement on http://www.codemink.com but I got error.

  • http://capstonelouisvillewebdesign.com/ Capstone Creations

    I can not get this to work in IE, is there a synax error I’m not seeing in the tutorial? I copy and pasted as it is into WP 3.5.1