Developers: Total Site Customization, part 2


Lots of customers have expressed interest in EditMe's Total Site Customization project that I wrote about previously. I wanted to provide an update on our progress to date. This post is largely intended for our more technical customers and developers who may be interested in using EditMe as a deployment platform for their sites and applications. It gets pretty geeky, so I thought that warning was in order.

After a lot of research and hemming and hawing, we have selected and implemented a new technology to replace XSL layouts. Along the way I've become intimate with just about every web templating technology in existence. We had a few fairly straightforward requirements, largely based on the shortcomings of the current XSL system:

  1. Layouts should be readable by humans who know HTML, and editable in existing HTML editors. 
  2. Scripting of any kind should be in a language familiar to our target audience.
  3. Doing simple stuff should be really simple, and complex stuff should be doable.
  4. It needed to work within our existing technology platform: Java.

After reviewing and testing dozens of options, we were unable to meet all of these requirements, so we did what we didn't really want to do... we built our own.

Now that it's working on development servers, I'm convinced this was the right choice. I truly believe what we've come up with is something new and an improvement on what's available. The rest of this post takes a sneak peak at this new technology and shows how it will take EditMe to the next level as a content management platform. (And this is where it starts to get real geeky.)

What we actually developed is a fairly thin conceptual wrapper around a few complimentary open source technologies. The main players are Rhino, a.k.a Mozilla's JavaScript engine, and DOM4J, the XML library that has been the workhorse behind EditMe internals from the beginning.

The idea that ties these together, and what makes the solution unique, is something we call attribute scripting. By combining some simple XML concepts, a little JavaScript, and about a dozen simple commands, an EditMe layout achieves all of our design goals, and then some.

Attribute scripts are tiny, sometimes one word, scripts placed in "editme" attributes of HTML tags. These scripts are processed on the server when the page loads, and act on the layout itself as an XML document. They also have at hand a simple JavaScript API that provides access to all the data in the site's database. Without further ado, let's look at a small sample (the line numbers are just for clarity and are not part of the layout):

1  <html>
2     <head>
3         <title editme="text site.title">Site Title</title>
4     </head>
5     <body>
6         <h1 editme="parse">{page.title}</h1>
7         <div editme="cdata page.content">content goes here...</div>
8         <p editme="if user.isLoggedIn;; parse">Hi, {user.name}!</p>
9     </body>
10  </html>

So here we have a complete (though admittedly simple) layout in 10 lines. It should be fairly clear what it does just by looking at it, and it can be viewed as-is in any web browser or edited in all but the most draconian HTML editors. Let's walk through what's going on here line by line.

Line 3 contains the first inkling that this is more than just plain HTML. The "editme" attribute in the title tag contains an attribute script. The first word of any attribute script is called the command. There are only about a dozen different commands, so learning them doesn't take long. Most commands accept one or more arguments separated by a space, and many times the last argument is a JavaScript expression. In the case of the "text" command, which replaces the contents of its tag with some text, any JavaScript that results in a string value can be used. Here, site.title simply returns the title field of the site object provided as part of EditMe's simple JavaScript API. The "Site Title" text in the tag is just there for show - it will be dynamically replaced by the value returned by site.title when a page is requested on the site. 

Line 6 shows another way to insert text dynamically. The "parse" command replaces {squiggly brackets} found in the contents of the tag with the results of their JavaScript expressions. For example, <p editme="parse">Here is a {'little ' + 'test'}.</p> would end up as <p>Here is a little test.</p> because the JavaScript expression results in a string with the value of "little test". This makes it easy to mix in dynamic content with static layout content.

Line 7 shows use of the "cdata" command. This command works just like the "text" command, but the content is not escaped for XML. Page content is HTML, so we want it to be inserted as HTML, not as text. CDATA is an XML term for content that should not be escaped. For example, <p editme="text '<b>bold</b>'"></p> would result in <p>&lt;b&gt;bold&lt;/b&gt;</p>, while <p editme="cdata '<b>bold</b>'"></p> would result in the more desirable <p><b>bold</b></p>. The page.content expression in this example references the page object, which is part of EditMe's JavaScript API and contains everything we need to know about the page currently being displayed.

Line 8 shows us two commands in a single attribute. Two semi-colons are used to separate multiple attribute commands. (A single semi-colon can be used to separate multiple JavaScript statements within a single JavaScript argument.) As you may have guessed, the "if" command only includes the tag if the JavaScript expression returns true. This makes it simple to have conditional sections of content. In this example, we only show the "Hi!" message if the user is logged in. Then we have a "parse" command to insert the user's name in the message.

So that's a simple example. Obviously, there's a lot more to it. For example, <script> tags can be used to define server-side JavaScript libraries so code within attribute scripts can be kept to an absolute minimum. You'll be able define functions and class libraries in a script and use them from your attribute commands (though for all but the most complex layout customizations this will not necessary). The JavaScript also has full XML-level access to the layout it's running within using the powerful DOM4J API. This is like traditional JavaScript DOM on sterioids, and allows an XML-aware developer to do some pretty advanced stuff. And, of course, we've just touched the surface of EditMe's JavaScript API which can be used to access data in the site's database, including pages, comments, attachments, users, etc.

In addition to the new layout language, some of the other features bundled into this release include:

  • Management of CSS style sheets and Layouts as normal EditMe pages, complete with versioning, diff, etc.
  • The ability to over-ride the site layout and style sheet at the individual page-level.
  • The beginnings of a package system. Skins are now zip files with a simple description file explaining how it should be installed. This doesn't mean much now, but down the road will allow functionality to be easily bundled and distributed to multiple sites.

Some of the stuff we're excited to be able to do once this new release is finished includes:

  • Site-level customization of system pages, like the Login page, Registration form, etc.
  • WYSIWYG layout editing should be possible given the HTML compatible nature of the new layouts.
  • Develop the new package system to allow sharing of skins and bundled site features.
  • Server-side script-only pages that can update and create content. (The layout scripts cannot do this.)

I'm excited to see this working on our development servers, and even more excited at the possibilities this opens up for the features and services we'll be able to build on this technology. After working with dozens of open source and commercial content management platforms in my years as a web development consultant, this technology is by far the most elegant, simple and powerful of all the systems I've seen. Barring some unexpected catastrophe during testing, this release should be available in September or October. It won't be long now! 

Stay Connected with EditMe

Subscribe via Email

Your Email:

Delivered by FeedBurner