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 it). They can be used very much like the existing form helpers (like html div ...
).
E.g., the one for horizontal text fields (in a horizontal form) looks like this:
horizontalTextField: aLabel
| field |
field := WATextInputTag new
class: 'input-xlarge';
yourself.
self html div
class: 'control-group';
with: [
self html label
class: 'control-label';
with: aLabel.
self html div
class: 'controls';
with: [self html brush: field].
].
^ field.
Which I aim to be using like this when rendering a component:
(self horizontalTextField: 'Titel')
on: #title of: self article;
id: 'title'.
So, the aim is to wrap the actual text field in a few divs, but still be able to make changes to this wrapped element outside of the helper function (using the normal tag helper accessors), as shown above.
However, this does not work as the with:
method causes the wrapping divs to be serialized (aka rendered) before I return the element, which I then cannot edit anymore.
POSSIBLE SOLUTIONS:
- Actually extend the WACanvasTag subclasses used for rendering the fields and create instances of those new subclasses in my custom helpers in my component class. I would simply overwrite their rendering code for my pleasure. This would probably be the most object-oriented way to do things, but quite arduous, especially as I'd have to repeat quite a lot of code for inserting my own HTML before and after the element for every single one of these subclasses (as they already have to inherit from the Tag class which I'm trying to wrap).
- When calling the helpers, do something like
self horizontalTextField: 'Titel' with: [:field | id: 'title']
. The block would then be applied before rendering the actual text field in the helper method. This would be quite flexible, but not very pretty (syntax-wise). - Hardcode the wrapping HTML (related to this question) in my helper functions. Like this:
self html html: '<label class="control-label">
etc. Quite the hack, in a way, and not very object-oriented.
Comments? Ideas? Better suggestions?
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:
And here's how I've implemented "row" -
In addition I added extension methods to WATagBrush to support span, offset and pull-right, as well as fluid containers:
And finally, here's an example render method that uses some of the above: