Integrating color module

Color.module allows the admin to change the color scheme of a theme completely. By selecting a palette of 5 colors (either from a set or by hand), you can change the colors of an entire theme.

The module can alter the stylesheet and re-render images. However, the theme must provide specific hooks to allow this, and the design must be created specifically to accomodate this.

This document explains the basics of making a colorizable theme.

Design

It is important to realize that due to the way color.module works, not every design can be colorized.

We take a transparent image of the design (the base), which includes everything except the background. We then compose this image on top of a colored background, to get the colored versions. Finally we slice up this composite image into smaller images and save them to separate image files.

We also process the stylesheet and change all the colors based on the ones you defined. The module smoothly changes the colors using the palette as a reference. Colors that don't appear literally in the palette are adjusted relative to the closest matching palette color (whether it is a link, text or background color).

So, the photoshop mockup of the design should consist of a layered file that has one or more colored layers at the bottom of the layer stack, with everything else blended on top. When you save the base image, you have to merge all layers together, while keeping the colored layers invisible. Take a look at Garland's base.png file to see an example (open it in an image editor to see the transparencies). There is a video showing how to create your own base.png file using Photoshop.

All the files generated in this process are written to /files/css and used instead of the default images. This means that a colorizable theme should still work out of the box without color.module, in the default color scheme.

In Practice

Let's use Garland as an example. The most important files are in the themes/garland/color subdirectory:

base.png
This contains the base design of the theme, which is composed and sliced into the images.
color.inc
This file contains all the necessary parameters to color the theme. See below.
preview.css
This stylesheet is used to generate the preview on the color changer.
preview.png
This image is used to generate the preview on the color changer.

The presence of color/color.inc makes the color picker appear on the theme's settings. It is a regular PHP file which contains an $info array with the following values:

Schemes

<?php
array('schemes' => array(
   
'#0072b9,#027ac6,#2385c2,#5ab5ee,#494949' => t('Blue Lagoon (Default)'),
   
'#464849,#2f416f,#2a2b2d,#5d6779,#494949' => t('Ash'),
   
'#55c0e2,#000000,#085360,#007e94,#696969' => t('Aquamarine'),
   
'#d5b048,#6c420e,#331900,#971702,#494949' => t('Belgian Chocolate'),
   
'#3f3f3f,#336699,#6598cb,#6598cb,#000000' => t('Bluemarine'),
   
'#d0cb9a,#917803,#efde01,#e6fb2d,#494949' => t('Citrus Blast'),
   
'#0f005c,#434f8c,#4d91ff,#1a1575,#000000' => t('Cold Day'),
   
'#c9c497,#0c7a00,#03961e,#7be000,#494949' => t('Greenbeam'),
   
'#ffe23d,#a9290a,#fc6d1d,#a30f42,#494949' => t('Mediterrano'),
   
'#788597,#3f728d,#a9adbc,#d4d4d4,#707070' => t('Mercury'),
   
'#5b5fa9,#5b5faa,#0a2352,#9fa8d5,#494949' => t('Nocturnal'),
   
'#7db323,#6a9915,#b5d52a,#7db323,#191a19' => t('Olivia'),
   
'#12020b,#1b1a13,#f391c6,#f41063,#898080' => t('Pink Plastic'),
   
'#b7a0ba,#c70000,#a1443a,#f21107,#515d52' => t('Shiny Tomato'),
   
'#18583d,#1b5f42,#34775a,#52bf90,#2d2d2d' => t('Teal Top'),
  ));
?>

This entry contains a straightforward array of pre-defined color schemes. Each entry must have 5 colors (which, in order, are base color, link color, top header, bottom header, and text color) formatted as above, and a title.

The first scheme is used as a reference and must match the colors used in the theme's default images and stylesheet closely. Otherwise, the final colors might not be what the user intended. See the 'stylesheets' section for more information about how the colors are calculated.

Images to copy

<?php
 
array('copy' => array(
   
'images/menu-collapsed.gif',
   
'images/menu-expanded.gif',
   
'images/menu-leaf.gif',
  ));
?>

This array contains a list of images which should not be altered. They are copied to the location of the generated images and stylesheet.

Fill areas and Gradients

To color the image, we create a target image that is the same size as the base image, and draw colored areas and a gradient. For full flexibility, the location of these areas is defined by specifying their coordinates using (x, y, width, height):

<?php
 
array('gradient' => array(0, 37, 760, 121));
?>

You can specify one vertical two-color gradient.

<?php
 
array('fill' => array(
   
'base' => array(0, 0, 760, 568),
   
'link' => array(107, 533, 41, 23),
  ));
?>

You can specify regions for each of the palette colors. The region will be filled in with the selected color. Available colors are 'base', 'link', 'top', 'bottom' and 'text'.

Image slices

Next, you need to define the areas of the base image to slice out for each of the images. Again, you specify coordinates as (x, y, width, height) along with the filename of the image, as used in the stylesheet. The logo and screenshot slices are special and always take the same filename. The screenshot will be resized to 150x90 pixels.

