Hello,

I am sure it is too much of a newbie question but I have been browsing and googling long enough now to try and ask it here.

I have a website and I want to have a different background image depending on content type. So I created a separate content type. No I want to have a separate layout for these pages. I can get a different template going. with the page-node-28-tpl.php and that allows me to make a different set up. But I would like to have a different css sheet linked to it. So I can change things in the css depending on the content type.

The thing I am looking for now is to have a different background image on different pages of the site. I thought doing this through a different style sheet would be best. for instance style2.css and link that a template. But how do I link a template to another style sheet?

Hope to find an answer.

Tony

Comments

matkeane’s picture

Him

Depending on how different your layout actually is between pages, creating individual tpl.php files might be overkill.

For example, if you just need to change a background image, while most of the design stays the same, you could modify your theme's template.php file to add an extra class to the body tag. You could add in a class based on a taxonomy, which you might use to divide your site into sections (although the http://drupal.org/project/sections module could do this for you), or a node-id, and then target the pages based on that. That way your body tag might look like:
<body class="not-front logged-in node-type-page sidebar-left listings node129">
... which would enable you to target all pages in the 'listings' section, or one particular page.

If you layout varies considerably, then you might still want to create some new tpl.php pages - maybe for each content-type - and then manually add an extra class to the body tag:
<body class="<?php print $body_classes; ?> myextraclass">
If you want to change the stylesheet completely, you can do this in the 'preprocess_page' function in the theme template.php

There's also a handbook page which should get you started: http://drupal.org/node/46027

tonyoverwater’s picture

thank you for you reply but I am afraid I am still a bit puzzled. I thought it would be much easier. Just add a different stylesheet and tell an adjusted template to use that. I am not very familiar with body classes.
I will try to understand more of this. I had hoped it would be a bit more simple. I guess I need to dig deeper.

Tony

matkeane’s picture

Hi,

Sorry if I muddied the waters there. The Drupal theming system is quite complex, but the advantage is that there are many different ways to solve a problem, depending on what you want to achieve - different templates, different stylesheets, or a combination of the two.

If 90% of your styles will used on all pages and you just want to change the background of a couple of elements, then I'd be tempted to stick with one stylesheet - your theme's style.css - with the advantage that you only need to maintain one stylesheet for the site. Adding an extra class to the body tag will enable you to target pages with new style rules, e.g:

body .this-section {some-background-styles-here} 
body .that-section {other-background-styles-here}

If your page layout will change depending on the content-type, or some other criteria, then you're on the right track with creating new tpl.php templates. Drupal adds a new body class for different content-types, so that allows you to target different types of content with different style rules with something like:
body .node-type-my-content-type div.header {my-header-background-rules-here}

An example: On a site I'm currently working on, I have different tpl.php templates for each of my content type so that I can tweak the layout for each of them. I also created a taxonomy vocab for 'site sections' and each node has a section assigned. In my theme's template.php file, I add an extra body_class based on the taxonomy term, and use that to change the header background and title (h1, h2) tag's colour so that each section has a distinctive look. I can then style my content-types differently, but make sure that all nodes in each section have a coherent look, even if they are of a different type.

If you want a completely different look for your different templates, then you need to tell Drupal to use a different, or additional, stylesheet in the template page_preprocess function. But if you don't want to mess around with the code, the 'sections' module allows you to specify different stylesheets and templates based on all kinds of criteria.

tonyoverwater’s picture

yes, this makes it more clear.... and adds more questions.

I am now able to change the background of the body through body class. But it now turns out I only want to replace a background of a a part of the page, a div. not really clear which it is. It is the content part. if I change the following class i get a result that is close

#wrapper #container #center #squeeze {
background: url(images/achtergrond.jpg) no-repeat;
position: relative;
height: 500px;
}

this is where the picture is linked.
so I copied this part, changed the name of the pic and changed the name #wrapper to wrapper2 etc

#wrapper2 #container2 #center2 #squeeze2 {
background: url(images/achtergrond2.jpg) no-repeat;
position: relative;
height: 500px;
}

and then I changed the template page as well. But there are many #wrapper #container #center and #squeeze related lines in the css. And it seems i need to copy them all to get the best result.

So now I thought it would be better to work with the last option. and that is page_preprocess function. And make a seperate style.css for the assigned page. but I don't know how to do this. tried to find it but couldn't. So a clear example as to how to change this in my template page would be much appreciated.

I would guess i would have to add something like

