writing tiddlywiki plugins is fun

rjbs on 2007-06-04T12:44:39

I've finished converting all my OmniOutliner and LaTeX notes to TiddlyWiki, and along the way I've found a few things I didn't like or that I thought were missing. Rather than just bitch, I though I'd fix these problems, and doing so has been a load of fun. Hacking on TiddlyWiki gives me the same kind of joy and awe that I felt when I first started programming in Ruby. In a lot of ways, I think TiddlyWiki is what Kwiki wants to be. Nearly everything builds atop a few simple structures, and everything is pluggable. Writing plugins is easy, editing templates is trivial, and only a very few lines of code are needed to add new features.

=== problem one: multiple tiddlers per page ==

The unit of content on a TiddlyWiki is the "tiddler," which is equivalent to a "page" in most wikis. When you use TW, clicking on links opens the new tiddler below all the other open tiddlers and sends the browser focus down to it. This means that as you work, you have more and more tiddlers open. This might make sense if you're really editing "microcontent," whatever that is, but for longish pages, it can get quite annoying.

I thought about trying to fix this, but then found an exiting plugin at TiddlyTools. To import a plugin, you provide your TW with a URL to another TW. It fetches it and lists all the tiddlers in it. You select the ones you want and hit import -- then they're in your TW.

This works for plugins because plugins are just tiddlers. They're special, but only just barely. They are tagged with "systemConfig" and are evaluated as JavaScript. To add your own plugins, you just make new tiddlers. To add someone else's, you just import them.

I installed the "SinglePageModePlugin" and that was that, problem solved.

=== problem two: jumping to a page ===

Sometimes, I'm editing a tiddler and I have an idea or remember something that I need to write down in another tiddler. As far as I can tell, I have three options to get there:

  1. navigate there
  2. search for the page name, wait for the search to complete, and click it
  3. edit the URL to put the page name in the fragment, then reload

All of these take too long and are stupid. I want to be able to type "Illithid" and go to that page. Adding this feature was trivial.

I made a new tiddler called GotoboxMacro, then wrote a little JavaScript on it. The JavaScript is simple: it adds an object to config.macros, and that object has a handler method. It's called with the location in the document where the macro appeared (and other arguments) and it adds content there. In the case of a gotobox, it adds a text input that listens for carriage returns and, when they occur, close all open tiddlers and open the one named in the box. It's also got an access key, so I can hit control-G to goto goto. Total code: about 25 lines.

=== problem three: the missing link page ===

There's a core macro called "list" that lists things. It can "list missing" to show you tiddlers to which you've linked, but which don't exist. Unfortunately, it didn't work for tiddlers linked to with the "forced link with title" syntax:

[[mind flayer|Illithid]] 

Fixing this was simple enough: I fired up firebug, traced the method that updated each tiddler's list of links, and found a stupid logic error. One line-change later, it worked. (It also turned out that this was fixed in a better way in Subversion, but I didn't know that until I was done!)

=== problem four: linking forward from a tiddler ===

Every tiddler displays the toolbar. The toolbar displays a selection of "commands", which are defined much like macros. One of the core commands is "references," which pops up a menu of tiddlers that link to the current tiddler.

I wanted something that did the reverse: since my content is sometimes long, I wanted a way to see all the pages to which I linked, so I could jump forward without searching for the link on the page. I wrote a command called "links" that did just this. I created an object in config.commands with a handler method. It uses TW's methods to get the current tiddler, find its links, create a popup menu, and add the links to it. Total code: about 25 lines.

=== problem five: sharing my plugins ===

Well, these plugins were really useful to me, and I want to share them. Given the way that plugin importing works, this is trivial: I created a new, empty TiddlyWiki, then imported the plugins to it, then published it on my web server. Now anyone else can import those plugins to their TW.

TiddlyWiki is fantastic! Now all I need is for the JavaScript vi script to be licensed such that I can use it on my TW.

Come use my plugins.


thanks for tiddlywiki notes

markjugg on 2007-06-04T17:45:19

Thanks for your sharing your notes on Tiddlywiki. It sounds like something I might enjoy, too. Now it's on my radar.

TiddlyWiki for Module Dependencies

Ron Savage on 2007-06-05T02:23:03

I work on 10 SunFires which have no internet access, or mutual access for that matter, so I use TiddlyWiki to track module dependencies, so I can install a set of modules in the 'right' order, with a minimum of pain. And yes, I have a shell script to install them in bulk mode. I've just switched to TiddlyWiki from TreePad, which I very much like. However, I wanted something not so bound with MS Windows...

Re:TiddlyWiki for Module Dependencies

rjbs on 2007-06-05T05:56:16

funny you should mention dependencies...

http://use.perl.org/user/rjbs/journal/33429

Failed to utilize your plugins

Ron Savage on 2007-06-05T05:52:13

I'm using version = {major: 2, minor: 1, revision: 3, date: new Date("Nov 3, 2006") of TiddlyWiki.
I tried LinksCommand, but could not get it to display anything (yes, saved and reloaded).
With GotoboxMacro, the very first time I used it, FireFox opened the Find dialog at the bottom of the page. After that, each use of ^G just made the cursor jump to the next occurrence of the text I'd typed. The input field was never updatable to search for a different string.

Re:Failed to utilize your plugins

rjbs on 2007-06-05T10:45:42

How odd. Let me spell check your brain here: after you'd installed the LinksCommand, you added it to the toolbar macro call in ViewTemplate? You added > to the sidebar in SideBarOptions?