Posts in "FluentHTML" category

Project updates

The past few weeks have been quiet for me in terms of any kind of technology driven activity, outside of work. Mainly due to the massive reorganisation of the house that we’ve been undertaking: creating an office, remodelling the living room, creating a nursery and contemplating the merging of the kitchen and dinning room – no room has been left unturned! All very DIY and I have to say; these hands were made for typing.

All of this has meant that I’ve not had much chance to contribute to the world in any particular way. However, over the past week I have managed to find some time and energy to get back into the swing of things and I have made some contributions to two of my open source projects.

  • FluentHTML – I have started working my way through the list of tags that exist in HTML5 and adding them into the project.  It’s ongoing but I have a couple of commits in there now which I think brings the list up to the end of the b’s!  I am just pushing through the list initially to try and get all of the tags in there.  After that I will look at any refactoring that might be possible and also at providing useful overrides on the methods.  I am also toying with the idea of validating the attributes that you can add to each tag but as I stand am unsure as to whether this is a good idea.
  • sObject Serialization – I have decided to make some fairly big changes to this.  Whilst the original idea was driven by the need to pass sobjects to @future methods I have decided that I will branch the project out and make it able to also (de)serialize lists and primitive types too.  This means a change to the interface so for the meantime I have created a Lists and Primitives branch in GitHub and am committing these changes to it.  Once they’re ready I’ll merge it back into master.  Currently I have updated the string serializer to fulfil the new requirements.  The JSON version will be updated but I need to update the JSON parser in there first, so it won’t happen straight away.

So that’s where I currently stand on these two projects and should hopefully give you a view of where I’m going in the short term with them.  Obviously progress is, as ever, subject to free time – an concept that currently seems to ebb and flow without much control.

Generating HTML from within APEX

After reading this post yesterday on Dynamic Visualforce Controllers I decided that I should should stay well away from the subject and leave it to those more experienced and more intelligent than myself to debate.  And I am sticking to that decision; no one needs my ignorance muddying the waters.

However one of the comments struck a note with me, probably because it’s a problem that I could solve, and it’s that which I want to focus on.

If you’re not interested in the forthcoming waffle and would rather just skip to the code then you’ll find it over on GitHub.

The problem as I interpreted it was to provide a way from within APEX to quickly and reliably output HTML.  It makes sense; writing HTML within code is error prone, not to mention dull.  One of the biggest problems is that we’re just creating a string to output – there’s no validation around the structure, missing closing tags, mispelt tags, invalid attributes; they’re all problems that are hard to spot but very easy to create.  So whilst creating HTML in code is seen as evil by some, it’s here and possible, so let’s at least try and create the best that we can.

With this in mind I opened up Eclipse, put all of the things I should have been doing to one side and set about trying to create a better way of creating the dreaded HTML.

I decided from the outset that I would write the solution to have a Fluent interface; mainly for readability but also because it reminds me of some of the happier times I had with C#.  It also feels like a good fit for this particular functionality… we want to generate HTML like this

<a href="">Search</a> <br/>

<input type="button" value="I do nothing"/>

from something like:

  new FluentHTML().a('','Search')
          .input('button', 'I do nothing');

As you can see there’s a clear corralation between the two, this makes it much more inutive to use, especially if you start breaking lines on the dot.

Implementing the a Fluent style interface isn’t particularly complex; the key is to remember to return a reference to yourself from each method.

Some HTML elements act as containers and can have other elements embedded within them such as a div.  Using a simple dot notation here could be confusing for the user; consider the following example:

    new FluentHTML().div()

Where is the anchor tag meant to go?  Is it in the div or after the div?  It’s not particularly clear.  We could add a new method called close or closediv but this then puts the onus back on the developer to remember to close the element they opened.  Instead I have chosen to allow another instance of the Fluent interface which in turn describes the HTML to put inside the div.  The worse that can happen now is that the developer miss counts the number of closing brackets to add but at least the compiler will assist in picking this up.  Using this syntax we can now either appened the anchor:

  new FluentHTML().div()

or add the anchor to the content of the div:

new FluentHTML().div( new FluentHTML().div()
                  .a('', 'Search') );

There is another type of container, one that can only contain specific child elements such as an ordered list (ol) which can only have list items (li) as it’s children.  In this case the method takes a specialised factory class which restricts the elements that can be added.

With the syntax decided the next step was to implement it.  I started out by planning to control the construction of the HTML myself, managing the opening an closing of tags, the consturction of attributes and the addition of the the text.  But then I remembered the rather obvious fact that HTML is really just a syntax of XML and that the platform has a nice object to handle all of that for me.  The DOM class certainly made the implementation of this whle thing a lot easier: providing the framework to do the heavy lifting and leaving me to just make sure that I create the correctly named tag.  A little bit of tweaking was necessary as I only wanted to output the string that represented the tags that I had added and the toXMLString() method contains the XML header and root but it wasn’t a major problem to clean that up.  The biggest problem came in implemeting the container elements such as divs.

My initial thought for bulding the container funtionality was to have the FluentHTML class that represented the child elements of the div expose those nodes and then to add them to the parent div node.  There’s just one small problem with that plan… the current implmentation of DOM.Xmlnode doesn’t allow you to add existing nodes as children.  Easy I thought, I’ll just call render() on the internal FluentHTML class and add the output as a textnode to the parent div.  Another flawed idea!  addTextNode() will encode any opening angle brackets into &lt; as you add the text to the node and rightly so.  In the end I lumped for the inelegant solution of adding a temporary child node which is numbered and adding the output from the inner FluentHTML object into a map which is keyed by the number of the temporary node.  All I need to do then is loop through the map and do a replace when I render the HTML.  As I say; it’s not beautiful but it works.

The implementation of the tags themselves is fairly trivial the biggest problem is figuring out which elements to add as parameters, for example should I always offer id as a parameter?  This is more a question of what would be useful than actual implementation.  The one thing that I will always accept as a parameter in at least one of the overloaded calls is a Map<string,string> of attributes as name value pairs, this means that the user can add whatever they need to to the tag; which also means I don’t need to offer an overloaded call with a billion paramters to cover all possible attributes on the tag.

And that’s pretty much the design of the class – it’s fairly easy really: instantiate a FluentHTML instance, add your tags using the methods avaliable and then when you actually want the HTML call the render() method.  Wht could be simpler?  At the end of it you know you’ll get some nice HTML out of it and then you’re free to do with it as you please.

The code is available over on GitHub and I will again submit it to the Code share site in due course.  Be warned though, the code that is currently there is very much a first pass at this.  I’m sure it could be faster and I’m sure it could be refactored to make it look nicer and on these things I shall work.  I shall also be looking at doing everything in a consistent manner: how I chose to implement the tags changed as I was implementing them and this probably shows in the code quite a lot.  I also need to spend some time figuring out which attributes on tags to offer as parameters and what combinations of these to present in the overloads.  All of these are topics that I’m open to disucssion and opinion about but would like to get sorted before I push ahead and implement the rest of the HTML tag set.

Whilst there is plenty of work left to do I feel as though I have already acheived what I set out to do: to provide a quick and robust way to output HTML from within APEX and all in an evening too – all of which makes me feel happy and that’s a good thing because now I have to go and do all those things I put off to do this instead.