<?php
 
array('slices' => array(
   
'images/body.png'                      => array(0, 37, 1, 280),
   
'images/bg-bar.png'                    => array(202, 530, 76, 14),
   
'images/bg-bar-white.png'              => array(202, 506, 76, 14),
   
'images/bg-tab.png'                    => array(107, 533, 41, 23),
   
'images/bg-navigation.png'             => array(0, 0, 7, 37),
   
'images/bg-content-left.png'           => array(40, 117, 50, 352),
   
'images/bg-content-right.png'          => array(510, 117, 50, 352),
   
'images/bg-content.png'                => array(299, 117, 7, 200),
   
'images/bg-navigation-item.png'        => array(32, 37, 17, 12),
   
'images/bg-navigation-item-hover.png'  => array(54, 37, 17, 12),
   
'images/gradient-inner.png'            => array(646, 307, 112, 42),

   
'logo.png'                             => array(622, 51, 64, 73),
   
'screenshot.png'                       => array(0, 37, 400, 240),
  ));
?>

Files

Finally you need to specify the location of the files for your theme. You need an image and a stylesheet for the preview, as well as the base image*:

<?php
array(
 
'preview_image' => 'color/preview.png',
 
'preview_css' => 'color/preview.css',
 
'base_image' => 'color/base.png',
);
?>

* As of drupal 6, Color.module will no longer require base_image, meaning it is possible to utilize the module without images.

Stylesheets

The color.module will read in a theme's style.css file as well as any other styles that are imported with @import statements and create a new style.css file. It will change the colors in the CSS using one of the chosen palette colors as a reference, depending on the context:

  • Links: the 'link' color is used, for rules that apply to a elements.
  • Text: the 'text' color is used, for rules that appear in color: styles.
  • Base: the 'base' color is used for everything else.

However, if a color in the stylesheet matches one of the reference colors exactly, the context will be ignored, and the matching replacement color will be used instead.

For example, suppose your reference color is dark blue by default, but you change it to red. Your default stylesheet contains both light blue and gray purple, both relative to this reference color.

The resulting colors (mauve and brown) are similarly different from red as the original colors were from blue. In technical terms: the relative difference in hue, saturation and luminance is preserved.

If you find color.module is using the wrong reference color, try separating the different pieces into separate CSS rules, each in their own selector { ... } section, so there is no confusion about the context.

Note that if you edit your stylesheet after changing the color scheme, you must resubmit the color scheme to regenerate the color-shifted version.

If wish for certain colors in the stylesheet not to be altered, you should place their CSS below the following marker:

/*******************************************************************
* Color Module: Don't touch                                       *
*******************************************************************/

You can only use this marker once in your style.css file. It applies globally, so if you use it inside an imported stylesheet, all colors below the @import statement will be left alone too.

Making colors match

It is important that the generated images match with the shifted colors in the generated stylesheet. Otherwise, ugly edges might appear.

To make this work, pixels in the base image must all be a simple color in areas where they have to match with CSS-defined colors. Because we don't know where CSS-defined colors appear in the base image, we use a global blending color which must be the same in the whole design. Garland uses white. Note that the Garland base does include e.g. gray and black pixels, but only in areas where only images are used as backgrounds (e.g. the header). Other than white, black or grey are good candidates too.

<?php
 
array('blend_target' => '#ffffff');
?>

Masochists can take a peek at color.module's innards, particularly the _color_shift() function if you're interested in the how and why of this.

PHPTemplate changes

Finally, you need to hook color.module into your theme. We'll use a PHPTemplate theme as an example, but this applies to other engines as well.

In your theme's template.php file, add the following snippet (for Drupal 6.x):

<?php
/**
* Override or insert PHPTemplate variables into the templates.
*/
function phptemplate_preprocess_page(&$vars) {
 
// Hook into color.module
 
if (module_exists('color')) {
   
_color_page_alter($vars);
  }
}
?>

In Drupal 5.x, you’ll need to the following snippet:

<?php
/**
* Override or insert PHPTemplate variables into the templates.
*/
function _phptemplate_variables($hook, $vars) {
  if (
$hook == 'page') {

   
// Hook into color.module
   
if (module_exists('color')) {
     
_color_page_alter($vars);
    }
    return
$vars;
  }
  return array();
}
?>

This will allow the module to override your theme's logo, stylesheet and screenshot. If you perform other changes in _phptemplate_variables, you need to merge in this snippet.

overview of supported themes

twom - August 13, 2009 - 18:03

Is there anywhere an overview of themes using the color module.
I have done searching and could not find a good overview.

Thank you,
Tom

Update: my list
• Garland
• Minelli
• Abarre
• AD Blueprint
• Alldrupalthemes.com basetheme
• Auquanaut
• Austere
• Deco
• Wabi
• Picture
• Twilight
• Kommunity

