[Seaside] RE: cssClass and cssID (was testing framework)
Brian Brown
rbb at techgame.net
Fri Jul 23 17:52:57 CEST 2004
On Jul 22, 2004, at 4:30 PM, Avi Bryant wrote:
> One thing this encourages is adding good CSS ids throughout the
> render, which is something that's always seemed overly clunky to me.
> That is, the necessity to put #cssClass: and #cssId:, as well as
> #div:, #span:, etc everywhere, clutters up the more interesting parts
> (like anchors and callbacks) of any given render method. Anyone have
> any good ideas to keep these separated? I'm just throwing out random
> thoughts here, but one possible pattern that occurs to me would be to
> introduce a higher level wrapper around the HtmlRenderer, that was
> specific to a particular component. For lack of a more imaginative
> name, let's call this a View. The idea would be that the *structure*
> of the rendering is still controlled by the component, but the
> specifics (the actual tags and ids) are filled in by the View. So,
> for example, take the following fairly typical render method:
>
> MyComponent>>renderItems: aCollection on: html
> html cssClass: 'item-list'.
> html unorderedList:
> [aCollection do:
> [:ea |
> html listItem:
> [html cssClass: 'item-choose'.
> html anchorWithAction: [self choose: ea] text: ea description.
> html spanClass: 'item-actions' with: [html anchorWithAction: [self
> remove: ea] text: '(remove)']]]]
>
> Would it be better, or just more confusing and cumbersome, to split
> this into something like:
>
> MyComponent>>renderItems: aCollection on: view
> view itemList:
> [aCollection do:
> [:ea |
> view item:
> [view chooseItem: [self choose: ea] text: ea description.
> view itemActions: [view removeItem: [self remove: ea]]]]]
>
> MyView>>itemList: aBlock
> html cssClass: 'item-list'.
> html unorderedList: aBlock
>
> MyView>>item: aBlock
> html listItem: aBlock
>
> MyView>>chooseItem: actionBlock text: aString
> html cssClass: 'item-choose'.
> html anchorWithAction: actionBlock text: aString
>
> MyView>>itemActions: aBlock
> html spanClass: 'item-actions' with: aBlock
>
> MyView>>removeItem: actionBlock
> html anchorWithAction: actionBlock text: '(remove)'
>
> Anyway, just a thought.
>
> Cheers,
> Avi
>
I think the second way introduces an unnecessary layer of abstraction -
yes, each individual method is cleaner to read the CSS info, but
overall it would be much more difficult building that component; I like
the conciseness of the first one.
What about the idea of assigning each component a default css name
based on the name of the component. All elements rendered in that
component would be in a namespace (from a CSS perspective) like:
MyComponent.table
MyComponent.h3
etc. This would follow the standard CSS inheritance, giving very fine
grained control to each component only if desired.
This doesn't help with <div /> but those are structural anyway, and it
is very useful to see what is being rendered inside of a particular div
element when editing the render methods. Just for various text styles,
spanClass:with: and spanNamed:with: don't seem too cumbersome. Using
this scheme, a #spanText: could also be created that acted like #text:
So instead of:
html span: [html text: 'Some words']
you would have:
html spanText: 'Some words'. "This span would be covered by the
default css component name space."
I may be missing some things here, and I certainly am not using CSS to
it's full potential in my own Seaside work, but what do you think?
Brian
More information about the Seaside
mailing list