Using hook_init() to include CSS and JS files

For some time, I've been using the most hackish ways of including custom CSS and Javascript in my site via themes and custom modules. The problem has been (at least, in Drupal 6) that the hook_preprocess_page() function, inside which I'd really like to include my drupal_add_css() and drupal_add_js() functions, due to the fact that it's easy to see what page I'm on, or what kind of page I'm on, is not able to add CSS or JS to the page, due to the order in which the hooks are fired.

I've often just put my JS and CSS includes (via the drupal hooks) into the end of my custom module file, instead of inside a function at all.

However, a much cleaner way to include your CSS and JS is inside your own implementation of hook_init(). For example:

<?php
/**
 * Implementation of hook_init().
 */
function custom_init() {

 
// Add custom CSS & JS to front page.
 
if (drupal_is_front_page()) {
   
drupal_add_css(drupal_get_path('theme', 'custom') .'/css/sample.css', 'theme', 'screen,projection', FALSE);
   
drupal_add_js(drupal_get_path('theme', 'custom') .'/js/sample.js', 'theme', 'header', FALSE, TRUE, FALSE);
  }

 
// Add Javascript to a specific Context
 
if (context_isset('context', 'blog')) {
   
drupal_add_js(drupal_get_path('theme', 'custom') .'/js/blog-sample.js', 'theme', 'header', FALSE, TRUE, FALSE);
  }

}
?>

There! Much nicer. (This code is adapted from a sample sent to me by Joel Stein).

Comments

Note that in Drupal 7 you can specify CSS and JavaScript files via the module's or theme's info files. If you want to conditionally load certain files (like in the example above) you still have to implement hook_init().

You can add CSS/JS via .info in Drupal 6 as well, but it's often best to only load the files conditionally, for performance reasons.

True, but if CSS/JS aggregation is turned on, it is better, performance-wise, to load the CSS/JS on all pages so that it can take advantage of aggregation. These settings can be checked by variable_get('preprocess_css, 0) and variable_get('preprocess_js', 0)

I would wrap the call to context_isset in a module_exists(); that's just me though, I try to make code more robust OR set a dependency for context in the info file.

Using hook_init() is generally preferred, but for what its worth, if you do need to add a css file in mytheme_preprocess_page(&$vars) ... you can do this:

<?php
  drupal_add_css
('path/to/file.css');
 
$vars['styles'] = drupal_get_css();
?>

The preproces function also works ie... Themename_preprocess if you want to do this in your theme template.Php file

It never seemed to work for me, thus the hook_init().