Skip to content Skip to sidebar Skip to footer

Write Helpers For Wrapping Html Elements

I am currently writing my own Component base class with a whole bunch of helper methods for using the Twitter Bootstrap CSS framework (and avoiding all the boilerplate code around

Solution 1:

As you noticed, the above code does not work because the HTML Canvas emits the HTML right away. Brushes should never be stored anywhere, they are only valid a very short time. The same goes for the HTML canvas, it is very uncommon and a possible cause of bugs to store it somewhere.

The typical way to do this in Seaside is to create a helper method:

renderHorizontalLabel: aLabelRenderer andField: aFieldRenderer on: html
   html div
       class: 'control-group';with: [
           html label
               class: 'control-label';with: aLabelRenderable.
           html div
               class: 'controls';with: aFieldRenderer ]

The nice thing about the above code is that both aLabelRenderer and aFieldRenderer can be any object implementing #renderOn: (String, Number, Block, WAPresenter, WAComponent, ...).

renderContentOn:htmlselfrenderHorizontalLabel:'Comment'andField: [
           htmltextFieldvalue:comment;callback: [ :value|comment:=value ] ]
       on:html.selfrenderHorizontalLabel:'Acknowledge'andField: [ self renderCheckbox: false on:html ]
       on:html....

To generate the actual field you could create other methods that you then call from the block you pass in as aFieldRenderer. This gives you the flexibility to arbitrarily compose the different parts. Have a look at the examples in Seaside, there are many users of this pattern.

Solution 2:

It looks like you want to use it like a Tag Brush, so I'd say you definitely want to go with the extending WACanvasTag approach - but only when you actually want to create a compound "tag" like in the horizontalTextField situation.

For other Bootstrap concepts - like row, container, etc, your best bet is to simply add extension methods to WAHtmlCanvas.

I've done this myself - here's my implementation of a Bootstrap NavBar tag:

WABrush subclass: #BSNavBar
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Bootstrap'

BSNavBar>>with: aBlock
    superwith: [
        canvas div class: 'navbar'; with: [
            canvas div class: 'navbar-inner'; with: [
                canvas container: aBlock]]].
    closed := true

And here's how I've implemented "row" -

WAHtmlCanvas>>row
    ^self
        div class: 'row'

WAHtmlCanvas>>row: aBlock
    self row with: aBlock

In addition I added extension methods to WATagBrush to support span, offset and pull-right, as well as fluid containers:

WATagBrush>>offset: anInteger
    self class: 'offset', anInteger asString

WATagBrush>>beFluid
    self attributeAt: #class 
        put: (((self attributeAt: #class ifAbsent: [^self]) 
            copyReplaceTokens: 'container'with: 'container-fluid')
            copyReplaceTokens: 'row'with: 'row-fluid')

And finally, here's an example render method that uses some of the above:

renderContentOn:htmlhtml navBar: [
        htmldivpullRight;with: [ 
            selfsessionisLoggedInifTrue: [self renderUserMenuOn:html] 
                ifFalse: [self renderLoginBoxOn:html]]]

Post a Comment for "Write Helpers For Wrapping Html Elements"