Custom Page Templates – Calling An External CSS File

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.

37 responses on “Custom Page Templates – Calling An External CSS File

  1. Sarah@Home Teeth Witening

    Great post on custom page templates in wordpress I do this all the time with an iframe plugin to embed amazon astores on a page… although i’m a little less elegant about it.. i just edit the page.php source to take out the call for the sidebar then change the post content width for the page content in the css.. it may not be pretty but it works for what I need as I’m not adding a lot of “pages”. I’ll try your solution on my next setup.

  2. Chelle@Gas Grilling Tips

    I have been lucky and not need to change the header! I’ve used page templates mostly for making pages for search results and cutting out sidebars, which is slightly easier for a wordpress dummy like myself. :)

  3. felix@Hectic Capiznon Bloggers 2009

    Glad that you made a new post and this customizing WP page tips is really very useful but I need to get over with the code again and again so that I could understand it well. I will just ask you later if I really can’t go with this code. Thanks for this.

  4. Reisefreak

    I have been lucky and not need to change the header! I’ve used page templates mostly for making pages for search results and cutting out sidebars, which is slightly easier for a wordpress dummy like myself.

  5. steve@Debt Settlement Program

    Great post really detailed I have had so many problems dealing with CSS files you have no idea lol

  6. Khaled@van leasing

    If you are going to use this statement:

    # ID == 7830) {
    # echo ”;
    # }
    # ?>

    where would you add the id on the template and what would the code be.
    Cheers

  7. anraiki@devigner

    I didn’t know about the “add_action” function that WordPress had. But, it is good to know that I can now call the header without making a 2nd header file for a different template.

    A good example using custom template is to adjust one template for “Google Adsense”. Theres no choice in doing it, and in my opinion, better than using a premade template by Google.

  8. The Nooge@Unsigned Musician Radio

    I’m going to be honest here, those CSS files make me want to punch someone in the face…

    I’m not exactly trained in any form of programming, but with our tech guy being taken off our website from time to time it’s kind of left up to me to update/make changes…and CSS gives me hell…

    And after reading over your post…i’m still lost…which is par for the course!

  9. felix@sulumits retsambew

    I actually make use of this solution on my new web site I build. All of your tips are really coming all in handy. Thanks.

  10. Brandon@The Richest Man On Earth

    Great stuff , i’ve been learning css as of recently so this helped with answering a few things i haven’t been able to figure out.

  11. Paul@Gazebo Hire

    Thanks for the clear instructiong. I’m just about to start on a brand new WP based site and have been looking for good ways of ‘individualising’ pages.

    I assume you weren’t happy with the plugins out there? (which I’ve not looked at yet)

  12. Luke@Corner Sofas

    OK, that solution is quite beautiful from a coding point of view. I would have gone for the IF approach in the header.php since I didn’t know any other way.

    So I guess add_action has many other uses?

    BTW, the comment before this one shows April 21 as the date, but today is only the 20th.

  13. Andrej @ sports footwear

    It’s really important that people avoid inlince CSS wherever it’s possible. I begin to realise this more and more since I’ve started working in SEO.

  14. Print Matt

    Thanks for posting these solution. I can now add some business card templates to my blog. Though I’m a mediocre at programming, I think I can work on this by trial and error. :)

  15. Uitvaart Verzekeren

    I wish I had read this post some weeks before, because I just did “Rejected Solution 1 – Don’t Use Header.php” to my website ;(

  16. Terry@ Lab Coat

    T_T I love working with codes but I don’t think I can master anything. The things you can do with CSS are truly great but woe is me who can’t make it work for me. T_T

  17. Susan@Frisco Tx Homes For Sale

    I am not very good with codes, however after following your detailed blog, I think I will give it a go. Thank you for the help and I will give it a try, I am sure it will not look good.

  18. Jimmy @ stock charts

    Definately Increases productivity, lots of websites use the same element , no use recreating the wheeeeel!

  19. Nick@Advanced SEO

    I had a few things that i wanted to change on my wp blog template. i could not figure out how. you shined some light on what i need to do

    thankyou

  20. Kasper@seo og webdesign

    Just started playing around with wordpress and study the possibilites.
    I see this blog is a nice ressource for me :)

    At least now i wont have trouble with CSS in WP, thanks :)

  21. Anna@Diety

    I can’t make heads or tails out of it, but i showed this post to my “webmaster” (my bf;)) and he said it’ll come in handy, so thank you :)

  22. sid@typeofattorney.com

    I am sort of new to the wordpress world and information like this really helps. The more i work with wordpress the more i like it, great platform.

  23. Daniel Affordable Housing

    I currently have a navigation menu on every page of a 30 page site. At the moment, it is a hassle when I want to change the menu because I have to alter every page.

  24. Rob@Online Poker Rakeback

    Here’s to hoping I came to the right place for help. I tried the WordPress forums, but to be frank they are pretty poorly organized and it’s hard to find specifically what I’m looking for.

    I’m very new to programming. In fact I’ve got very little knowledge of it. I’ve made some minor modifications to my WordPress blog as well as quite a few mods to the phpBB forum.

    Anyhow, I like the basic layout of your blog and was wondering if you (or anyone here) might be able to help me out with a similar design.
    Here’s what I’d like to do:

    1. I would like to to have more room on the side for the ads.
    2. If possible, I’d like to put ads on the left on the blog content on the right.
    3. I would like to include the same ads on every page of my blog, not just the main page where all of the latest blogs are listed.

    Any help would be greatly appreciated. I’ve got you bookmarked and will check back often, as well as browse your other posts to see if I can stumble upon some answers.

    Thank a million.

    1. Rob@Free Poker Tournaments

      Hey, just wanted to give a quick update. I actually found a theme that suits all of the above needs I listed. I guess just talking it through led me to a solution. Thanks for giving me a sounding board!

  25. train horn

    I kinda don’t like working on codes but this will be an exception. It is very a helpful post for people like me. Very clear and detailed. It was easy to understand. :D be back for more.

  26. lee@speed training

    You certainly are giving your visitors a lot of precious info. External CSS file is the solution that I’ve been looking for. Great tutorial! Applying this to my theme right now – can finally finish and get it published. Thank you

  27. Charles Wong

    It is very useful for me. I visit your jobs listing China webstie. It is very interesting. if you need more job info in China, maybe I could help you.

  28. Stephen Cronin Post author

    Hi All,

    I noticed a problem here (thanks Ken).

    The last two examples were using bloginfo rather than get_bloginfo which is needed if we are using Echo. The code should work now.

  29. MegoScott

    I have been looking FOREVER for someone to explain how to do custom css on custom page templates. So many unreliable plugins and crap solutions. I’m so pleased at how well this is working. Why isn’t it in the freaking codex? Thanks!

  30. Jaime

    I am very new to WordPress. I think this is my solution. I need help with where to add it.
    Where do I put this code? Inside the header.php? Where exactly inside the header.php?
    I need to add an external css stylesheet so it can style the html inside my post “Text” section.

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>

Anti-Spam Quiz: