The Canonical Design Sketch

We’re having a TiddlyWeb fest tomorrow, and I explained one of the things I want to get out of it is a canonical design sketch.

Luke Hohman’s superb text, Beyond Software Architecture, explains how he comes into a project and asks people to draw the architecture. A great predictor of the project’s state is whether people come up with the same diagram. Put crudely, if they are all on the same page – if they all know module X is in the top-right and module Y is centre left – the project is onto a winner.

I’ve found similar things myself. I will work on a project for a while before someone puts up a poster depicting the emerging architecture. People will then find themselves congregating around the poster and building it up.

While some people are more visual than others, I believe most of us have good spatial abilities and a team has a lot to gain from a shared understanding of the architecture. This is even more so in the case of a framework like TiddlyWeb, where the community is disparate and connected much more loosely than a group of agile developers in a room together.

A good example of a design sketch is that by a project with some similarities to TiddlyWeb: CouchDB.

I like the fact it’s a sketch, not a boring old “formal” diagram. Diagrams that are too neat are also brittle, whereas simple sketches are resilient to change. Moreover, I like the fact it’s on the homepage. That makes a bold statement to the community. This is the canonical design sketch for the project, and any discussions around architecture will naturally be couched around this sketch and the entities within.

Scrumptious Update: Open ID Support, UI Enhancements

I’ve released a new version of Scrumptious. Main change is it now supports Open ID. You can click a “login” link to comment by Open ID. It’s optional by default, though a Scrumptious site operator could easily make it mandatory for read, write, or both by just changing a couple of words in the “policy” config files. Similar to other CMSs like WordPress, non logged in users can indicate their name and URL when they submit a comment.

There are also UI enhancements – the design is cleaner and looks closer to the original original TiddlyWiki comments plugin. Interestingly, I retained almost identical markup, so I was able to cut-and-paste the original CSS for the comments plugin and it mostly worked. I also now include the default TiddlyWiki stylesheets as well. It’s not just look-and-feel which is closer to the original plugin, but the content – you now have info like modifier, modified date, and a permalink available.

I also added something I always wanted to add on the original plugin, which is some animation, e.g. when you add a new reply, the page scrolls to that reply, and a yellow fade effect highlights it. This is a genuinely useful feature as I was finding it difficult to see which reply I’d just added, when there are a lot of comments around.

I’ve also begun work on a Comments Report showing recent comments. Obvious related enhancement is to take the TiddlyWeb Atom plugin and make a comments feed.

Right now, all this is only tested on Firefox (the original was tested on all browsers, at least the full website view); my next priority is to work on browser compatibility, and after that, extract a modular JQuery comments plugin.

Implementation Notes

Regarding the implementation, TiddlyWeb ships with Open ID by default (Open ID is one of two default challengers, the other being the usual simple user-pass key pair config). The most challenging thing here was getting the UI right for both anonymous users and logged in users, as well as handling a redirect in the popup after a successful login; but at the back end, Open ID “just works”.

In summary, I added Open ID support as follows:

  • Add a “login” link to the TiddlyWeb OpenID challenger UI, using a “target” attribute so the challenger opens in a popup.
  • The challenger URL in that link also contains a redirect param, which I redirected to a new static page. This static page shows the user their login ID (by inspecting the “tiddlyweb_user” cookie value), calls a callback “onLogin” method on the original page, and closes itself.
  • The “onLogin” callback updates the login display to show the logged in user and a logout link; the logout link simply runs some Javascript to remove the cookie. The callback also updates any forms that are open prompting for bio info; it hides this info and in its place, shows the current user ID (read-only).

Thanks to Ben and Chris for pointing me in the right direction on TiddlyWeb’s Open ID support.

PS I discovered late in the day (literally) that TiddlyWeb lets the client specify whatever modifier they want

When Resource IDs are URLs

Being a web app about websites and other resources, Scrumptious has a resource which is basically a URL, called “Pages”. A Scrumptious resource modelling google.com/about looks like:

http://scrumptious.tv/comments/bags/ pages/tiddlers/http%3A%2F%2Fgoogle.com%2Fabout

See? The resource ID is http://google.com/about, encoded. (encodeURIComponent("http://google.com/about")

This was working fine on my dev machine, running “twanager server comments.boz 8080″ (comments.boz being an alias for my local machine). But on the server, and run through apache and TiddlyWeb’s apache.py, it failed:

The fix was twofold – both of the following were required:

  • AllowEncodedSlashes On in apache config. This option ensures encoded slashes (%2F) are passed through to the end-app.
  • PathInfoHack plugin As with any TiddlyWeb plugin, I downloaded it and added it to ‘system_plugins’ list in tiddlywebconfig.py. (Thanks Chris for the pointer.)

And now we can happily talk resources with URLs as IDs to the server.

Add-On Collections: A Trail Framework for Firefox Goodies

Moz has begun Add-On Collections (via Ajaxian):

Today, we’re excited to introduce a new feature to our website that will expose the niche add-ons that can be hard to find, and gives users a more active role in helping outstanding add-ons bubble to the top. One thing we’ve learned as add-ons have grown in popularity over the years is that once a user finds an add-on they love, they become a fan for life. We see this all the time as people recommend add-ons to their friends and write great reviews. And we’re very happy to see so many bloggers writing about lists of their favorite add-ons.

Now this is interesting for a couple of reasons. Firstly, it’s an example of the URL Trail pattern; Firefox Collections is a framework allowing people to publish and share a collection of links; very similar to Amazon’s “So you want to …” ListMania. It adds the ability to do something that neither I, nor Vannevar B. mentioned about trails: the ability to subscribe to a trail, in order to see changes made, e.g. Here is the RSS feed for the Social Circuit collection.

The second hotness about Collections is the fact that Firefox add-on management is getting easier. You can click on a bunch of add-ons, like adding them to a shop cart, and install them all in one go:

It takes Firefox closer to where it should be IMO, in which add-ons are easily installed with one click, and distros are available for specialised needs, e.g. a developer build containing Firebug and other dev tools. Moz themselves might be wary of blessing certain extensions in this way; so the ideal situation might be if they were to provide a framework like Collections, where anyone can propose a bundle and the best bundles rise to the top, with a way to yoink a Firefox build containing all the add-ons in a collection.

TiddlyDocs, TiddlyCMS, and Permissioning Models

We’re designing a setup for TiddlyDocs (and potentially other “TiddlyCMS”s) where there will be an instance for each group of contributors. This is one TiddlyWeb design pattern, where you say “we all trust each other” (although there are still audit logs!) and so everyone can add, delete, or modify all the content freely. That is, there is only one content bag accessible to all. Likewise, anyone can append comments. There is still an admin role for setting up config stuffs, which only the admin can change; otherwise, any user could easily perform a phisihing attack, for example. Users also have private bags which they can do what they like with – they could use it for drafts, or for overriding shadow tiddlers setup by the admin in config.

A rough sketch looks like this:

(Some things need fixing, but the overall idea is conveyed.)

I discuss more about this architectural pattern with Jon in the following video:

TiddlyDocs Architecture from Michael Mahemoff on Vimeo.

Now that model alone is good enough for basic cases, where you have a group of people who work together and just want to set up an instance. TiddlyWeb handles that just fine, even using the basic cookie authentication technique. In more complex situations (read: “enterprises”), you have a many-to-many relationship between users and instances. I was talking with TiddlyWeb’s architect, Chris Dent, about possibilities, and we decided on one possible model:

A central user-to-pool mapping database, which is shared by three web apps: (a) all the TiddlyDocs’ servers, specifically their Challenger module; (b) an admin app for managing the mappings (typical Django/Rails app with forms generated from data model); (c) a user-facing app (possibly a gadget in our envisioned OpenSocial scenario) showing the user (already authenticated via single-sign-on) a dropdown of instances they can launch.

Scrumptious: Conversations About Websites (and other resources)

Scrumptious is a web framework I’ve begun working on at Osmosoft. It’s a web app and web service for sharing bookmarks and comments about websites, and pretty much anything else with a unique URL. Things it is related to: Delicious (bookmarking), Digg (threaded comments), JS-Kit and Disqus (embedded comments with common identity across multiple sites).

Scrumptious is open source, under the BSD license (meaning you can do just about anything you like with it). There are already many open-source clones of this sort of thing, so why make a new one? There are a few reasons:

  • Adherence to RESTful principles – Scrumptious is backed by TiddlyWeb, a RESTful data service.
  • A non-TiddlyWiki TiddlyWeb client – So far, people who have used TiddlyWeb as a server have used TiddlyWiki as a client. They do play nicely together, but TiddlyWeb is a powerful RESTful framework on its own. Part of the motivation for Scrumptious was to port the TiddlyWiki nest comments plugin to a generic JQuery plugin that could be used on any web page. (Comments are indeed implemented as a plugin right now, but more work needs to be done to extract it into something truly modular and reusable; for example, the plugin right now assumes comments are about a web page; also, they are tied to TiddlyWeb. Nevertheless, the app still does achieve the main purpose of demonstrating TiddlyWeb is a fine data service for generic web apps.)
  • Demonstrating the power of URLs – In evangelising web standards, a very practical piece of advice is simply to associate a unique URL with each distinct resource. That’s REST 101, but it’s something lacking in many web apps. With a tool like Scrumptious, you get a comment system “for free” as long as each resource in your system has a unique URL. We’ll be developing a similar framework for URL Trails in the future, and the same principle applies: use unique URLs, and people can put your stuff in trails “for free”.
  • Flexible security model – Again, TiddlyWeb offers flexible permissioning, so you can use the app in different ways. e.g. a private conversation between colleagues; a public conversation (as with the demo), a publicly readable conversation where only certain individuals can contribute, etc. Likewise, TiddlyWeb offers flexible authentication, so you could hook into an organisation’s LDAP system, use open ID, simple user-password pairs, or any other form of authentication you wish to use.

