It was driven by TiddlyDocs, but I’ve been wanting one anyway for a while. Mostly because lightbox libraries generally do some hocus-pocus on page load, like applying to everything marked rel=”lightbox”, but don’t let you dynamically produce the lightbox yourself. That’s fine for pages that are just a static image gallery, but not useful to someone building a dynamic web app.

I’ve subsequently used nyromodal, on good advice, but wanted something smalller and with a simple API for my main use case, which is just showing some text.

The plugin also simplifies work by not requiring you to install a separate CSS file. Doing that, and linking to it, as well as installing any images, is something that always slows me down when I want to start using a graphical client. In keeping with the “happy path” You-Aint-Gonna-Need-It (YAGNI) mantra, I’d rather keep a library to a single Javascript file – be evil and do styling in the library by default, but still support users who want to put custom CSS in a stylesheet.

environment – massive impact on gameplay. can use it to cause problems
for AI, final fantasy – drag monster to rock where game designers
didn’t think it would be.

flow.

grinding. people doing nothing particularly intelligent or challenging
to keep moving up. (not sure what the design implication is here; if
people like it …)

hacks. constant battle between hackers and designers.

iteration. we tend to iterate to solve problems, keep refining.

jobs. different tasks.

killing. more graphical over time.

leaderboard. whatever the variable it shows, top guy gets the most cachet etc.

MMORPGs. Each has its own community, vocabulary, etc. Duality of
competition and co-operation. e.g. people waiting together for a
monster to appear. Tribal phenomenon. (Formed a “static” – same group
of people, because the only way to beat it was to work with the same
group of people, get used to their style, etc – shifted body clock to
California time.)

narrative. games becoming more cinematic. e.g. Bioshock – conveys
political message through its narrative.

“home ground advantage”: knowing about your own area helps you, e.g.
living near football stadium, you don’t go shopping. (discussion about
“match day” conditions on parking restrictions – which sport, what
match, is today a match day???)

mapumental – good example of embodying tacit knowledge locals have

kevin lynch – talks about legibility of a city.
http://www.csiss.org/classics/content/62 e.g. NYC cnr of 5rd and 27th.
easy. whereas london – easy to get lost, which is maybe why postcodes
are so specific, to compensate. Ireland doesn’t have a postcode system
outside Dublin (wot?!)
http://en.wikipedia.org/wiki/Postal_code#Ireland.

Will there be laws to prevent discriminating based on location?
Companies like BT and Royal Mail have social obligation policies.

Share this:

Questioning Alan Cooper when he says developer’s job is at conflict of
interest with user needs and difficult to treat usability

Jeff walks through his career, started out doing web tech, fascinated
by IA, got into it

Learned lessons earlier on

Five years later, started job as developer but now doing UX

Two contrasting projects: One he knows the code backwards, one he doesn’t. Interesting to see contrast between project where he knows the code and where he doesn’t. Difficult to feel like the UI is “magic” when you know the code backwards – feels more free in ignorance of the code.

Good to do lo-fi prototyping etc, but especially user testing.

Fin.

Discussion:

Can cut off options too early if put in developer arguments too early.

(me) Everyone needs to user test anyway. But I find I an detach myself as a developer and see things as a user.

Others not sure about this. example – if you’re coming up with multiple undo, part of your brain starts screaming!

Talking about advantages of coming to UX as a developer versus coming to UX as a developer. As a developer – you can’t be blagged by IT guys saying “it can’t be done”; can open up new possibilities that UX people mightn’t have been aware of.

You can have a website without designers, but you can’t have a website without developers – you can’t make it work by putting a wireframe online. So UX people need to know enough to spec it, not be blagged.

Looked at Bill Buxton – Sketching User Experiences. Lo-fi/Hi-fi – can even use video as lo-fi if keep it sketchy style production

The idea is to use human bodies to model the interaction – the humans represent different things in the UI moving around.

Reminds me of software design techniques. e.g. I recall physical versions of CRC where people represent software objects, communicating with each other. Also a good way of explaining traditional CS algorithms like bubble sort.

I participated in a demo where we were columns on a UI while a “user” shifted the columns (that is us) around.

Not only high level and sketchy, but also nice that it’s fun an light – helps people to enjoy the process.

The developers who are serving as actors in the process learn about the algorithm wh
ile they act out the parts. e.g. when I did the demo, it started dawning on me after
two or three “runs” that I need to start shifting out of the way. e.g. user says “c
olumn D, move to between column A and B”, so initially I ignore the user being colum
n E. But then I realise I’m part of the system and I have to get into gear and start shuffling along too.

Bespin has the idea of multiple backends attaching to the same client.
Right now, Python is apparently “winning” while Java has fallen behind
and PHP appears to have faded away.

The situation is very analogous to Shindig
(http://incubator.apache.org/shindig/) which has a strong Java
back-end, a PHP back-end that took a long time to get started in
earnest and AFAICT from a quick glance has tapered off, and a number
of non-starters.

I do wonder whether something like this is really viable – can you
have a vibrant ecosystem of back-ends in different languages? Granted,
there are hundreds of implementations of SMTP, FTP, and so on, in all
the languages of the rainbow. Those are actual protocols based on
strong standards. Likewise, Shindig had a fair crack at it because
it’s based on the OpenSocial standard (but the diversity effort is
probably hampered by the fact that most companies who want to be
OpenSocial hosts tend to fall in the Java camp).

Bespin would need to formalise things and establish proper standards
to support multiple backends. Nothing as onerous as the IETF
standards, but still, they’d need to nail down all the subtle issues
and edge cases in order to support multiple backends. Good for
cleanliness perhaps, but at the expense of project velocity. Years
ago, I asked SpringSource’s Rod Johnston about why one should use
Spring over the upcoming EJB3, and one of his
reasons – quite rightly – was that his code was available NOW
while the committee-driven EJB standard and subsequent implementations
were a long way off. In other words, Spring demonstrates that working,
open, code is in many respects far more powerful than a standard. I
can’t imagine Bespin will want to formally document its protocols;
instead it will rely on code. But of course, if the code is a moving
target, how easy will it be for different backends to keep up?

Also, how motivated will the second, third, and fourth guys be? It’s
more fun being the first to see the concept become reality; less so to
be building a port from one language to another. As with the previous
point, though, I stand to be corrected; some people might enjoy the
engineering challenge of building a parallel backend. (Maybe I’m being
solipsistic here, as I’m personally 20x more motivated by user stories
than implementation details.)

Java hosting is notoriously painful compared to the ease of cheap PHP
hosting, so I can see the argument for both; companies will want to
host Bespin on their own shiny enterprise Java servers, while
rebellious little startups will want to do the same thing for a sliver
of the cost on commodity iron.

Share this:

Tonight, I was thinking of making a Twitter app to manage my various accounts (I have ~dormant accounts related to projects like @webwait and @listoftweets). The app would be holding username and password details for each of these accounts, so it made sense to build it as a Single Page Application (SPA). This way, a more paranoid user could always keep the app in their local file system, while a less paranoid user could always stick the file on a protected server somewhere, having configured all the username-password details.

TiddlyWiki is a framework for developing SPAs. One might say it’s the framework for developing SPAs, since there are no prominent alternatives. So my obvious choice was a TiddlyWiki. However, not too long ago, the TiddlyWiki core guys extracted out the secret sauce for SPAs: the ingenius bit of code that saves files without requiring any browser extensions. (I’ve tried to explain this to people and it always leaves even the most brilliant minds a little dumbstruck, but yes TiddlyWiki demonstrates there are pragmatic hacks that can be used to read a file into the browser and then write it out again.) I was keen to explore this saving mechanism, so experimentation ensued.

The file management techniques ship conveniently in a JQuery plugin, jQuery.twFile. There is a basic demo which lets you edit the entire text and save it. The demo confused me at first – because it was editing the entire body of the file, I wasn’t sure how to translate that info into what I, as an application developer needed. The demo is useful for framework developers understanding the plugin, but less so for application developers. So I extracted it into a demo that is still minimalistic, but closer to the kind of thing you’d do in an application.

Once I did that, I realised what’s required is a SPA framework. In practice, most developers using twFile will be keeping all the HTML, CSS, and Javascript in a single file, so it’s possible to build a higher-level abstraction on twFile, so that developers can focus only on the content. I built the demo in a way that distinguished what was boilerplate framework code and what was application-specific HTML, CSS, and Javascript.

It was all still in one file, and that’s fine for many developers – you can give the developer the file, tell them “edit these bits”, and they can come up with something functional. I decided to extract things further though, and found the Jinja templating framework to be useful here. Jinja has a concept of template inheritance, so you can easily build up an “include” system. The net effect is I was able to encapsulate SPA logic in a single file, which was passed through a Jinja processor to produce the executable HTML document.

<li>Save this file to your local file system and open your local copy in the browser (using a file:/// URI). The browser might ask for special permission for this document, and you will need to grant it.</li>

<li>Hit shift-reload to perform a clean reload the page and observe that your message has been saved.</li>

</ol>

<h3>What is this?</h3>

<p>This is a demo of an experimental Single Page Application I am building atop <ahref="http://jquery.tiddlywiki.org/twFile.html">jQuery.twFile</a>, the file saving plugin extracted from TiddlyWiki. Forked from <ahref="http://jquery.tiddlywiki.org/twFileDemo.html">this twFile Demo</a>. Only tested on Firefox for now.</p>

</div>

{% endblock %}

{% block javascript %}

$.spa.save = function(text) {

return text.replace(/<inputid="message".*?></input>/,

'<inputid="message"value="'+$("#message").val()+'"></input>');

}

{% endblock %}

So it contains separate HTML/CSS/Javascript blocks. Probably not a good engineering practice (though it doesn’t impact on the end-user experience, which is always a single file), but it’s convenient for now. The key SPA logic is here:

As an app developer, all you have to do is override $.spa.save (which in retrospect should be renamed as it doesn’t actually perform the save). This function receives the text of the file as it was stored on disk when the page loaded. It must then return the text that should be saved to disk. Thus, it must store application state in HTML, probably by performing some kind of substitution.

Having put this together, I’m keen to proceed with the envisioned Twitter app. It’s not yet clear if there’s any mileage here over a regular TiddlyWiki, but as someone who is more familiar with starting apps from a blank HTML page (or a simple Project Deploy* template), it might end up being a more familiar way to kick an app off. Watch this space.

We are working on a design that will keep TiddlyDocs as generic as possible. The core TiddlyDocs product will have a concept of “rooms”. This is the same kind of room you see in online forums or chat sites, where everyone inside the room contributes and sees content inside the room they’re in, and can’t see or do anything about rooms they’re not in.

Our design works like this. Each room is a recipe of several room-specific bags, along with a global config bag. Each room is associated with a unique user role.

Note the role is used inside the respective bags’ policy files, and they each vary somewhat. e.g. the comments bag says readable by everyone in ‘role’, appendable (“create tiddler” permission) by everyone in ‘role’, editable by “#(role)_admin”. (ie there is a second role called “role_admin”.); whereas the content bags says readable and writeable and editable by everyone in ‘role’; and the config bag says readable by everyone in ‘role’, appendable by ‘#{role}_admin”.

For now, there’s a “makeroom” script that generates the recipe, the bags and the policies. (I’d ideally like to see the recipe be “magic” in some respects, using a wildcard mechanism).

That’s the basic design. We also have some unique challenges in this particular installation – (a) users are authenticated using a custom, enterprise-specific, single-sign on solution, where the incoming header for each request identifies user’s ID and (effectively) company; (b) we have certain rooms whose composition is manually configured and are a subset of the company’s membership, and we also have a “everyone” room which is automatically composed of everyone in the company (e.g. we might have a “megacorp-everyone” room along with the manually configured “megacorp-accounting” room, and “megacorp-marketing” room); (c) to let users allocate specific TiddlyDocs to users, we need a dropdown containing real names of all users.

BTW I’m simplifying some of the finer details here to make the discussion more pertinent to the general topic of TiddlyWeb/TiddlyDocs, rather than our specific problem. All of the following will be developed as proprietary plugins for our own installation. It’s a somewhat complicated set of requirements because it’s a real-world enterprise problem, where we have specialised requirements, combined with integration issues where we can control some things, but can’t control others. (e.g. We can’t change the underlying user store, where we would ideally store which rooms a user is in, instead of holding secondary user records inside TiddlyDocs.)

We will be building a TiddlyWeb plugin that sets the “extractor” filter. This is one of the several filters the request is subject to, on the way into TiddlyWeb. It is usually paired with the challenger filter – where challenger might present a username/password form and set a cookie, and extractor will read the cookie and set usersign (aka user ID) and any other info like users’ roles. In this case, though, we already have the header set, so we don’t need a challenger at all. We simply need an extractor that sets the usersign from the incoming header, and also notes the user’s company. Verification will then check that (a) if the user is attempting to access the “everyone” company room, they are a member of the company; (b) if the user is attempting to access a “manual” company room, they are a member of the company and they have the role associated with the company. We use a naming convention to determine which company a manual room belongs to.

On (c), we need a tiddler in the room “config” bag containing a list of user names. So in addition to the custom extractor, we will also need a periodic script to poll the user store associated with the SSO system. This will give us all the info about users in each company, so we can build up a mapping from company to list of users, where each user record has an ID and name. company->list[{user ID, user name]}. The script will then (a) rewrite the list of user names for the “everyone room” based on the company list, by effectively “copying” the results for that company (b) rewrite the list of user names for each manual room, by walking through each user, checking their roles, and accumulating their user name into the room list for each room they’re in (c) do some cleanup – removing TiddlyWeb records for any users not in the list.

There’s nothing very elegant about these custom implementations, and I’ve primarily written these details for the benefit of myself and colleagues who are implementing these custom features. The more interesting, general, point here is about open-source and plugins. TiddlyWeb’s architecture allows us deliver a generic solution for TiddlyDocs rooms, which is applicable to any organisation, and we can then superimpose a custom feature using the plugin mechanism. Furthermore, the plugin mechanism is a great way to decouple concerns – plugins are moduels on steroids. The core TiddlyDocs developer can concentrate on building an open-source, functional, multi-room TiddlyDocs edition, using the default authentication mechanism. Meanwhile, other developers can work in parallel on custom plugins.

(This post is a refinement of this post; we have been doing further thinking as we get closer to the final product and we learn more about our external environment.)

Share this:

Digg Bar launched with some controversy recently. It’s iframe trapping all over again; sites like About didn’t make themselves too popular with this technique, and so it died down until recently. I think there are legitimate uses for the top bar though; certainly the Digg Bar is useful to at least those people who are currently logged into Digg.

In fact, the reaction in the past few months suggests that top bars are here to stay. There was an initial uproar, but it seems to have been accepted, and I think top bars will start to become a fixture of the web. Given the valuable tracking data that comes from it, I can imagine dominance of the top 40 pixels of the browser window will become a big deal too…and right now, the big GYM guys (Google/Yahoo/Microsoft) aren’t doing it. Through development or acquisition, IMO that will change.

Users always trade off privacy against utility, and what can be an uproar about privacy concerns and google juice theft quickly dies down when people find value in a new feature. In this case, companies like Digg and StumbleUpon aren’t producing top bars as part of a cynical get-rich-scheme; I believe competition is too fierce to resort to cheap tricks that will get users off-side. Instead, I believe they are genuinely aiming to win, adding awesome features to improve user experience first and foremost. The Google Juice and tracking data that comes with it is a gigantic dollop of icing on the cake and top bars therefore constitute another example of having your cake and eating it too.

But this article is about web design, not web trends. An application of top bars I’ve been looking at recently is a “trails player” I’ve been building into Scrumptious lately. User creates a trail of websites for someone to visit, and each of them shows up in a trail bar at the top of the page.

To style this, I made like the web greats and peeked under the covers at a bunch of similar websites:

So the bar is absolute-positioned in the top-left, with width: 100% to span the entire width, and height set to whatever height you want for the bar. Make the iframe top margin match that height, and you’re set.

Note that the bar shouldn’t have any padding, otherwise it will add to the 100% width (padding isn’t included in the width under standard CSS box model) . So if you want padding, put it inside an inner div, like #content above.

An interesting thing is that you can set the iframe’s source, but you can’t actually detect it, because of cross-domain security, under modern browsers. Which is unfortunate. The user might start clicking around inside the iframe, after you have set its initial source URL, and you won’t actually know where they are at. Good for the user’s privacy, but bad if you want to provide certain awesome features. e.g. Digg would probably like to show the number of Diggs on any page users click over to, and StumbleUpon would like to show votes as well as related pages. In Scrumptious, I’d like to provide a “trails recorder” that automatically scoops up pages you visit into a trail…but I’ll have to achieve that with a browser extension.

And in all these cases, you probably want a “close bar” feature that would ideally work by setting document location to the iframe’s source. ie you want something like document.location.href=$("iframe").attr("src");. But that fails because the right-hand side is null. The best you can do is set document.location.href to the last URL you pointed the iframe at.

Share this:

Today, @WHAT-WG started posting weird stuff on Twitter. Turns out whatwg.org had an open form to post to its Twitter account, right on the homepage. The interesting thing is it sat peacefully for two years on the homepage of a relatively prominent organisation’s website, until someone started being funny, and then others noticed, and by the end of the day…it’s in lockdown, with a password attached to the form. Still fairly open as you can apparently ask for the password in IRC.

Share this:

G’Day

Welcome to Michael Mahemoff's blog, soapboxing on software and the web since 2004. I'm presently using HTML5 and the web to make podcasts easier to share, play, and discover at Player FM. I've previously worked at Google and Osmosoft, and built the Ajax Patterns wiki and corresponding book, "Ajax Design Patterns" (O'Reilly 2006).
For avoidance of doubt, I'm not a female, nor ever have been to my knowledge. The title of this blog alludes to English As She Is Spoke, a book so profoundly flawed it reminded me of the maturity of the software industry when this blog began in 2004. I believe the industry has become more sophisticated since then, particularly the importance of UX.
Follow @mahemoff