WAStyleGroup (was Re: [Seaside] vwport - WAMultiCounter example broken)

Avi Bryant avi at beta4.com
Mon May 24 20:05:56 CEST 2004


On May 24, 2004, at 10:24 AM, Bany, Michel wrote:

> Some more to learn with the new CSS stuff !!

Well, feel free to poke around and look at it, but I'm not sure whether 
it'll stay, or change.  I'll describe it and see what people think.

There are two things I'm trying to achieve.  One is to allow more 
flexible and incremental use of CSS by the developer.  What I've done 
is added a set of WACssAttribute classes, for the "class", "id", and 
"style" attributes.  Any of them can be passed to WAHtmlRenderer>>css:. 
  It's easiest to create these on the class side of a subclass of 
WAStyleGroup, so, for example, you might start out with

MyStyleGroup class>>selectedCustomer
	^ self style: 'foreground-color: red'

MyComponent>>renderContentOn: html
	...
	html css: MySyleGroup selectedCustomer.
	html span: self selectedCustomer fullName.
	...

This ends up with <span style="foreground-color: red">, which isn't 
good practice, but is quick and easy at first.
The idea is that at some later point a designer will come along and 
refactor this to use a CSS id and external stylesheet:

MyStyleGroup class>>selectedCustomer
	^ self id: 'selected-customer'

MyStyleGroup class>>defaultStyle
	^ '
	.selected-customer {foreground-color: red}
	'

The #css: method makes sure to include any stylesheets on the style 
group that was used to create the CssAttribute, so you don't need to do 
anything extra to get a link to #defaultStyle.  And the render code 
didn't need to change at all for this refactoring to happen, just the 
style group (which, ideally, there would be a custom browser/editor for 
that was used by the designer).

The second thing I'm trying to achieve is to make it easier for people 
to have multiple alternate styles for  the same components.  With a 
single #style method, that doesn't work very well: if your package 
needs to extend the style of a base Seaside component, you have to 
override #style, which is messy to maintain.  A style group can have 
any number of methods whose selectors end with 'Style', and all of them 
will be included, so it's easy for a package to cleanly extend them.  
Each different style should be namespaced by wrapping all CSS 
definitions in a particular CSS class, eg,

.mystyle .selected-customer {...}
.mystyle .contact-info {...}

vs.

.mystyle2 .selected-customer {...}
.mystyle2 .contact-info {...}

That way by wrapping a particular CSS class around an instance of 
MyComponent, you can choose how it will be displayed.

The thing I'm unsure about with StyleGroup is that it takes this stuff 
further away from the components - #style is so nice and handy, and 
it's annoying to go hunt for a separate class that has all the CSS 
stuff in it.  We could collapse the StyleGroup stuff into Presenter, 
and do something like "html css: self selectedCustomerAttr" in the 
above example instead of "html css: MyStyleGroup selectedCustomer".  
But this is maybe throwing too much behavior into one class.
And it's also nice to be able to group styles and attributes that may 
be used across many different components in one convenient place, 
outside of the component hierarchy.  This ought to encourage coming up 
with some standard attributes and styles that get used in everyone's 
components and applications, which should make everything more easily 
theme-able.

Cheers,
Avi



More information about the Seaside mailing list