I’ve just pushed version 0.4-beta1 of sacy to its github repository. Aside of requiring PHP 5.3 now, it also has support for transforming contents of inline-tags.

So if you always wanted to write

<script type="text/coffeescript">
hello = (a)->
    alert "Hello #{a}"
hello "World"
</script>

and have the transformation done on the server-side, then I have good news for you: Now you can! Just wrap the script with {asset_compile}...{/asset_compile}.

I’m not saying that having inline-scripts (or even stylesheets) is a good idea but sometimes, we have to pass data between our HTML templates and the JS code and now we can do it in Coffee Script.

Development note

When you take a look at the commits leading to the release, you will notice that I more or less hacked the support for inline tags into the existing codebase (changing the terminology from files to work units in the process though).

Believe me, I didn’t like this.

When I sat down to implement this, what I had in mind was a very nice architecture where various components just register themselves and then everything falls into place more or less automatically.

Unfortunately, what ever I did (I used git checkout . about three times) to start over, I never got a satisfactory solution:

  • sometimes, I was producing a ton of objects, dynamically looking up what methods to call and what classes to instantiate.

    This would of course be very clean and cool, but also terribly slow. Sacy is an embeddable component, not an application in its own right.

  • sometimes, I had a simplified object model that kind of worked right until I thought of some edge-case at which point we would have either ended up back in hack-land or the edge-cases would have had to remain unfixed

  • sometimes I had something flexible enough to do what I need, but it still had code in it that had to know whether it was dealing with instances of Class A or Class B which is as inacceptable as the current array-mess.

In the end, it hit me: Sacy is already incomplete in that it simplifies the problem domain quite a lot already. To cleanly get out of this, I would have to actually parse and manipulate the DOM instead of dealing with regexes and I would probably even have to go as far as to write a FactoryFactory in order to correctly abstract away the issues.

Think of it: We have a really interesting problem domain here:

  • the same type of asset can use different tags (style and link for stylesheets)
  • Different attributes are used to refer to external resources (href for stylesheets, src for scripts)
  • File-backed assets can (and should) be combined
  • Conent-backed assets should be transformed and immediately inlined
  • Depending on the backing (content or file), the assets use a different method to determine cache-freshness (modification-time/size vs. content)
  • And last but not least, file based asset caching is done on the client side, content based asset caching is done on the server-side.

Building a nice architecture that would work without the ifs I learned to hate lately would mean huge levels of indirections and abstractions.

No matter what I tried, I always ended up with a severe case of object-itis and architectur-itis, both of which I deemed completely inacceptable for a supposedly small and embeddable library.

Which is why I decided to throw away all my attempts and make one big compromise and rely on CacheRenderer::renderWorkUnits to be called with unified workunits (either all file or all content-based).

That made the backend code a lot easier.

And I could keep the lean array structure for describing a unit of work to do for the backend.

I would still, at some point, love to have a nice way for handlers to register themselves, but that’s something I’ll handle another day. For now, I’m happy that I could accomplish my goal in a very lean fashion at the cost of a public interface of the backend that is really, really inconvenient to use which leaves way too much code in the fronend.

At least I got away without an AssetFactoryFactory though :-)



blog comments powered by Disqus