function page_preprocess(style2.css)

I sure it is more complicated than that.

Hope to hear from you.

I really appreciate the help.

Tony

matkeane’s picture

Hi,

OK so firstly, if you're messing with CSS, then, if you haven't already, you should probably install Firefox and the Firebug extension - it makes identifying the CSS rules to change so much easier.

Now, if you've already added a body class and changed the background of the body, you can use the same trick to modify your other page elements. So, instead of:
#wrapper #container #center #squeeze
... you can change this on certain pages with:
body.mybodyclass #wrapper #container #center #squeeze

If you've got several elements that you want to change, then you might find - with the help of Firebug - that there's a way to target them all with one rule. e.g:
body.mybodyclass #wrapper #container #center div.someclass

But, bear in mind that you might run into issues with CSS specificity. Basically, there's an order of importance to CSS selectors, so if you have one rule that's defined with #ids, you won't be able to override it with a .class unless you add another element to make it more specific. So, generally, you'll want to define your general styles with classes (all div.thisclass in one colour) and then override the exceptions with #ids (except div#thisone in a different colour). Again, Firebug can help you here as it shows all the rules applied to an element - from the most specific, to the most general.

As you guessed, changing things in the page_preprocess function is a bit tricker, as it handles more than just CSS files - it's your last chance as a themer to change any variables that are about to be passed to the page.tpl.php. One of the things you can modify is the array of stylesheets (core system ones, contrib module ones, etc). There's more detail on these pages:

http://drupal.org/node/171209 - adding stylesheets to all pages using the theme.info file
http://drupal.org/node/225868 - adding stylesheets using page_preprocess

... but it sounds to me like you could probably do what you need by manipulating the CSS in the current stylesheet.

tonyoverwater’s picture

WOW!!! Yes, great. I finally got it to work. Thanks a million!

one more small question if I may.

To make this work i called the page page-node-18.tpl.php which relates directly to this specific node. Would it also be possible to call a page page-nameofthecontenttype.tlp.php and that my background will change acording to content-type? I tried it but it didn't work directly. I suppose I need to address it differently.

