Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

All right, so we're probably all familiar with the typical way to ensure that your main CSS file is refreshed when you load the page (busting the browser cache), right?

<link rel="stylesheet" type="text/css" media="all"
  href="<?php echo get_stylesheet_uri();
    echo '?'.filemtime( get_stylesheet_directory() . '/style.css'); ?>" />

I need to do the same thing on another CSS file. Yes, my style.css file has its own set of @import "css/myFile.css" which are working fine, but humor me, if you will. So, back to header.php, right after that first link, and before the call to wp_head():

<?php $cssFile = get_stylesheet_directory_uri().'/css/other.css'; ?>
<link rel="stylesheet" type="text/css" media="all"
  href="<?php echo $cssFile; echo '?'.filemtime($cssFile); ?>" />

And this leads to a warning (as part of the href attribute of the link when the browser gets the page):

Warning: filemtime(): stat failed for http://localhost/wordpress/wp-content/themes/my_theme/css/other.css

the path to the file seems to be built correctly (and the other.css file is there), but filemtime (stat, actually) fails on it. How come?

Other recommended ways to include the 'latest' version of a CSS file other than style.css? Should I go with wp_register_style instead? If so... how can I tell wp_register_style to bust the browser cache (ie: get me the latest version of the css file, even if the browser has it cached)? Thanks in advance

share|improve this question

6 Answers 6

up vote 5 down vote accepted

You're using the file's path in the first call, but its URL in the second. So it won't work.

share|improve this answer
    
Thank you. Changing get_stylesheet_directory_uri() to get_stylesheet_directory() in the second call seems to have been the right move! –  FOR Dec 10 '10 at 3:44

I tend to just enqueue the main stylesheet using wp_enqueue_style, and append something to the version when i want to prevent caching..

$ver = '';
wp_enqueue_style( 'theme_style', get_bloginfo('stylesheet_url'), false, $ver );

When i want to stop caching i update $ver to something that will constantly change, such as the time..

$ver = time();

Or something similar..

share|improve this answer
    
Thanks for the tip on using the $ver argument - didn't realize it could be used like that. –  FOR Dec 10 '10 at 3:46
    
It was an assumption that caching is done based on the version number but it seemed like an easy solution to be using an enqueue and to alternate the version number as appropriate, plus it seems to work just fine... :) –  t31os Dec 10 '10 at 15:05

Here is the code I have from an unreleased CDN plugin I have. It will automatically replace the ver query_var that the enqueue functions use with the file time:

class CDN_VersionAssets {

    private $default_version = '';
    private $root_url;

    public function __construct() {
        $this->root_url = site_url();
    }

    public function initialize() {
        add_filter('style_loader_src', array($this, 'replace_version'), 10);
        add_filter('script_loader_src', array($this, 'replace_version'), 10);
        add_filter('stylesheet_uri', array($this, 'replace_version'), 10);
    }

    public function on_template_redirect() {
        $this->default_version = @filemtime(get_stylesheet_directory().'/style.css');
    }

    private function get_version($url) {
        if(0 === strpos($url, $this->root_url)) {
            $parts = parse_url($url);
            $file_path = str_replace(site_url('/'), ABSPATH, $parts['scheme'].'://'.$parts['host'].$parts['path']);
            if( !($version = @filemtime($file_path)) ) {
                $version = $this->default_version;
            }
            return $version;
        }
        return false;
    }

    public function replace_version($src) {
        if( $new_version = $this->get_version($src) ) {
            return add_query_arg('ver', $new_version, $src);
        }
        return $src;
    }
}
add_action('init', array(new CDN_VersionAssets(), 'initialize'));
share|improve this answer
    
Impressive! Thanks for sharing. I've picked Denis answer because he was right on target with what I was doing wrong - but I'm voting your up as well because it may be quite useful in more general terms! –  FOR Dec 10 '10 at 3:45

If you'd prefer not to use the standard style.css file for your WordPress theme's CSS cache-busting technique, here's a complete working code example:

<?php
    // Prevent CSS Caching
    $css_link = get_stylesheet_directory_uri() . '/css/screen.css';
    $css_file = get_stylesheet_directory() . '/css/screen.css';
?>

<link href="<?php echo $css_link . '?' . filemtime( $css_file ); ?>" />

Would result in the following HTML output:

<link href="http://example.com/wp-content/themes/theme-name/css/screen.css?1349389530" />

For terseness of this example, I excluded rel="stylesheet" type="text/css" on the <link> element, so be sure to add those attributes to your final markup.

share|improve this answer

I wrote my own little function as a plugin for jobs like this. It take two paramters, the path that will need to be appended and a date format. Here is a sample usage...

<?php echo cache_busting_path('/css/reset.css', 'Y-m-d_g:i:s'); ?>

which would result in http://pewsocialtrends.org/wp-content/themes/pew-socialtrends/css/reset.css?2010-11-11_6:47:45

Here is the code:

    <?php
/*
        Plugin Name: Cache Busting Path
        Description: Function that returns a path with a cache-busting query string based on the last time the file was updated.
        Version: 1.0
        Author: Russell Heimlich
        Author URI: http://www.russellheimlich.com/blog/
        License: GPL2
    */

        function cache_busting_path($path, $time_format = 'U') {
            if( $path[0] != '/' ) { //Checks for the first character in $path is a slash and adds it if it isn't. 
                $path = '/' . $path;
            }
            return get_bloginfo('template_url') . $path . '?' . date($time_format, filemtime( get_theme_root() . '/' . get_template() . $path ) );
        }
?>
share|improve this answer

Simple: use the URl to load the style and the path to get the filemtime():

wp_register_style(
    'handle',
    get_stylesheet/template_directory_uri().'/path/to/your/stylesheet.css',
    array( 'possible_dependency' ),
    filemtime( plugin_dir_path( __FILE__ ).'path/to/your/stylesheet.css' )
);

The resulting URl will be something like

<link href="http://example.com/wp-content/themes/path/to/your/stylesheet.css?1379012967924">
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.