css — generate CSS file and create a link to it


Attribute Pos. Req. Default Description
name Yes Yes   Name of the CSS file. The name will be forced to lowercase, and the ".css" extension will be added unconditionally.
basefile       If the Variable is being used dynamically via DirConfig, this should be the filename the CSS is contained in. The file will be checked for modification time, and the CSS will be rebuilt if it's older than the source file.
imagedir     Value of the ImageDir directive Image prefix to use.
no_imagedir     0 Don't prepend value of the imagedir option to the generated link URL?
literal       Literal, in-place CSS definition. See the section called “EXAMPLES”.
media       The media attribute for the link HTML tag. For example, PRINT.
mode     0644 File creation mode.
output_dir     images Directory to place generated files to. It makes sense to match this with the ImageDir value.
relative     0 Copy the directory hierarchy in the output directory. Say, the [css] tag on the info/index.html page would produce output in images/info/theme_css.css.
timed       Regenerate the file on a timed basis? Default unit are minutes, but you can pass any standard interval.
interpolate     0 interpolate output?
hide     0 Hide the tag return value?


This tag builds a CSS file (from a Variable or other sources) and generates a link to it.

Note that if you're providing the literal argument, the CSS file won't be rebuilt when you change the literal, in-place definition changes. To cause rebuild, you must explicitly delete the generated .css file.


This tag appears to be affected by, or affects, the following:
Global Variables: MV_PAGE


Example: Simplest tag example


In the example above, the [css] will look for the images/theme_css.css, and generate an HTML link to it (<link rel="stylesheet" href="/images/theme_css.css">).

You can either save your CSS in a scratch variable, or provide it directly in-place. Here are both variants:

[set my_css]
.title { background-color: #336699; }

[css name="test_css1" literal="[scratch my_css]"]
[css name="test_css2" literal="body { background-color: yellow; }"]


When Interchange is ran in RPC ic run mode, the dynamic_variables_file_only pragma must be enabled to activate the standard THEME_CSS update mechanism. Namely, that will force Interchange to always read the latest copy of THEME_CSS, instead of using cached data.


css is available in Interchange versions:

4.6.0-5.9.0 (git-head)


Interchange 5.9.0:

Source: code/UserTag/css.tag
Lines: 126

# Copyright 2003-2009 Interchange Development Group and others
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.  See the LICENSE file for details.

UserTag css Order   name
UserTag css addAttr
UserTag css Version $Revision: 1.9 $
UserTag css Routine <<EOR
sub {
my ($name, $opt) = @_;

use vars qw/$Tag/;

return unless $name;

my $bn = lc $name;
$bn .= '.css';

my $dir = $opt->{output_dir} ||= 'images';

my $id = "";

if (! $opt->{no_imagedir} ) {
$id = $opt->{imagedir} || $Vend::Cfg->{ImageDir};
$id =~ s:/*$:/:;

$dir =~ s:/+$::;

if($opt->{relative}) {
my @dirs = split m{/}, $Global::Variable->{MV_PAGE};
pop @dirs;
if(@dirs) {
  $id .= join "/", @dirs, '';
  $dir = join "/", $dir, @dirs;

my $sourcetime;
if($opt->{basefile}) {
  $sourcetime = (stat($opt->{basefile}))[9];
#::logDebug("basefile=$opt->{basefile} sourcetime=$sourcetime");

my $url = "$id$bn";
my $fn  = "$dir/$bn";

my $write;
my $success;

my @stat = stat($fn);
my $writable;

if(@stat) {
  $writable = -w _;
  if($opt->{basefile}) {
    if($sourcetime > $stat[9]) {
#::logDebug("Found a basefile, out of date at modtime=$stat[9]");
      $write = 1;
    else {
#::logDebug("Found a basefile, in date at modtime=$stat[9]");
      $success = 1;
  elsif($opt->{timed}) {
    my $now = time();
    $opt->{timed} .= ' min' if $opt->{timed} =~ /^\d+$/;
    my $fliptime = adjust_time($opt->{timed}, $stat[9]);
#::logDebug("fliptime=$fliptime now=$now");
    if ($fliptime <= $now) {
      $write = 1;
    else {
      $success = 1;
  else {
    $success = 1;
else {
  $writable = -w $dir;
  $write = 1;

my $extra = '';
$extra .= qq{ media="$opt->{media}"} if $opt->{media};

my $css;
$css = length($opt->{literal})
      ? $opt->{literal}
      : interpolate_html($Tag->var($name));
$css =~ s/^\s*<style.*?>\s*//si;
$css =~ s:\s*</style>\s*$:\n:i;

  last WRITE unless $write;
  if(! $writable) {
    if(@stat) {
      logError("CSS file %s has no write permission.", $fn);
    else {
      if ( -d $dir ) {
        logError("CSS dir %s has no write permission.", $dir);
      else {
        logError("CSS dir %s does not exist.", $dir);
    last WRITE;
  my $mode = $opt->{mode} ? oct($opt->{mode}) : 0644;
  $success = $Tag->write_relative_file($fn, $css) && chmod($mode, $fn)
    or logError("Error writing CSS file %s, returning in page", $fn);

return qq{<link rel="stylesheet" href="$url"$extra>} if $success;
return qq{<style type="text/css">\n$css</style>};


Mike Heins, Interchange Development Group


DocBook! Interchange!