Than I would really be on my way!! (so far:-(

Thanks again

Tony

matkeane’s picture

Hi,

I'm pretty sure you can create page templates for each content-type. It just occurs to me that I've only ever made node-content-type.tpl.php templates until now, but I guess that should work as well. I'm too lazy to maintain a bunch of page templates though, so I just use the body classes to style the main page.tpl.php differently! There's more info about template files on this handbook page: http://drupal.org/node/223440

Anyway, glad it's working for you...

Junro’s picture

Hello,

It's exactly what i try to do: "different background image on different pages"

I've got a node with the ID node-85 and impossible de target the entire page of this node.

When I'm using #node-85, only the node content is affected.

The only solution shoulb to create a template only for this node? page-node-85.tpl with <body class="<?php print $body_classes; ?> myextraclass">.
Only to add a background...

Do i have others solutions?

Thanks :)

matkeane’s picture

Hi,

Like I said somewhere above, I think adding extra template files just to change a background image is overkill. I'd probably do this by using this the page_preprocess function in the template.php file to add an extra class, or id, to the body - for example, adding 'node-'. $node->nid would give you <body class="node-85"> which should allow you to target any page in the site.

Then again, if coding is not your thing, then adding template functions may be overkill compared to adding another template file!

Junro’s picture

ok, thanks, it's exactly what I'm looking for, add classes to node page.

'node-'. $node->nid

in my template.php; i've got this function:

function phptemplate_body_class($sidebar_left, $sidebar_right) {
  if ($sidebar_left != '' && $sidebar_right != '') {
    $class = 'sidebars';
  }
  else {
    if ($sidebar_left != '') {
      $class = 'sidebar-left';
    }
    if ($sidebar_right != '') {
      $class = 'sidebar-right';
    }
  }
 
  if (isset($class)) {
    print ' class="'. $class .'"';
  }
}

if (is_null(theme_get_setting('litejazz_style'))) {
  global $theme_key;
  // Save default theme settings
  $defaults = array(
    'litejazz_style' => 0,
    'litejazz_width' => 0,
    'litejazz_fixedwidth' => '850',
    'litejazz_breadcrumb' => 0,
    'litejazz_iepngfix' => 0,
    'litejazz_themelogo' => 0,
    'litejazz_fontfamily' => 0,
    'litejazz_customfont' => '',
    'litejazz_uselocalcontent' => 0,
    'litejazz_localcontentfile' => '',
    'litejazz_leftsidebarwidth' => '210',
    'litejazz_rightsidebarwidth' => '210',
    'litejazz_suckerfish' => 0,
    'litejazz_usecustomlogosize' => 0,
    'litejazz_logowidth' => '100',
    'litejazz_logoheight' => '100',
  );

  variable_set(
    str_replace('/', '_', 'theme_'. $theme_key .'_settings'),
    array_merge(theme_get_settings($theme_key), $defaults)
  );
  // Force refresh of Drupal internals
  theme_get_setting('', TRUE);
}

is it this kind of function I have to write? All thaht stuff?

matkeane’s picture

is it this kind of function I have to write? All thaht stuff?

Kind of, but don't get too discouraged! I'm surprised to see an actual body_class function, as I didn't know that existed, although in the light of this post - http://john.albin.net/drupal/die-phptemplate-prefix-die - maybe it's not best practice?

Anyway, I don't want to confuse things... In the themes I've used, the body classes are manipulated in the page_preprocess function - e.g:

<?php
function yourtheme_preprocess_page(&$vars) {
  /*  Tweak body classes */
  $body_classes = array($vars['body_classes']); // get array of current body classes
  $current_section = yourtheme_get_site_section($vars['node']); // check node taxonomy for site section vocab
  $body_classes[] = yourtheme_id_safe($current_section); // Add unique class for each website section
  if(isset($vars['node'])) {
    $body_classes[] = 'node-'. $vars['node']->nid; // add node id class
  }
  $vars['body_classes'] = implode(' ', $body_classes); // put modified array back into page variable
  
  /* Tweak CSS files */
  $css = $vars['css']; // get array of current css stylesheets
  // remove nice-menus CSS - use theme style.css instead
  unset($css['all']['module']['sites/all/modules/nice_menus/nice_menus_default.css']); 
  $vars['styles'] = drupal_get_css($css); // put modified array back into page variable
} 
?>

That's an excerpt from one of my theme's template.php file - I add an extra body class according to the taxonomy term used (or fall back to checking the path if no taxonomy is set) and then, as another example, remove a module's stylesheet, since all the modified styles are in the theme's style.css.

So your page.tpl.php now has the modified $body_classes and $css variables ready to print, and any node pages should have an extra body class (not tested this though, this is email pseudocode!).

However, I'm not sure how the preprocess_page function will interact with your existing phptemplate_body_class function - it might be better to use one or the other, although I don't see how the phptemplate_body_class function could get any info about the $node. Anyway, have a play with that and see how you get on. Alternatively, if you don't want to mess with code, the Sections module allows you to do pretty much the same thing (and a lot more).

Junro’s picture

Hi, thanks for all theses usefull informations :)

I tried your function with body_class function but it's not working with my theme.

I tried to remove my body_class function but get:

Fatal error: Call to undefined function phptemplate_body_class() in /home/pariscin/www/themes/litejazz/default-page.tpl.php on line 110

I haven't created my theme... i'm not a hard coder lol it's the Littlejazz theme.

In fact, I did'nt even understand very well the body_class function of littlejazz theme. It only use a sidebar-left sidebar-right body classes? It's not very helpfull...

I'm going to try the Sections module :)

matkeane’s picture

Hi,

if you're not averse to a bit more tweaking - the PHP error when you remove the phptemplate_body_class() function is because that function is called from the default-page.tpl.php template file. If you remove that function call, and replace the body tag with something like:

<body class="<?php print $body_classes; ?>">

... then it should work with the page_preprocess method. The $body_classes variable is what you saw being prepared in the page_preprocess function of the template.php in the previous message.

The sidebar-left and sidebar-right classes are included by default by Drupal (D6 at least), so you should be able to get away without the phptemplate_body_class() function. But mixing two different theme methods may well result in a great deal of confusion and frustration!

Junro’s picture

ok well

I can't remove the function phptemplate_body_class($sidebar_left, $sidebar_right). I have to keep it.

SO I just add print $body_classes; "> to my default-page.tpl.php, but the class .node-85 is not working.

Even if this solution is possible, I simply don't have the skull to change .tpl code to make all this work :(

The solution for me is to create a page-node-85.tpl.php I think.

matkeane’s picture

Hi,

No worries - there are usually half-a-dozen different ways to achieve anything in Drupal, so go with what works best for you!