Now, this doesn't mean I cloned Tiles in Spyce. I took the usual Spyce approach of adding functionality found in the JSP world without adding all the complexity. (Actually, in this case it's actually more influenced by the OpenACS master and slave tags, but how many people would that mean anything to? :)
Specifically I added a way to create consistent site layout templates in the reverse-include style familiar to users of all modern web frameworks. (No, ASP.NET isn't modern by this definition. But ASP.NET 2.0 will be. They call it "Master pages," and googling for that is an excellent way to find a lot of people talking about how this is the best thing since sliced bread. This entry is long enough without me reiterating the reasons why this is a Good Thing.)
Instead of including header and footer in your content page, your content page declares that it belongs to a parent page, which defines all your common markup and a placeholder for the child. Simple example:
child
<spy:parent title="child title" /> Child content
parent
<html> <head> <title>[[= child['title'] ]]</title> </head> <body>[[= child['_body'] ]]</body> </html>which results in the final html of
<html> <head> <title>child title</title> </head> <body>Child content</body> </html>
This is both recursive and dynamic.
Recursive, in that one parent template can itself be the child of another. This is useful wherever you have shared content or navigation on a group of pages; you can make them children of parent1 which is a child of your master parent, so site-wide changes still only need to be made in one place, and changes affecting only this group are also only made in one place.
Dynamic, in that all the arguments to spy:parent are evaluated at runtime, even the src argument. Here's an example that doesn't do much except demonstrate this:
[[ import os cwd = os.getcwd() s = '/parenttable.spy' ]] <spy:parent src="=s" foo="=cwd" />This results in the template located at /parenttable.spy being used instead of the default, and an argument named foo being passed with the result of the getcwd evaluation. (Changing which parent template to use at runtime is primarily useful for localizing different languages; passing other parameters that are evaluated at runtime is something you will use frequently even if you only care about English.)
In my opinion it's a phenomenal example of how robust Rimon's Spyce framework is that the diff for this changeset is only about 70 lines. Spyce is one of those rare projects that's a real pleasure to work on because the original author found just the right balance between thinking for future extensibility and overengineering. Tough line to walk, and Spyce does it well.
Comments
ASP.NET 1.1 and 1.0 support "master pages" - it's just that for 2.0, Microsoft has provided better IDE support via the next version of Visual Studio (the designer will show the page elements in a fancier way than do the previous versions) and it is now more formalized, with a specific abstraction for people who are unable to handle the OO concepts that would allow them to do the same with the current version. I have used templates for a while in ASP.NET, just as many other users have. It is unfortunate but true that there are simply a lot of 'developers' using Microsoft products that don't think something is possible unless MS provides it to them on a silver platter and give it a nice marketing term. Sad, but true. Object/Relational mapping is a perfect example of this. I currently know quite a few people fighting the idea of it, but I bet as soon as Microsoft comes out with their "official" version of an O/RM tool, they will jump on the bandwagon.
There are many ways of implementing it in those older versions, I use their PlaceHolder controls and inheritance (a base page class) to create my own templates, and it works fine (the specific technique was one I learned from Dino Esposito's ASP.NET book). I guess my main point is that we don't have to wait until MS puts a pretty name on something to get it to work, as long as we know what we are doing with regards to OO and such; since ASP.NET supports OO constructs, I can make my own abstractions.
Anyway, I think you get my point. :P
Uh, anyway.
I should have a beta out this week, and things will be even more stable then. I'll have a look at the makefile, but you don't need it if you co from svn -- just run spyceCmd.py -l and you're off.