Try Tuts+ Premium, Get Cash Back!
The header.php – What Needs to Go in It and What Doesn’t

The header.php – What Needs to Go in It and What Doesn’t

Tutorial Details
  • Program: WordPress
  • Difficulty: Beginner
  • Estimated Completion Time: 10 minutes

In this tutorial, let’s talk about the header.php, an essential file for any WordPress theme. I’ll show you a nice header file example and give tips about what needs to go in it and what doesn’t.


Step 1: Introduction

The first thing that you need know about the header.php file is your function.

But, we have more than a logo and menu in this file, we also have the head tag and lots of other tags, like: link, script, meta and title.

I’ve written an example header.php file, I’ve tried to create a file as full as possible, but feel free to comment on this tutorial giving tips about the file.

Remember that your header is all content that is shown on all the pages of your site. For example, the logo and menu are shown on all the pages so… both will be added to the header.php

If an element is shown only on a specific page, you need to re-think if this element really must be inside your header.

Let’s work and I hope that you like it!


Step 2: The Final Code

Here you can get the final code to use in your theme. Read the other steps to know exactly what each line does.

First, paste these lines at the top of your functions.php file: (Remember that you need to modify the paths to your CSS and JavaScript files)

define("THEME_DIR", get_template_directory_uri());
/*--- REMOVE GENERATOR META TAG ---*/
remove_action('wp_head', 'wp_generator');

// ENQUEUE STYLES
	
function enqueue_styles() {
	
	/** REGISTER css/screen.css **/
	wp_register_style( 'screen-style', THEME_DIR . '/css_path/screen.css', array(), '1', 'all' );
	wp_enqueue_style( 'screen-style' );
		
}
add_action( 'wp_enqueue_scripts', 'enqueue_styles' );
	
// ENQUEUE SCRIPTS
	
function enqueue_scripts() {
	
	/** REGISTER HTML5 Shim **/
	wp_register_script( 'html5-shim', 'http://html5shim.googlecode.com/svn/trunk/html5.js', array( 'jquery' ), '1', false );
	wp_enqueue_script( 'html5-shim' );
		
	/** REGISTER HTML5 OtherScript.js **/
	wp_register_script( 'custom-script', THEME_DIR . '/js_path/customscript.js', array( 'jquery' ), '1', false );
	wp_enqueue_script( 'custom-script' );
		
}
add_action( 'wp_enqueue_scripts', 'enqueue_scripts' );

Now inside your header.php add these lines: (Remember that you need to modify the paths to your CSS and JavaScript files)

<!doctype html>
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7]> <html class="no-js ie6 oldie" <?php language_attributes(); ?>> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7 oldie" <?php language_attributes(); ?>> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" <?php language_attributes(); ?>> <![endif]-->
<!--[if gt IE 8]><!--> <html <?php language_attributes(); ?>> <!--<![endif]-->
<head>

	<!--=== META TAGS ===-->
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<meta charset="<?php bloginfo( 'charset' ); ?>" />
	<meta name="description" content="Keywords">
	<meta name="author" content="Name">
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
	
	<!--=== LINK TAGS ===-->
	<link rel="shortcut icon" href="<?php echo THEME_DIR; ?>/path/favicon.ico" />
	<link rel="alternate" type="application/rss+xml" title="<?php bloginfo('name'); ?> RSS2 Feed" href="<?php bloginfo('rss2_url'); ?>" />
	<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />

	<!--=== TITLE ===-->	
	<title><?php wp_title(); ?> - <?php bloginfo( 'name' ); ?></title>
	
	<!--=== WP_HEAD() ===-->
	<?php wp_head(); ?>
	 
</head>
<body <?php body_class(); ?>>

<!-- HERE GOES YOUR HEADER MARKUP, LIKE LOGO, MENU, SOCIAL ICONS AND MORE -->

<!-- DON'T FORGET TO CLOSE THE BODY TAG ON footer.php FILE -->

A header “must” have some things, this template that I’ve made does the following (on the next steps I’ll talk about each):

  • Doctypes
  • Conditionals to IE8, 7, 6
  • Meta Tags to ensure that your theme is rendered properly
  • Favicon, RSS and Pingback
  • Title
  • Following official WordPress guidelines, adding scripts and styles with wp_enqueue_script and wp_enqueue_style functions
  • Optimized with the use of constants and removing Meta Generator tag to assist with security
  • Clean and commented code

The steps below will talk about the code used and you’ll learn why to use it.


Step 2: The functions.php File

Let’s begin talking about the functions.php file, we added these lines in the file:

define("THEME_DIR", get_template_directory_uri());
/*--- REMOVE GENERATOR META TAG ---*/
remove_action('wp_head', 'wp_generator');

// ENQUEUE STYLES
	
function enqueue_styles() {
	
	/** REGISTER css/screen.cs **/
	wp_register_style( 'screen-style', THEME_DIR . '/css_path/screen.css', array(), '1', 'all' );
	wp_enqueue_style( 'screen-style' );
		
}
add_action( 'wp_enqueue_scripts', 'enqueue_styles' );
	
// ENQUEUE SCRIPTS
	
function enqueue_scripts() {
	
	/** REGISTER HTML5 Shim **/
	wp_register_script( 'html5-shim', 'http://html5shim.googlecode.com/svn/trunk/html5.js', array( 'jquery' ), '1', false );
	wp_enqueue_script( 'html5-shim' );
		
	/** REGISTER HTML5 OtherScript.js **/
	wp_register_script( 'custom-script', THEME_DIR . '/js_path/customscript.js', array( 'jquery' ), '1', false );
	wp_enqueue_script( 'custom-script' );
		
}
add_action( 'wp_enqueue_scripts', 'enqueue_scripts' );

The first line just creates a constant called THEME_DIR that stores the template directory, we create this constant to optimize the theme, if you look in our header.php file, we need the directory a few times and we use it in functions.php file also to print the theme path. If we call the get_template_directory_uri() all the time, we just create requests. Creating a constant and using it we save server processing, because we call the function once.

/*--- REMOVE GENERATOR META TAG ---*/
remove_action('wp_head', 'wp_generator');

This line removes the Meta Generator Tag, because this tag shows to anyone the WordPress version installed. This kind of information can allow to an invader know the bugs of your version and exploit them.

Adding Your CSS

// ENQUEUE STYLES
	
function enqueue_styles() {
	
	/** REGISTER css/screen.cs **/
	wp_register_style( 'screen-style', THEME_DIR . '/css_path/screen.css', array(), '1', 'all' );
	wp_enqueue_style( 'screen-style' );
		
}
add_action( 'wp_enqueue_scripts', 'enqueue_styles' );

Here, we created a function to add the link tags to header.php. The official WordPress guidelines say that the better way to add styles (.css) and scripts (.js) is with wp_enqueue_script and wp_enqueue_style functions. You can learn more about this in our article, How to Include JavaScript and CSS in Your WordPress Themes and Plugins.

First, we create a function called enqueue_styles and then we call the add_action function, this line says to WordPress that it must call our function when the ‘wp_enqueue_scripts’ event is triggered, which happens during our call to wp_head() in header.php!

Inside our function we have the following lines:

	/** REGISTER css/screen.cs **/
	wp_register_style( 'screen-style', THEME_DIR . '/css_path/screen.css', array(), '1', 'all' );
	wp_enqueue_style( 'screen-style' );

First, we register our stylesheet and then add it to WordPress’ queue.

We use the function wp_register_style to register a style, this function requests the following:

  • #1 Param: A name that you can choose, something like mystyle, mediaqueries
  • #2 Param: The file path, note that we use the THEME_DIR constant here.
  • #3 Param: Here you type the dependencies, the name of style files that need to be loaded before this file.
  • #4 Param: The version.
  • #5 Param: The media attribute for the link tag.

And then, we call the wp_enqueue_style function and we pass as a parameter the name of our style that will be added.

To add more styles to your file, just duplicate these two lines and modify the name, directory and the other parameters.

Adding the Scripts

