Problems
While trying to integrate Theme Builder 3.0 with Confluence 2.6 I've run into a number of problems, also there have been a few posts on the developer forums about how to deal with css styles for plugins, and after a conversation with Jonathan it has become clear that we need to create some kind of formal framework for dealing with CSS in confluence. Some of what I outline here may already exist in some form and I would welcome input from Confluence developers as to what is already available that I have missed.
The way I see it is that there are three distinct kinds of style data:
- confluence styles - styles that should be common across all themes (unless a theme wanted to specificly override it) - eg tabs, the edit screen, people directory, comments, labels heatmap etc..
- theme styles - code that is specific to making the individial theme look the way it does - eg: the css in the left-nav theme that makes the list on the left look like an accordion menu
- plugin styles - styles that are specific to an individual plugin - eg recently-updated, the code macro, footnotes etc..
In addition to these kinds of style data, there are several different situations where the style data should or shouldn't be included, for instance if you are running a closed wiki or are using confluence as a website, you dont really want to expend the extra bandwidth to feed the edit-page css to users who will never have the permission to actually use those styles. Similarly if you only use a macro/action that outputs a 50k stylesheet on one single page of your wiki, why hand it out to every user?
However the need to be efficient with the amount of data that you are sending down the pipe to users needs to be balanced against the desire to have as much data as possible fully cached by the client's browser. In Builder 2.x we achieved this by creating two static CSS files, one which contained just enough style data to allow a page to be displayed correctly, and then another much larger file which contained the styles for the less often used 'actions' such as edit-page and labels-heatmap. This worked 'well', in that there was a good balance between minimising download for casual users and allowing as much data as possible to be cached by the browser.
However we repeatedly hit problems (primarily with the {code} macros) whereby the styles had been updated and we hadnt noticed & users complained that their screens looked different between the default theme and the Builder theme. So for Builder 3.0 we decided to try and tackle this problem by going back to using the old monolithic main-action.css - confluence is now MUCH better at generating cache expiry and last-modified http headers, so it was decided it wouldnt be THAT much of an issue after all.
Unfortunately things didnt go all that smoothly, for some reason the main-action.css doesnt contain the css for the recently-updated macro ... which is what has led to this page ;D
Solutions
This is where I may start proposing things that already exist, showing up my lack of detailed knowledge of the very internals of confluence.
confluence styles
- There needs to be a core-confluence css file that contains all of the styles for core confluence 'things', like the tabs you get across the top of every page, the heading styles, the css for making those nifty warning panels with the little icon, basically everything that comes from a basic confluence install that you might encounter while VIEWING a page. (eg: /styles/core-confluence.css)
- There needs to be an 'action specific' css resource whose URL is based on the action at hand whose content is specific to that action (eg: /styles/edit-page.css, /styles/labels-heatmap.css, /styles/search.css, /styles/dashboard.css) It is quite possible that there will be some duplication between these since some of the styles used on the dashboard might also be used by the search-results for instance (using LOTS of separate files should be avoided though since latency will become an issue). Where possible however the same file should be used for similar groupings, so the styles for the search should be used on both the results page, and the search options page so that the browser can cache the data more easily. It's also quite possible that the groupings could be less finely grained eg: /styles/edit.css, /styles/global.css, /styles/space.css
theme styles
Each theme should deal with it's own styling in it's own way.
plugin styles
Right now when most of MY plugins want to add some css to the page, they insert a <link rel="stylesheet" type="text/css" href="yadda yadda"> tag and then set a flag on the request so that I dont add the stylesheet the next time the macro gets executed. This is great in that the data can be cached nicely by the browser however it means I have lots of repeated code all over the place adding and checking flags on the request object (other people may use the renderContext for storing their flags, however I know that will 'break' when used with builder panels and the css file wil get included more than once)
Much better would be if there were some kind of css manager that I could prod with my stylesheet eg: CSSManager.getCSSManager().addCSSfile(pluginkey,cssFileURL) or CSSManager.getCSSManager().addCSSdata(pluginkey,mystyles), that way I wouldnt need to keep a flag, the css manager would overwrite an entry in a hashmap each time I called it to add my css data.
The css manager would then output a non-cached stylesheet, generated freshly for each page, the css 'files' would be included using @import statements at the top of this stylesheet (allowing them to be cached by the browser) and the smaller 'ad-hoc' style 'data' tacked on below.
It would probably be most ideal if the css manager was integrated with the web resource manager, so that you could add your file css using the following syntax
CSSManager.getCSSManager().addCSSfile(cssfileId,pluginkey,cssFileURL)
The cssfileId would be a string that the css manager uses in conjunction with the plugin key as the key to the hashmap, the fileURL would then be in the same format as would be passed to the WebResourceManager.getStaticPluginResource(pluginkey,cssFileURL) ... which would remove an extra step for plugin devs and also ensure the correct cache expiry and last modified headers get set on the file request ![]()

Comments (2)
Sep 14, 2007
Guy Fraser says:
The problem with actionspecific styles is that most of those actions are using m...The problem with action-specific styles is that most of those actions are using macros which can also be used in pages - as such, it would be better to ensure that all the standard actions can re-use as much of the existing styles as possible. Not only would that trim down the style sheet, but it would also make changing the styles across the site far easier.
Sep 14, 2007
Alain Moran says:
Any macros should be adding their style data to the plugin styles section, unles...Any macros should be adding their style data to the plugin styles section, unless it is a commonly used core confluence macro in which case it should go into the core-confluence section. Perhaps 'plugin styles' would be better named as 'macro styles'?