color.module used by RootCandy

hferree - November 5, 2009 - 23:07

Understanding base.png for the 'Image Processing' Challenged

PumpkinFace - November 18, 2009 - 16:41

For the sake of Image Processing Newbies, the following explains how to understand Garland's base.png and how you can create your own base.png using GIMP.

After opening garland's base.png in GIMP you may note something odd about it. There are 'shaded' areas which don't correspond to any pixel color. If you click around on the image, you will see white virtually everywhere, with the lettering done in a gray. So what do those shaded areas represent?

The PNG file format uses an RGBA representation for each pixel. The 'A' in this case stands for the alpha channel. Its a byte indicating how much background is allowed to shine through. This is key in many image processing effects. So the shaded areas that you seeing is GIMP's way of communicating to you the percentage of alpha each pixel actually is.

To see this more precisely, we can use GIMP's color picker. After loading garland's base.png in GIMP, you will see 3 windows. The left is the Toolbox window, the center is the image, and the right is the layering window.

Note: when using GIMP you need to be very aware of what layer you are in. I don't know how many times I was left completely befuddled, because the operation I was trying to do would not work even though I tried again and again. The problem was I was in the wrong layer.

Which layer you are in is controlled by the little cascade at top of the layering window. Use this cascade to ensure you are in the right file. Then, make sure the layer of interest is selected in the list beneath.

Garland's base.png will have just one layer called 'Background'. Select this, and then bring up the color picker on the toolbox window side. At the bottom of the dialog is a 'Use info window' check box. Click that. Now when you click on a pixel a little info window will pop up showing you not only the RGB value, but also the alpha percentage as well (100% = completely opaque, 0% = completely transparent).

Creating your own base.png from scratch:

Do File->New, and create an image the same size as garland's base.png image.

Ensure the layering dialog is set to the new file.

You should see one layer named 'Background' for your new base.png. Notice that the Background word is in bold. This means there are no alpha channels defined yet for that layer. You need to create one.

This is how I like to do it: Set the foreground color to white. Then fill the entire image with that color. Then, select Layer->Transparency->Color to Alpha. By default, it should have 'white' be the color. When you execute this command, it will replace the color white with a fully transparent pixel.

Creating Gradient Transparent Regions:

You will notice in garland's base.png that there are gradient transparency regions. For example, the left side bar is one such region. To create a gradient transparent region using GIMP, do the following:

First create a new layer. Now make sure that layer is selected. By default the size of the new layer will be the size of the image. That's fine for now. Select the region you want to create using the rectangular select tool. Now click on the Blend Tool in the Toolbox window. In the dialog you need to set the Gradient control to be 'FG to Transparency'. Make sure the foreground is white. Now let's say you want to make a gradient region with the top being mostly opaque to the bottom being mostly transparent. Click on the top of your selected region and drag with your mouse down to the bottom. After you do so, you should see shaded effect. If it's not working, most likely you are in the wrong layer.

In garland's base.png you will also see mostly uniform transparent regions. For example, the breadcrumb region is one such region. The way I created these was also with the Blend tool. But instead of starting at the top of the selected region, I started way above the selected region. Then, instead of ending at the bottom of the selected region, I ended far below the selected region. This will create a near uniform transparency for the selected region.

How the image slices are constructed in the color.module:

  1. An empty target image is created to the size of base.png.
  2. The 'fill' colors specified in your color.inc are applied to the indicated regions of the target image.
  3. The gradient region is made using the header top and header bottom color values as indicated in the configuration settings form.
  4. Now the base.png file is loaded and copied into to the target image. This means the fill and gradient colors will be lost unless transparency values were used in those exact areas from the base.
  5. From this target image, the slices as indicated in your color.inc are used to create the indicated files.

Producing your first set of default sliced images

The color module has one efficiency built in: for the default color scheme it will not generate any files. Rather it logically bails out of any processing it normally would do and simply uses the existing files in the shipped theme. This makes sense during production, but how can you get those initial images? I consider it too error prone to hand create your first crop of sliced images.

I didn't see a better way, so I recommended temporarily commenting out the relevant lines in the color.module. This would be lines 285->293 in modules/color/color.module. It's the section that starts with the comment 'Don't render the default colorscheme, use the standard theme instead.'

Now when you open do 'Save configuration settings' in the configuration settings for your theme, it will save the files in a new directory underneath the 'sites/default/files/color' folder. Copy these images to your official theme location. When you are done developing the initial images, undo the changes you made to the color.module.

Note: another thing I like to do just during development is to make an 'all.png' slice being the size of the image. This just lets me see if everything is getting put together correctly.

A simple color.module suggestion to the developer: in the aforementioned lines, bail out only if the theme is the default AND the first slice file exists in the theme directory. This way if the developer needs to recreate those initial images, all they have to do is remove the first slice file.

 
 

Drupal is a registered trademark of Dries Buytaert.