Peer Pressure

Stuff to look at about looking at stuff. From Chris Dent. What?

Archive

Feb
9th
Mon
permalink

TiddlyWeb Plugin Tutorial Part 2

Update 20091113 to reflect current TiddlyWeb state of the art.

This is the second part of a multi-part tutorial for creating TiddlyWeb plugins. See part one.

In part one we set our Content-Type to text/html and our status code to 200 with a start_response call like this:

start_response('200', [('Content-Type', 'text/html; charset=UTF-8')])

It’s quite likely we’re going to make that very same start_response call pretty often, so there is some code you can use so you don’t have to write it. Install the tiddlywebplugins.utils package to get some useful decorators and other methods:

sudo easy_install -U tiddlywebplugins.utils

You can see some basic documentation for the available functions by:

pydoc tiddlywebplugins.utils

Let’s use do_html and entitle to get rid of some common code. To the top of the file add:

from tiddlywebplugins.utils import do_html, entitle

change the jinx function so it looks like this:

@do_html()
@entitle('Hello World')
def jinx(environ, start_response):
    return ['<h1>hello world</h1>']

Start the server (note that in the configuation of TiddlyWeb, for every code change you need to stop the server and then start it again), go to /jinx, and view the source of the generated page. Where did all that extra stuff come from? do_html() makes the response Content-Type be text/html but all entitle does is set tiddlyweb.title in environ. Where is the extra HTML coming from? What is that ‘User GUEST’ doing?

That extra HTML is coming from yet another WSGI application, called HTMLPresenter which modifies outgoing HTML, if tiddlyweb.title is set, to add bounding HTML, and set the value of <title>. Advanced TiddlyWeb plugins can modify or replace HTMLPresenter but we won’t get into that here.

Private Hello World

‘User GUEST’ is showing the currently active user. If no login has happened, then the current user is GUEST. Let’s require a user at /jinx by making this change to the code:

@do_html()
@entitle('Hello World')
@require_any_user()
def jinx(environ, start_response):

Start the server. Whoops, there’s been an error:

NameError: name 'require_any_user' is not defined

We need to make sure we have the necessary code. Change the import line to look like this:

from twplugins import do_html, entitle, require_any_user

Now start the server. Reload /jinx. You should see “Login Challengers”. Click on the one with openid in the name, enter a valid openid, and allow TiddlyWeb to have access to your info. Eventually you’ll get back to the jinx page and where it used to say ‘GUEST’ it will now say your openid.

require_any_user checks to see if there is a user other than GUEST and if not, asks TiddlyWeb to redirect to its challenger system: tools for authenticating a user.

Personalized Hello

If /jinx is private it’s not really the world we are saying hello to, is it? Let’s have TiddlyWeb say hello to you:

    username = environ['tiddlyweb.usersign']['name']
    return ['<h1>hello %s</h1>' % username]

When you restart the server, and reload /jinx it should now say “hello ”. Woot! Personalization.

tiddlyweb.usersign is a data structure containing information about the current user. The current is extracted from the current HTTP request by a thing called a “Credentials Extractor”. TiddlyWeb can support multiple extractors. The interface is described in tiddlyweb.web.extractors. An extractor WSGI application is called before the selector dispatch application, which means every request is scanned for user information.

Go to part three

Comments (View)
blog comments powered by Disqus