Now we’ll see the function that adds our scripts.

// ENQUEUE SCRIPTS
	
function enqueue_scripts() {
	
	/** REGISTER HTML5 Shim **/
	wp_register_script( 'html5-shim', 'http://html5shim.googlecode.com/svn/trunk/html5.js', array( 'jquery' ), '1', false );
	wp_enqueue_script( 'html5-shim' );
		
	/** REGISTER HTML5 OtherScript.js **/
	wp_register_script( 'custom-script', THEME_DIR . '/js_path/customscript.js', array( 'jquery' ), '1', false );
	wp_enqueue_script( 'custom-script' );
		
}
add_action( 'wp_enqueue_scripts', 'enqueue_scripts' );

Here the process is the same, the difference here is that we use other functions to add scripts.

To add scripts we use the wp_register_script and wp_enqueue_script functions. The wp_register_script function requires the following:

  • #1 Param: A name that you can choose, something like jquery, dojo, etc.
  • #2 Param: The file directory, note that we use the THEME_DIR constant here.
  • #3 Param: Here you type the dependencies, the name of script files that need be loaded before this file.
  • #4 Param: The version.
  • #5 Param: Here you say if this script will be added in the wp_head() (usually in header.php) or the wp_footer() (usually in footer.php) function calls. If you pass false, it will be loaded on wp_head(). If you pass true, will be loaded on wp_footer()

And then, we call the wp_enqueue_script function and we pass as a parameter the name of our script that will be added.

To add more scripts to your file, just duplicate these two lines and modify the names, directory and the other parameters.


Step 3: The header.php

First, I’ll list here the links to the libraries that you can use on this template, I already uses jQuery and the HTML5 Shim in this template but you can add others.

  • jQuery – library to add nice effects to your theme, I think you probably already know this library, and it’s actually already included in WordPress by default
  • Modernizr – this library allows you to know exactly the features supported by the user’s browser
  • HTML5 Shim – this library allows browsers that don’t have native support for HTML5 markup to start supporting it
  • Respond.js – allows browsers that don’t have native support for CSS3 Media Queries to start supporting it

You can download these libraries and update the paths in your header.php file.

Doctype

In this template we just use the default HTML5 doctype:

<!doctype html>

<html> Tag

<!--[if lt IE 7]> <html class="no-js ie6 oldie" <?php language_attributes(); ?>> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7 oldie" <?php language_attributes(); ?>> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" <?php language_attributes(); ?>> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" <?php language_attributes(); ?>> <!--<![endif]-->

In this part, I used a few IE conditionals to add a class according to the IE version or don’t add nothing if the browser isn’t IE 8 or lower (Firefox, IE9, Chrome and others).

This is really useful because you can create a rule inside your CSS file to affect an object if the browser is IE 7 doing the following:

/* RUNS ON ALL BROWSERS */
#mymenu { 
	width: 400px;
}
/* RUNS ONLY ON IE7 */
.ie7 #mymenu {
	width: 200px;
}

But you can also create a separate CSS file and link it inside the conditionals area, we’ll talk about it in the steps below. The choice is yours.

<meta> Tags

The meta tags are very important because they pass certain information to the browser to ensure the correct rendering of your theme.

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

This line ensures that browsers won’t use Quirks Mode, very useful because this render mode can break the layout.

<meta charset="<?php bloginfo( 'charset' ); ?>" />

This line tells the charset to browser, avoiding unknown characters!

<meta name="description" content="Keywords">
<meta name="author" content="Name">

Just basic meta tags that can help the SEO of your theme. You can add keywords that describe your website and type your name or business’ name.

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

This tag removes/resets any default zoom of a mobile device like iPad and iPhone, very useful if you are working on a responsive layout.

<link> Tags

<link rel="shortcut icon" href="<?php echo THEME_DIR; ?>/path/favicon.ico" />

This adds a favicon to your page, giving a more professional touch to your website.

<link rel="alternate" type="application/rss+xml" title="<?php bloginfo('name'); ?> RSS2 Feed" href="<?php bloginfo('rss2_url'); ?>" />

A link to the RSS Feed of your website.

<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />

A link for the Pingback URL of your site.

<title> Tag

<title><?php wp_title(); ?> - <?php bloginfo( 'name' ); ?></title>

The title tag is very important because it replaces the default title and is useful to improve your rank in search engines.

wp_head()

<?php wp_head(); ?>

This is a very important function, you MUST call this function! Through this function, WordPress adds code from plugins, other JavaScript libraries, and much more.


Conclusion

And it’s done! I really hope that you enjoyed this article and please, feel free to comment about the template and give your code snippet to improve it!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://ourwebmedia.com Kumar Sekhar

    Great post. Informative. Specially the HTML 5 specific responsive header.

  • nigedo

    Good example of current best practice with easy to follow explanations. Thanks!

  • http://www.deluxeblogtips.com Rilwis

    Nice post. I think all WP users should follow this practice: using wp_enqueue_scripts hook to register JS and CSS files. I like the idea of enqueuing theme CSS file, it’s cool!

    And in addition, I’ve written a post about better way to display title meta tag, which is also helpful in this topic.

  • http://tommcfarlin.com Tom McFarlin

    Hey Rafeal – nice tutorial! There are a couple of things in the code that, although they work, aren’t up to WordPress best practices:

    Rather than using THEME_DIR, use get_template_directory_uri(). It’s a bad practice to use global constants and using the template directory function ensures that your theme will properly support child themes.

    I’d make a case that you don’t need an IE6 conditional. WordPress no longer supports IE6 so building sites that target that browser on a platform that doesn’t support seems like it’s creating more work than it’s worth.

    Custom functions, such as enqueue_scripts, should be prefixed with the theme name. For example, if you have a theme named “Envato Theme,” it’s a good idea to name the fucntion envato_enqueue_scripts. This gives a clearer indication of what the function does and it’s named so specific that it’d be more difficult to overwrite it in future development.

    Other than that, good stuff – keep it up!

    • http://www.mojowill.com theMojoWill

      I was just about to add this comment regarding using a constant instead of just using the very useful built in WordPress functions!

      • http://www.gjakovljevic.com Goran

        I think that he is defining constant to lower the number of requests. Anyway, looks nice, will read it tonight

        • http://paspar2.com Ihor Vorotnov

          You have a typo in comment in your first code block:

          9. /** REGISTER css/screen.cs **/ – must be css/screen.css

          Of course, it does no effect but should be fixed.

          And you have completely wrong understanding of this line:

          It has nothing to do with quirks mode, it forces IE to use Google Chrome Frame if it’s installed. And it does NOT asks user to install this frame, just forces to use it if it’s already installed which is usually not. If you are creating a separate optimized styles for old IEs then you don’t need it at all. But if you write your code for newer versions and completely ignoring older versions then you can use this tag and additional Google Chrome Frame script which will detect older browser and prompt user to install GCF.

    • http://wp.envato.com/ Japh Thomson
      Staff

      Great feedback, thanks Tom! :)

      I understand that it’s best practice to use get_template_directory_uri(), however, using the constant appears to save on database queries. Am I misunderstanding something there?

      • http://profiles.wordpress.org/stephenh1988/ Stephen Harris

        Constants can change from version to version, albeit unlikely. Using constants also means none of the filters get applied. In any case, the database query is real quick – you wouldn’t notice the difference.

      • http://www.damiencarbery.com Damien Carbery

        I think that Tom McFarlin has misinterpreted or misread the use of THEME_DIR and others have perpetuated that – having said that, Rafael may have updated the article to clarify the definition and use of THEME_DIR.

        @Goran and @Japh are right – THEME_DIR is defined to reduce database requests (and function calls).
        @Stephen Harris: THEME_DIR is defined in this header.php file, it is not connected to a WordPress version.

        Good article.

        • http://tommcfarlin.com Tom McFarlin

          Indeed, you’re right – I missed while reading through the article for the first time! Sticking the value returned from that function make sense.

          My bad on the misunderstanding :).

        • http://kovshenin.com Konstantin Kovshenin

          Reduce database calls, what are you talking about? The get_template_directory_uri() will only call the database one since all calls to get_option() are cached for the whole request, or longer if a persistent caching plugin is enabled. Not only the use of the constant makes absolutely no sense, it also has two problems. It’s called “THEME_DIR”, what if your child theme defines the same constant? Boom! Clash! Errors oh no!

          Another problem is that many developers will think the “THEME_DIR” constant is the theme directory path returned by get_template_directory() and not the URI. This is confusing and people will have to constantly scroll back and forth through your code (or switch through your pile of files) to understand that. The use of get_template_directory_uri() in each case would have been much more obvious.

          Also, Tom said “WordPress no longer supports IE6″, this is not true. WordPress dropped support for IE6 inside the admin panel, but the front-end browser support remains up to the theme developer. You can support IE5 if you want.

          I’m sure there are other problems with the article but I don’t have time to give you a full review. Cheers.

          ~ Konstantin

      • Amanda

        What about when you are using a theme for a specific site and not packaging it up for general distribution?

        For example, when I am “optimising” a final WP install, I will remove most of the bloginfo(”) calls and hard code those instead, since the blog name/description, etc are not going to be changing. Is it still best practice to use get_template_directory_uri()? I don’t normally define a global in the functions file the way the author does – I usually just assign get_template_directory_uri() to a variable at the top of files like header.php and use the variable instead…

        Thanks in advance for your opinions…

    • http://kevinjohngallagher.com Kevinjohn Gallagher

      ” WordPress no longer supports IE6 “

      Total and utter nonsense!! Your WordPress theme can support any browser you want it to.
      The WordPress ADMIN AREA no longer supports IE6.

      But lets not let the facts get in the way of writing comments.

      • http://wp.envato.com/ Japh Thomson
        Staff

        Good point, Kevinjohn! But, let’s not forget you can also make good points while still maintaining a friendly disposition ;)

  • http://www.ellahworks.com Rowela Alzona

    Again, what a wonderful and useful piece of information… Nice post, keep it up!

  • http://www.web-actually.fr William

    Thanks Rafael for this detailed tuto,

    Shouldn’t be better a better idea to call the customscript file on the wp_footer() ?

  • Luca Rosaldi

    Just one thing to point out: HTML5shim is included with the last version of Modernizr, so don’t include both.

  • Albert

    Great!! just… upload souce files, please!!!

  • Jesse

    Great post. I really enjoyed the HTML5 scripts and IE conditionals.

  • Pete

    Sorry if this is a stupid question, I’m new to WP but why is it of any use a link to the RSS feed in the head instead of an anchor in the body where the user can save or click, or is this for something else?

    <link rel="alternate" type="application/rss+xml" title=" RSS2 Feed” href=”" />

    • http://wp.envato.com/ Japh Thomson
      Staff

      Hi Pete, good question: the <link> for the RSS feed in the <head> is not really for humans. It allows browsers and RSS readers to easily detect the correct feed to use to subscribe to your blog.

  • http://www.sanjaykhemlani.com/how-create-accordion-design-photoshop/ sanjay

    Nice! I hope there’s more of post like this one, looking forward to best practices and stuff :)

  • Pingback: Starter Guide On Header.php

  • Pingback: WPTavern: Starter Guide On Header.php | WordPress Planet

  • begs

    Thanks for the infos.

    Found a small typo:
    “Step 2: The function.php File”
    has to be
    “Step 2: The functions.php File”

    • http://wp.envato.com/ Japh Thomson
      Staff

      Oops! I missed that, thanks Begs, all fixed

  • Pingback: HostNine Weekly Round-Up: March 19-23 | HostNine Company Blog

  • http://www.wpbeginner.com Syed Balkhi

    Just wanted to point out that removing wp_generator only removes the version number from the header. Someone can easily go in your site’s feed and find the version number. Or they can simply access the readme file.

    So you have to delete that readme file. Then you have to filter the_generator tag rather than removing wp_generator.

    Also not sure if showing no WP version really helps that much. If the hacker wants to hack, they will find ways.

    • http://kovshenin.com Konstantin Kovshenin

      In addition to that (meta generator tag, rss feed generator tag) there’s also: 1. readme.html in your root directory exposing your WordPress version, and 2. an XML-RPC call to your endpoint can also reveal your version. However, hiding all that is stupid, because an experienced WordPress developer will always find out you’re using WordPress — there are billions of ways, from looking through your plugin readme.txt files, to trying different combinations of query vars :)

      ~ K

  • http://sevenroots.com Tiyo Kamtiyono

    Thanks a lot, this post is helpful to make all the things before body tag simpler and cleaner. :)

  • Pingback: Tweet-Parade (no.12 Mar 2012) | gonzoblog.nl

  • http://psawyer.co.uk Peter Sawyer

    Don’t want to sound thick but I thought description and keywords were two different things rather than combined.

    Your meta:

    What I thought:

    • http://wp.envato.com/ Japh Thomson
      Staff

      Hi Peter, thanks for your comment! Unfortunately it looks like your code examples got eaten. Don’t forget to wrap any code in your comment as described below the comment box.

      i.e. like this: <pre name=”code” class=”html”>your code here, html like this &lt;tag&gt;</pre>

      • http://psawyer.co.uk Peter Sawyer

        Hmmm did try and wrap the tags before…..basically my point was that I though that the two meta fields description and keywords were two different things rather than combined.

        Your example:
        meta name=”description” content=”Keywords”

        What I thought:
        meta name=”description” content=”description”
        meta name=”keywords” content=”Keywords”

        Removed the tags.

  • Kay

    I love this! Will you be creating a series of posts on the other WordPress php files, too?

  • http://themeid.com Emil

    27 comments here and none of you fellas notice this?

    /** REGISTER HTML5 OtherScript.js **/
    wp_register_script( ‘custom-script’, THEME_DIR . ‘/js_path/customscript.js’, array( ‘jquery’ ), ’1′, false );
    wp_enqueue_script( ‘custom-script’ );

    doing_it_wrong is wp_register_script there’s no need to register anything, wp_enqueue_script is enough.

    function my_custom_script() {
    wp_enqueue_script( ‘custom-scripts’, get_template_directory_uri() . ‘/js/custom-scripts.js’, ‘jquery’, ’1.0′, false );
    }
    add_action( ‘wp_enqueue_scripts’, ‘my_custom_script’ );

    Almost everything above is registering, there’s no need to register anything and it hasn’t been for a long time. wp_enqueue_script will do the trick and it works just fine.

    Same thing with styles, it should not be registered it always must be enqueued period.

    Cheers,
    Emil

    • http://kovshenin.com Konstantin Kovshenin

      Good point Emil! Also worth pointing out that enqueuing scripts inside header.php right before the call to wp_head is not a mistake. It’s actually a good idea because one would be expecting to see references to scripts and stylesheets in your <head> section. Twenty (T|Elev)en themes are good examples.

      ~ K

      • http://themeid.com Emil

        Absolutely that’s what I got in my Theme:

        <?php wp_enqueue_style(‘responsive-style’, get_stylesheet_uri(), false, ’1.2.0′);?>

        How’s the coolest job at Automattic so far?

        Emil

    • http://shabushabu.eu Boris

      While wp_register_script is redundant in this case it’s definitely not wrong doing it. If you have a look at the function it states that you’re only doing it wrong if you register it before the init hook. In fact, there are some great use-cases for using it. Say you have a shortcode that requires a JS file. You obviously don’t want to load that file on every page load, so you register it on the init hook, so that it’s always available. Then, in a static class, you check for the shortcode and if it’s there then you use wp_print_scripts to output the JS file in the footer.

      I’ve never registered a stylesheet, I think, and can’t think of why you’d do it but stating that it always must be enqeued rather than registered is just plain wrong, mate.

      • GaryJ

        wp_enqueue_script first registers the script if it isn’t already registered. Stick with that.

        The only scenario where you’d register, but not enqueue, is if you were making a script available for a plugin to conditionally load it, or have some set up where there theme would register and only conditionally enqueue it itself, perhaps depending on some combination of features.

        • http://shabushabu.eu Boris

          You basically just repeated my use-case, mate. Here’s another. I have a fairly large plugin that consists of various components that can be turned on or off. Several components use JS files from the base component, so rather than having to write the source, etc again I can just use the handle, cause I know it’s already been registered and localized.

          Anyways, my point was that categorically stating that you must not use wp_register_script or wp_register_style is wrong.

      • http://themeid.com Emil

        Not to be a huge pest, however wp_print_scripts is also not the practice either. Instead of explaining why here’s what Andrew Nacin of WordPress has to say about it.:

        Use wp_enqueue_scripts, not wp_print_styles, to enqueue scripts and styles for the frontend

        If you are enqueueing scripts and styles, you will want to use one of these three hooks:

        - wp_enqueue_scripts (for the frontend)
        - login_enqueue_scripts (for the login screen)
        - admin_enqueue_scripts (for the admin dashboard)

        Don’t let the names fool you — they are for both scripts and styles. We’ll probably add equivalent *_enqueue_styles hooks in 3.4 just to make it more obvious, but these hooks have all existed for some time now.

        A possible incompatibility with WordPress 3.3 could arise if you are using the wp_print_styles hook to enqueue styles — your styles may end up in the admin.

        The fix: Use wp_enqueue_scripts instead. Yes, it’s that easy.

        Edit: Yes, the same goes for registering styles. Registering or enqueueing (styles or scripts) should occur on *_enqueue_scripts.

        and here is the original link to this:
        http://wpdevel.wordpress.com/2011/12/12/use-wp_enqueue_scripts-not-wp_print_styles-to-enqueue-scripts-and-styles-for-the-frontend/

        • http://shabushabu.eu Boris

          I wasn’t advertising to use of wp_print_scripts instead of wp_enqueue_scripts, which you should’ve realised if you read my responses properly. I was however pointing out that in the way of conditionally loading JS files based on the existence of a shortcode or widget, wp_print_scripts() (the function, not the hook) is the only proper solution I know of. But enlighten me, if you know of any other solution. Anyways, I agree with you that where appropriate (most cases, anyways) wp_enqueue_script/-style should be used. There are however scenarios, like the one I pointed out, where you want to use something different, so you shouldn’t state that you must use wp_enqueue_script/-style exclusively. It just adds to the confusion some people already experience.

    • Harold

      I also agree that it is not good to be loading PHP for every style sheet. If you load one PHP page with two dyainmc’ style sheets, that’s 3 PHP calls for every loaded page, for every visitor. That will add up real quick if/when your website starts to pull traffic.The best thing to do is leave the stylesheets static. If you need to add dyainmc style information, include it in the actual web page in style tags.cigraphics is on the right track for re-generating static style sheets when changes are made to the website, but then you have to worry about browsers caching their CSS sheets because they are expected to be static. I know there are workarounds for that, but why worry about it? Just include any dyainmc content in the main web page.

  • Agnel Waghela

    Does anyone knows about ‘basket.js’ http://addyosmani.github.com/basket.js/ “A simple (proof-of-concept) script loader that caches scripts with localStorage”
    i’m thinking of integrating this with my theme development…wouldn’t this be useful….

    Any suggestions?

  • Pingback: What Needs to Go in the Header.php file and and What Doesn’t | WPbase

  • GaryJ

    In addition to the constant and register / enqueue coding issues others have picked up, there’s also:

    - a lack of WP code standards consistency in the first few PHP lines.
    - inconsistent closing slash on some meta tags (which, along with the uncapitalised “doctype” means the source won’t be a polyglot document).
    - some awful looking HTML comments that group meta / link / other elements which are totally un-necessary as we can clearly see they are meta / link / other elements and so do nothing apart from push actual content further down the source.
    - absolutely no formal phpDoc DocBlocks for the functions – documenting the code properly and verbosely means that someone hasn’t got to find and refer to this article when they can’t remember what something they’ve copied and pasted actually does.
    - completely incorrect explanation for the X-UA-Compatible meta tag.
    - a reference to the HTML5shim, which is currently versioned at pre3.5, yet the code here enqueues it with version ’1′.
    - a instruction to paste the PHP lines to the top of the functions.php file, which will cause errors for those who blindly follow it since it doesn’t include a leading <?php.

  • http://www.lotusmarketing.ca Lotus Marketing

    erm, I did’nt even know about HTML5SHIM.. that plugin looks great for compatibility for our customers using older browsers… you can’t ignore them.

    how good is it?

  • Sebastian Green

    Great post, but why do you add the pingback and rss links? Does WordPress not add these automatically?

  • Pingback: The header.php – What Needs to Go in It and What Doesn’t | Shadowtek | Hosting and Design Solutions

  • Pingback: Wordpress | Pearltrees

  • http://www.itoctopus.com itoctopus

    I’ve seen the header.php file being used and abused by so many developers out there. There were many header.php files out there that contain a lot of business logic – which is wrong…

  • Gavin

    Hi

    New to all this and this is a first for me dealing with the header this way.

    I’ve got a question though. I read that in Param #4 if I change the false value to true then it should place my scripts in the footer.php. but this is not happening at all. is there something I’m doing wrong here?

    Do I need to add some type of code to my footer.php in order for this to work?

    thanks a mil

    • http://wp.envato.com/ Japh Thomson
      Staff

      Hi Gavin, yes you need to have <?php wp_footer(); ?> in your footer.php file.

      I hope that helps :)

  • Pingback: My Stream | Best of Tuts+ in March 2012 | My Stream

  • Pingback: Best of Tuts+ in March 2012 - Milk-Break

  • Pingback: Best of Tuts+ in March 2012 | CS5 Design

  • Pingback: Best of Tuts+ in March 2012 | DigitalMofo

  • Pingback: Best of Tuts+ in March 2012 | Clixto7

  • Pingback: Best of Tuts+ in March 2012 | cssWOW Showcase | Css Gallery | Css Awards | Design Inspiration Tutorials

  • Pingback: Best of Tuts+ in March 2012 | linuxin.ro

  • Pingback: Best of Tuts+ in March 2012 | Shadowtek Hosting and Design Solutions

  • Pingback: Best of Tuts+ in March 2012 | PHP Developer Resource

  • Mj

    Useful article ;) just a question , how can i just print styles in header, using wp_head?
    i want to print styles in footer.

    cheers

  • Gerrit Kuilder

    http://codex.wordpress.org/Function_Reference/get_stylesheet_directory_uri should be used if you want to make the header child theme friendly…

  • Pingback: Файл темы header.php — тонкости настройки | Wordpresso

  • http://philoharvey.com/ SuperPhil

    Thanks for this very informative tutorial, it is just the way a tut should be. The complete notated code proved and detailed description of each step. Awesome! Also do you have similar posts for each of the different WordPress templates?

  • http://yacobi.eu yacobi

    hello,
    cool but how can I add html5.js only to IE>9?

  • http://www.yacobi.eu yacobi

    sorry, i shoud have written IE<9 obviously

  • http://webmaster.ypsa.org Shakir

    Thanks, Very useful for the professional theme developer. All rules were maintained.

  • romuloctba

    dude… that was amazing. thank you

  • Koen Poelhekke

    Great tutorial! Thanks a lot

  • al mamun

    whats a nice entry……..

  • http://www.jernejsila.com/zapisi Jernej

    I was looking for something like that! Thanks

  • fred

    I HAVE A GREAT QUESTION : HOW TO REMOVE META TAGS (og:title, og:description, og:image) in WordPress 3.5 ??? I want to clean my head and create it, but i dont know how to remove these meta tags. If someone have the answer, please help :) Fred

  • Pingback: Deborah’s Weekly Links: March 25, 2012

  • http://www.facebook.com/mittul.chauhan Mittul Chauhan

    nice tipz ./.

  • Pingback: Best of Tuts+ in March 2012 | Envato Notes