I have tried to procure a dynamic switch of style sheet for different paths and pages. But I encountered a problem when I wrote the preprocess_page code into the template.php, the following error in the admin page was shown and nothing happens for the style...

* warning: Cannot modify header information - headers already sent by (output started at /home/chandamo/www/www/testplatz/themes/blue_bars/template.php:19) in /home/chandamo/www/www/testplatz/includes/common.inc on line 141.

The code I wrote in the template.php is copied(from http://drupal.org/node/225868):

function drop_preprocess_page(&$variables) {
  $front_style = path_to_theme() .'/front-page.css';
  $path_style = path_to_theme() .'/path-'. arg(0) .'.css';

  if (file_exists($front_style) && $variables['is_front']) {
    $include_style = $front_style;
  }
  elseif (file_exists($path_style)) {
    $include_style = $path_style;
  }

  if (isset($include_style)) {
    drupal_add_css($include_style, 'theme', 'all', FALSE);
    $variables['styles'] = drupal_get_css();
  }
}

Does anyone have any clue about it? Do I need to do something with the page.tpl.php header? And is it the only method I can have a dynamic system of style sheet applied to different pages?

Thanks a lot.

Comments

cog.rusty’s picture

Make sure that there is no empty space or line after the final ?>, or just delete the final ?>. (Notice that the error message says "line 19").

All drupal core modules do that, to avoid this kind of error. They don't have a final ?>.

chandamon’s picture

thanks for your instant reply, I tried but it is still the same...
and make it clear, line 19 is the first line of the code shown above. Before it, the first 18 lines of codes are the default code of blur bar template, which is:


function phptemplate_system_user($form) {
  foreach (element_children($form) as $key) {
    $row = array();
    if (is_array($form[$key]['description'])) {
      $row[] = drupal_render($form[$key]['description']) . drupal_render($form[$key]['screenshot']);
      $row[] = array('data' => drupal_render($form['theme'][$key]), 'align' => 'center');
    }
    $rows[] = $row;
  }

  $header = array(t('Name/Screenshot'), t('Selected'));
  $output = theme('table', $header, $rows);
  return $output;
}

Does it clash with the code I copied? If so, what can I amend?

Or Do I need to deal with the header? coz it seems the problem with the header is the crux of it....

Many thanks.

cog.rusty’s picture

It still may be the same problem I mentioned, in a more general form: No printable characters allowed outside php tags. They cause headers to be sent.

Watch for spaces or line changes before, after, and between closing and reopening php tags in this file. In particular line 19 of template.php, whichever it is. Printable character outside php tags are only allowed in the tpl.php files.

chandamon’s picture

Oh thanks!!!
The error message disappears, however, the style sheet remains unchanged for every page...
Could you please kindly do me a favour again?
I have been dealing with this vexatious problem for quite a long time.

Many thanks.

cog.rusty’s picture

Hmm... I don't know much about theming, but have you double-checked the details?

Is your theme's name "drop" or you have changed the function's name accordingly?

For '/path-'. arg(0) .'.css', do you have style sheets named path-node.css or path-taxonomy.css or path-admin.css etc, to be loaded when you are viewing a node or a taxonomy list or an admin page, or whatever you want to style differently?

Or you might want to modify that concatenated style name, depending on what you want to style differently.

Other solutions to consider are
http://drupal.org/project/sections
http://drupal.org/project/taxonomy_theme

======= Edited to add:

Also check the produced html source in your browser, to see if the right style sheet is included or not, and which one is included in different cases.

chandamon’s picture

Yes, I had changed the drop to the theme name and uploaded the style sheet corresponding to the specific path.

Anyway really grateful to have your help.I will try what u advised right away.

Thanks a lot.

chandamon’s picture

I've checked the source code of my page and found that no css file is loaded according to the preprocess code in template.php. Only the default css is loaded as following:

It seems I have to do something with print $styles
in the page.tpl.php, right?

For whom reading this, thanks for your taking time.

cog.rusty’s picture

If your front page style isn't included in your front page either, then you are right that something is missing.

But if only the '/path-'. arg(0) .'.css' theme is not included, then the problem may be something simpler. For example, arg() ignores URL aliases and uses the original drupal paths.

chandamon’s picture

oh god,
the problem has just been fixed, thanks to your advice.

Thanks a lot.

georgedamonkey’s picture

What did you do to fix it? I've been trying to do the same thing, but to no avail. I can't get it to display anything in the header according to path.

georgedamonkey’s picture

I should clarify. I was able to get it working for the front page. But, I can't get it working for any internal pages.

cog.rusty’s picture

If you are trying to use paths with URL aliases, the logical thing to try is to replace arg(0) in '/path-'. arg(0) .'.css' with the first part of the aliased path. For example:

$section = drupal_get_path_alias( trim($_GET['q'], '/') );
$section = explode('/', $section);
...
...
$path_style = path_to_theme() .'/path-'. $section[0] .'.css';
...
...

and assuming you want to theme the /news/* pages, create a stylesheet file named path-news.css

I haven't tried it but I guess that would be the solution.

georgedamonkey’s picture

Absolutely perfect!!! Thank you!!!

rpmskret’s picture

I followed keenly the bits of advice and references on this page. It all did work out and I would like to share the solution in the following single code block.

function freetheme_preprocess_page(&$vars) {
 $front_style = path_to_theme() .'/front-page.css'; 
 $alias=drupal_get_path_alias($_GET['q']);
 $alias=explode('/',$alias);
 $path_style = path_to_theme() .'/path-'. $alias[0] .'.css';
 if (file_exists($front_style) && $vars['is_front']) {
    $include_style = $front_style;
 }
 elseif(file_exists($path_style)){
	 $include_style=$path_style;
 }
 if(isset($include_style)){
	 drupal_add_css($include_style,'theme','all',FALSE);
	 $vars['styles']=drupal_get_css();
 }
}

Example data

the website: yoursite.com
the theme name: freetheme
example path alias: things-you-saw
To get custom css for the front page create front-page.css.
To get custom css for the page at yoursite.com/things-you-saw create path-things-you-saw.css

Place the .css files in your theme's directory as in sites/all/themes/freetheme.
Place the code block in template.php without the closing ?>.

orange peel’s picture

Thanks for the great info, works great, only thing I have an issue with is when you have aliased path names, and you name your style sheets accordingly (path-alias.css), when you edit that node, my style sheet is ignored, since the page is now referenced to node/2/edit. Any help/ideas on this? I'm using Zen. Thanks!

Scott

Pav-2’s picture

Just like chandamon in the posts above I'm not able to get the new styles to show.
I'm a newbie to Drupal - don't mind the PHP but I really checked all details and followed the instructions and it's still not working.

Can anyone suggest anything?

I would really appreciate your help.

Pav-2’s picture

I'm using Zen and I can't get this to work.

I made all the changes and the the styles sill don't change. my_theme_preprocess_page seems not being used. I checked with theme_builder and it seems to be using

Preprocess functions:
template_preprocess + template_preprocess_page + zen_preprocess_page

not my_theme_preprocess_page

I don't know how to debug code so I'm a bit stuck for now.

What is a simple way to start debugging code with PHP on Drupal?
Does anyone know what's happening?

Many thanks,

Pav

stickgrinder’s picture

I use Zen on Drupal 6 and there is no problem with my subtheme. I created it with Zenophile and I get mytheme_preprocess_page (commented) function at line 117 of template.php. I just wanted to include a path-first-alias-segment.css file if present; no path-front.css. My purpose is to everride some css rules based on path. Here is my function:

<?php
function mytheme_preprocess_page(&$vars, $hook) {
  $alias=drupal_get_path_alias($_GET['q']);
  $alias=explode('/',$alias);
  $path_style = path_to_theme() .'/path-'. $alias[0] .'.css';
  if(file_exists($path_style)){
       drupal_add_css($path_style,'theme','all',FALSE);
       $vars['styles']=drupal_get_css();
  }
}
?>

Two notes:

  1. If you want to use filnames in the form path-node.css, you should change drupal_get_path_alias() function at line 3 with drupal_get_normal_path(), otherwise you are stick with aliased path (if you use path/pathauto module, you'll have /my-nice-node-title instead of /node/123. Here is the code:
    <?php
    function mytheme_preprocess_page(&$vars, $hook) {
      $alias=drupal_get_normal_path($_GET['q']); // <---------- here is the different call
      $alias=explode('/',$alias);
      $path_style = path_to_theme() .'/path-'. $alias[0] .'.css';
      if(file_exists($path_style)){
           drupal_add_css($path_style,'theme','all',FALSE);
           $vars['styles']=drupal_get_css();
      }
    }
    ?>
    
  2. Double check you're calling the right CSS file using the dirty die() trick:
    <?php
    function mytheme_preprocess_page(&$vars, $hook) {
      $alias=drupal_get_normal_path($_GET['q']);
      $alias=explode('/',$alias);
      $path_style = path_to_theme() .'/path-'. $alias[0] .'.css';
      
      die($path_style); // <--------------- here is the awful trick. Please, don't tell my mom I use this! ;)
    
      if(file_exists($path_style)){
           drupal_add_css($path_style,'theme','all',FALSE);
           $vars['styles']=drupal_get_css();
      }
    }
    ?>
    

I had it up and running with no hassles.
Bye