Scrumptious is still at an early stage. Future work includes:

  • Bookmarking – for now, there is only commenting rather than social bookmarking per se.
  • Nested comments UI needs work to give it the same kind of UI as in the TiddlyWiki comments UI. e.g. show info like creator and creation data, and use suitable rendering and indenting.
  • Graceful degradation – It would be possible to provide a basic system not requiring Javascript. This would be probably be done using TiddlyWeb plugins, though I’d also be interested in running the JQuery-powered web app on the server, using server-side Javascript.
  • TiddlyWiki comments plugin harmonisation – As TiddlyWiki now ships with JQuery, it would be ideal if there was a single code base for the comments plugin, running in and out of TiddlyWiki. Indeed, I hope TiddlyWiki moves towards a general microkernel architecture, in which all plugins are useful outside TiddlyWiki. This is certainly becoming the case, with generic JQuery plugins being extracted for core activities like file saving, CSS applying, and wikifying.
  • Browser extensions – instead of a bookmarklet, use a browser extension to show, for each page, if comments are available, as well as bookmarking info. (Similar to the StumbleUpon or Delicious Firefox extensions.) A good opportunity to get my hands dirty with JetPack.
  • Login and identity management – while TiddlyWeb already provides the security and permissioning model, work is required to handle this at the UI level. For example, let anonymous users enter their email address and homepage, and/or register.
  • User admin – for situations where users must be authenticated, some form of user management would be handy. Again, TiddlyWeb provides a good model for this – a “bag” of tiddlers has its permission specified in JSON, which may include a list of users for each access type, so you simply need to PUT and GET this if you are sufficiently permissioned (ie an admin). What’s missing right now is a UI (in TiddlyWiki too, let alone standalone web apps).

Scrumptious Screencast:

<

p>Scrumptious from Michael Mahemoff on Vimeo.

What’s the Maximum Z-Index?

Z-index is the CSS property governing how high in the stack an element is, if you visualise the elements as appearing in a 3D stack coming out of the page. The actual value of an element’s z-index doesn’t matter; just its value relative to other elements on the page. Elements with higher z-indexes appear on top of elements of lower z-indexes.

I was just designing a bookmark for Scrumptious (a TiddlyWeb powered tool to have discussions around websites; I’ll talk about it in a future article). And with a bookmarklet, I need it to appear above everything else on the page. So it needs a higher z-index than everything else. Maybe not the highest z-index possible, since there might be apps that need to sit above my app’s bookmarklet (Design For Extensibility). But I still need to know the maximum z-index.

It would be nice if the standards publshed the maximum allowed z-index. Every reference always makes a comment like “there’s no real limit”. For good reason too, since the W3C standards don’t really cover this. The CSS Spec (2.1) goes so far as to include an “Elaborate description of Stacking Contexts”, and it’s even called “zindex.html”, but even here, omits to pin down the max z-index value.

A handy summary was stated on StackOverflow (which has fast become the central resource for programming FAQs and a site I have quickly come to adore for its clear mission, clean design, and community feel):

So basically there are no limitations for z-index value in the CSS standard, but I guess most browsers limit it to signed 32-bit values (−2147483648 to +2147483647) in practice (64 would be a little off the top, and it doesn’t make sense to use anything less than 32 bits these days)

Looking further, I came across the most comprehensive summary of the situation, published recently. It also highlights the fact that it’s not just the maximum value we want, but what happens if we exceed it.

I made a simple test page to find these limits and figure out what happens when you exceed them.

Browser Max z-index value When exceeded, value changes to:
Internet Explorer 6 2147483647 2147483647
Internet Explorer 7 2147483647 2147483647
Internet Explorer 8 2147483647 2147483647
Firefox 2 2147483647 *element disappears*
Firefox 3 2147483647 0
Safari 3 16777271 16777271
Safari 4 2147483647 2147483647
Opera 9 2147483647 2147483647

So the best way would be to use browser detection and pick the max from there. But if not, use 2147483647.