Custom Page Templates – Calling An External CSS File

March 30th, 2009 by Stephen Cronin (Please wait) [Shortlink]

Note: Not long after writing this post, I discovered that the best way to load external CSS files is by using the wp_enqueue_style function. Similarly, the best way to load JavaScript files is by using the wp_enqueue_script function. The method outlined below is not necessary – although it may still be useful for other things to be added to the head section.

Custom page templates are a powerful feature of WordPress that can be used to make pages (not posts) do something different from normal. You can make them do pretty much anything. Obviously, this can greatly increase the flexibility of your site.

Amongst other things, I’ve used custom page templates to create a basic photo wall and a dynamic listing of jobs in China.

However, because of the way most WordPress themes are created, calling an external CSS file from a custom page template is not straightforward. Here, I explain the problem, look at the options and explain how to use ‘plugin functionality’ to overcome the problem.

Creating Custom Page Templates

Much has been written about creating custom page templates, so I won’t cover it in detail here. Briefly, you need to do the following:

  1. Create a php file in your theme directory, containing the functionality you want (I normally start with an existing template and modify it).
  2. Ensure there is a comment at the top of the file, so WordPress knows it’s a template. For example (and don’t forget to change the name):
    <?php
    /*
    Template Name: My Page
    */
    ?>
    
  3. In the Admin panel, edit the page you want to use the custom template with and set the Template field to the template you created.

That’s it in a nutshell. For more detailed instructions, please see:

Calling An External CSS File

There may be times when you want to include something in the head section of the HTML document. The most obvious example is a call to an external CSS file to provide custom styling for the page.

Adding the style information to the main CSS file would add unnecessary weight to every page / post, when it’s only needed on one page. Inline CSS should be avoided where possible. So the best solution is an external CSS file that is called only for that page (ie called by the custom page template).

This article focuses on calling an external CSS file, but it also applies to anything that you want to add to the head section of the HTML document, such as calling a JavaScript file or adding a meta tag, etc.

The Problem With Adding Items To The HTML Head

It sounds simple enough: I just call the CSS file from the custom page template, right? Right in theory, but in practice you can’t easily do this because of the way most WordPress themes are designed.

The external CSS file must be called from the head section of the HTML document. In most WordPress themes, the entire head section is contained in the header.php file. This is normally called from the custom page template using the get_header() function in the following manner:

<?php
/*
Template Name: My Page
*/
?>
<?php get_header(); ?>

This calls header.php, which will probably have a variation on the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
<title><?php bloginfo('name'); ?> <?php if ( is_single() ) { ?> ยป Blog Archive <?php } ?> <?php wp_title(); ?></title>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
<link rel="shortcut icon" href="<?php bloginfo('stylesheet_directory'); ?>/images/favicon.ico" />
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
<?php wp_head(); ?>
</head>
<body>
<div id="page">
<div id="header">
	<div id="headerimg">
		<h1><a href="<?php echo get_option('home'); ?>/"><?php bloginfo('name'); ?></a></h1>
		<div class="description"><?php bloginfo('description'); ?></div>
	</div>
</div>
<hr />

If you try to call the CSS file before the get_header() function, for example:

<?php
/*
Template Name: My Page
*/
?>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_directory'); ?>/includes/mypage.css" type="text/css" media="screen" />
<?php get_header(); ?>

then the additional code will appear BEFORE the code in header.php. In the case above, it will appear before the DOCTYPE line, which is obviously no good.

If you try to call the CSS file after the get_header() function, then the additional code will appear after the code in header.php. In the case above, it will appear after <hr />, which is in the body of the HTML document and also no good.

There are several solutions to this problem.

Rejected Solution 1 – Don’t Use Header.php

One possible solution is to copy and paste the code from header.php into the custom template, instead of calling it via get_header(). You can then easily edit the code to add the call to the external file. Great!

The problem is that if you ever change header.php, you’ll have to remember to come back and change the equivalent code in the custom page template. That’s messy (and the chances are you’ll forget).

Rejected Solution 2 – Edit Header.php

Another possible solution is to edit header.php and use a conditional statement to only include the CSS file on the page in question. For example, if we only wanted to use the custom template on the page with an ID of 7830 we could add the following to header.php:

<?php
if ($post->ID == 7830) {
	echo '<link rel="stylesheet" href="'.get_bloginfo('stylesheet_directory').'/includes/mypage.css" type="text/css" media="screen" />';
}
?>

This would only call the external CSS file for the page with the specified ID. Note that the IF condition can be adapted to our needs. If we wanted to call the same external stylesheet for multiple pages, we could check for the existence of a custom field, or perhaps a certain tag, etc. The possibilities are endless.

The problem with this solution is that it’s messy. What if you plan to use multiple custom page templates and want a different stylesheet for each one? Your header.php will be filled with conditionals. It’s far better to find a solution where you can call the external CSS file from the custom page template.

My Solution – Add_action Function With Wp_head Hook

Although I’m starting to play with WordPress themes, my background is in WordPress plugins. If I wanted to call an external CCS file from a plugin, I’d use the add_action function with the wp_head hook. There’s really no difference between plugins and themes when using WordPress functions, so this technique works just as well in a custom page template.

Here’s how to do it:

<?php
function mypage_head() {
	echo '<link rel="stylesheet" type="text/css" href="'.get_bloginfo('stylesheet_directory').'/includes/mypage.css">'."\n";
}
add_action('wp_head', 'mypage_head');
?>
<?php get_header(); ?>

First, we define a simple function called mypage_head that echos the HTML code calling the external stylesheet. That’s all it does. Of course, you could echo anything here, such as a call to a JavaScript file, a meta tag, etc.

Next, we use the add_action function, with the wp_head hook, to call the mypage_head function. This tells WordPress to run our function whenever the wp_head function is called (this is called by your header.php).

Lastly, we call header.php using the get_header function. This calls wp_head and WordPress remembers to the mypage_head function and your code is added.

It’s not messy, because all the code is in the custom page template. You can leave header.php as it is. But it doesn’t require you to remember to change code if you change header.php, because you’re re-using header.php.

Final Thoughts

That’s my solution: to use the add_action fuction to add something to the header. What do you use? I know there are other solutions out there (including plugins), so I’d be interested in hearing what you do.

Like this article? Plus One it!

Tags: , ,

There are 35 reponses to this article. Visit the comments page.

Leave a Reply

Anti-Spam Quiz:


Stephen Cronin

is Manager of Online Service Delivery at a Queensland Government department & has been a freelance WordPress developer/consultant since 2007
*Content on this site is my own and is not related to my employer

Hire me - I'm expensive, but I'm very good!

WordPress Plugins

Want a Custom WordPress plugin? See my Services page.

Greasemonkey Scripts

Visit my home page at Userscripts.org.