Tuesday

Whadya know, this semantic markup crap is actually useful

why you should use a rules engine

The UI of a web application generally consumes 60-90% of the development effort. UIs are complex, and they're big. All the cross cuttng concerns of the application combine in the UI to give you as many versions as there are variables. For many sites that means there can be hundreds of unique ways for a page to be rendered. As a consultant, I see a lot of you writing templates that look like this:
<div id="product">
<c:if test="${hasErrors}">
<div class="errors">
Bid must be a number
</div>
</c:if>
<c:if test="${forSale}">
<input class="buyButton" value="Buy!" type="button">
</c:if>
<c:else>
<span id="saleMessage">Sorry, not for sale.</span>
</c:else>
<c:if test="${isAdmin}">
<input value="Delete" class="deleteButton" type="button">
</c:if>
</div>
You get tag/conditional soup, because the there are a bunch of different states that the page could be in, and you have to show/hide lots of things, or give things different colors, or whatever based on whatever state the page is in. Or maybe you list several things on a page, and some of them will be in different states than others. Or you have some button that the user isn't allowed to click because they don't have the right role.

If you have tag soup, you're doing it wrong. All of the things I described above are state, or semantically useful information. With the exception of hiding information from those who are not allowed to see it, there is absolutely no reason not to render just about everything and use CSS rules to hide and otherwise transform the page based on the current situation. Here's an example:
<div id="product" class="user${userRole} ${forSale ? '' : 'notForSale'} ${hasErrors ? 'error' : ''}">
<div class="errors">
Bid must be a number
</div>
<input class="buyButton" value="Buy!" type="button">
<span id="saleMessage">Sorry, not for sale.</span>
<input value="Delete" class="deleteButton" type="button">
</div>
And you have CSS rules like so:
.errors, .deleteButton, .notForSale .buyButton, #saleMessage { display: none; }
.error .errors { display: block; }
.notForSale #saleMessage { display: inline; }
You can't tell me that isn't simpler. It's easier to read too. All those business rules that you have translate nicely to CSS rules. Imagine that, rules begin easily represented as rules. This approach combines nicely with Ajax as well. Receive an update from the server and suddenly the item is for sale? $('#product').removeClass('notForSale'); and the browser takes care of the rest.

You might tell your self such an approach would never fly, what about security? Anyone could look at the source and see the delete button, or use Firebug to show it, then suddenly they're deleting things! Hopefully you understand the problem with that argument, but for the naive: if you're not checking permissions and validating data on the server, you're wide open to all kinds of attacks. Your rendered HTML is just the preferred interface. The real interface to your application is HTTP, and an attacker will quickly figure out what a real delete request looks like, so unless you're also checking credentials, you're screwed.

The exception, as I said before, is information that needs to stay secret. You shouldn't render some element with user passwords and hide it with CSS. Don't do it with trade secrets, launch codes or your secret pictures of yourself dressed as a drag queen either. For anything else, take advantage of one of those things about semantic markup that actually works well, and make your life simpler.

Next time: You obviously don't understand what a controller is for.

But first: Writing one liners; for readability.

No comments: