Forum OpenACS Development: A proposal: CSS Styles and module hooks in OpenACS 4

How does OpenACS 4 support external style sheets? 3.2.5 doesn't do much, leaving it as part of site implementation to change ad_header to add a link to an external style sheet.

I'd like to suggest a small change in the ACS to better support CSS styles in ACS 4 (and 3.2.5).

There are four ways a site might support CSS styles. (This is written up well at http:/ /

  1. not at all
  2. support for offline browsers (that can't download your style sheet)
  3. support for Netscape 4ish, (IE 4, and IE3?) browsers (basically very broken as far as CSS is considered.)
  4. support for more modern but still broken browsers (and one day unbroken?)
To support offline browsers, it's a good thing to incorporate a small number of style tags inline, embedded in the document. Support for the Netscape 4 broken series is handled by a <LINK REL... > link within your document that sends Netscape 4+ downloading of a presumably more complete style sheet that can override the simple, embedded styles. Similarly, support for more modern browsers is handled by a @import within the linked stylesheet. Netscape 4ish browsers can't handle the @import and will skip it, and this lets you include even more complex and even conflicting styles that can override the styles listed in the original <LINK REL...> style sheet.

Anyway, I would like to propose three small changes and two big changes to the routines within the ACS that create headers (mainly ad_header of course.), context bars, and footers. Incorporating these changes will make it much easier for sites to support CSS external style sheets, and will also make it much easier for sites to modify the out of the box OpenACS look and feel without requiring editing or redesign of any of the OpenACS modules.

To better support CSS external stylesheets, I propose we:

  1. add support for browsers with no understanding of styles by creating ad.tcl parameters for bgcolor, color, link, vlink, alink, text, and maybe background. (Note that bgcolor and color are currently supported.) Change ad_header to spit out these parameters in the <body ... tag.
  2. add support for offline browsers with a parameter, style_block, that contains literal text to be included within the <HEAD of a document. The style block if present would be placed within a <STYLE block and surrounded by an HTML comment marker.
  3. add support for online browsers with a parameter containing a url to the site's base style sheet
That's three changes that will make it much easier for a site to support CSS styles, but it's not quite enough for an ACS site that has many different modules and many types of users.

What I'd really like to do is to make it possible for each page to specify a different style sheet to link to depending upon a) module preferences, b) page design, and possibly c) user agent or even media type. Basically, I'd like to add APIs such that

  • a module can determine the url of the main site's base style sheet
  • a designer can create and name a set of styles that describe the pages within a module (e.g. one-column-pages, three-column-pages, reporting-pages, purchase-pages, etc.)
  • a designer can specify for each page in a module, the name of the module specific style sheet
The obvious way I see this being implemented is through a module specific callback that ad_header calls. The callback would determine the url, the user agent (maybe the media) and would return the name of the style sheet to link to. (And other ideas?)

Now, some of this might be doable by a site today using the templating system. Two comments then: one, I would like to see a formal mechanism designed and supported within the OpenACS and two, styles are light weight, very easy to develop entities. I believe flexible support of styles is useful even for a site in which templating doesn't yet make sense. So I would like to see a light weight solution developed which doesn't bring into play the entire templating system.

Determining the media might be done in a variety of ways. In addition to using the user-agent, which is not entirely sufficient, a site may wish to download browser sniffing javascript on the first page of any session, and add a session cookie denoting the browser and it's various capabilities. (I've seen reasonable scripts that weigh about 1000 bytes.)

My final proposal is something that could probably be handled within the templating system. Arguably, it might be better handled within the templating system. Still, I think it's useful at times when templating is not called for, and I think it provides capabilities beyond those of the templating system. And that proposal is to give site developers the ability to modify, on module by module basis, the values returned by ad_header, ad_footer, and the various context bar routines. Why one would want to do this and how, I think is best left for another thread.

Posted by Jerry Asher on
It would be very valuable to enumerate a series of CSS style class tags (or id tags) that would denote various ACS objects and that could be referenced inside a CSS style sheet to change the formatting of various ACS objects. Perhaps some subset of:
  • acsheader
  • acsfooter
  • acscontextbar
  • acsuser
  • acsgroup
  • acsmodulename
  • acsnote
  • acspagecontent
  • acsnavigation
What else?

The goal then is that newly designed modules would take care to encapsulate these objects within these tags.

This is a reasonable idea. I think it helps acceptance, when making a proposal like this, to provide a patch at least partially implementing the ideas you are proposing :-)

It took me an hour to hack the first four of your six ideas into being under OpenACS 3.2.5. The extra ad_parameter names are

  • linkcolor
  • vlinkcolor
  • alinkcolor
  • bodycolor
  • StyleBlock
  • BaseStyleUrl

And the URL of the site main style sheet (your fourth item) is then available using [ad_parameter BaseStyleUrl].

I'll leave conversion to OpenACS 4.x to you :-)

The patch is submitted as Patch 28 against OpenACS in the SDM, at

Anyone want to revive this idea for OpenACS 4.7?

I've written a simple version of this for acs-subsite 4.6
All it took was:

1. Added a few parameters to h1_font_family, h1_font_size, h1_color, h2_font_family...h6_color, etc.

2. modified /www/default-master.tcl to set the values for h1_font_family, etc.

3. modified /www/default-master.adp. added a <style> tag that
uses the values set in default-master.tcl.

I admit that it's not as beautiful and flexible as jerry's proposal, but it's easy to implement, and I think it will go a long way toward helping newbies looking for the skin feature of PostNuke.

Reviving this idea would be great, though I also don't see anything to be gained by tying the CSS to parameters. Jerry Asher's "semantic tags" is the way to go, plus the <BODY> tag should be given a class named after the package in case you need package specific formatting (e.g. body.bboard p {} looking different from p {}).

It would be best, it think, to separate out CSS for different packages into different files which were then imported into a main stylesheet or through links added in the template. On the site I manage I add an "extra_css" property to the package's master template, so that a list of stylesheets is passed up to default-master where they are all output as links in the header. I've been putting all CSS files in /web/[server]/www/css, but I wonder if package specific CSS, in a scheme like this, shouldn't go in /web/[server]/[package]/www/css to keep everything belonging to the package together (otherwise you'd have to have a mechanism to move te package css to the site-wide css directory during installation of the package).

Hi Radam,

I think its good.  Although I think it would make it better if we can just write the CSS file into the file system.  I am not sure if its wise to stuff that into the parameters.  Although parameters is cached I still think writing a css file is more efficient.

Novice users can use your UI to create/edit the css file.  While more expert users can modify directly the file.  Then on the master templates just link the css file like ordinary html stuff.

We also did similar to what you did in CCM.  We have site object and CSS of this site was stored in db.  Then we have a style.jsp that pulled those out in to the db.  I am not that too happy about it since its not flexible.  I think the UI to create/edit a CSS file will be far better and flexible.  Although more work must be done on the later.