Hi Devin Great stuff.
I'd be in favour of adding an API like this to the core. In fact, the very first version of TiddlyWiki5 was based around a jQuery-like chainable API: https://github.com/Jermolene/TiddlyWiki5.2010.alpha/blob/master/js/%24tw.js There's a ticket for making the APIs friendlier: https://github.com/Jermolene/TiddlyWiki5/issues/507 Best wishes Jeremy On Sun, Apr 20, 2014 at 2:45 PM, Devin Weaver <[email protected]>wrote: > *Original text/vnd.tiddlywiki version attached.* > > I was recently working on a macro for handling the creation of links to > our ticket system. Instead of copy pasting the whole URL I can place the > ticket number in the TiddlyWiki <http://localhost:8080/#TiddlyWiki> text > and the macro will build the URL and > WikiText<http://localhost:8080/#WikiText> link > for me. > > One of the requirements was that it could grab the ticket number from a > tiddler's field so that if you called the macro without a ticket number it > would still have a sane default. For example: <<jira IOS-200>> would > become [[IOS-200|https://mycompany.atlassian.net/browse/IOS-200]] and if > I set the ticketfield to IOS-300 on a tiddler and call <<jira>> it would > output [[IOS-300|https://mycompany.atlassian.net/browse/IOS-300]] > > When making the plugin I tried desperately to find the current tiddler ( > currentTiddler) only to realize this isn't a Tiddler object but a string > for the current tiddler's title. And to get the current tiddler and > subsequently the field from the object, I had a few intermediary steps to > take: > > exports.name = 'jira'; > exports.params = [{name: 'ticket'}]; > exports.run = function(ticket) { > if (!ticket) { > var title = this.getVariable('currentTiddler'); > var tiddler = this.wiki.getTiddler(title); > ticket = tiddler.getFieldString('ticket'); > } > if (!ticket) { return ''; } > > var url = 'https://mycompany.atlassian.net/browse/' + ticket; > > return '[[' + ticket + '|' + url + ']]'; > }; > > This is all well and good and I should have stopped there. But I had > noticed that in other examples there is a lot more *chaining* going on > then the example above (fetching values from different objects to be fed > into subsequent functions) and I couldn't help myself in thinking this was > a perfect case for a > Monad<http://tritarget.org/blog/2014/04/05/monads-by-mistake/>. > I took the time to experiment what that would be like and the result was > pretty impressive. Granted, it's a few lines longer in *this* example, > but I felt it was worth the effort especially if your *chaining* was more > complicated. Perhaps other plugin authors might appreciate the solution. > > First I create the > Monad<http://tritarget.org/blog/2014/04/05/monads-by-mistake/> > object: > > function Monad(data) { > this.data = data; > } > Monad.prototype.bind = function(context, functionName) { > return new Monad(context[functionName](this.data)); > }; > > Note that this does *not* support all the rules of a > Monad<http://tritarget.org/blog/2014/04/05/monads-by-mistake/> simply > because the use case is so tightly scoped. However, it is easy to add them > with two lines to the constructor: > > function Monad(data) { > if (!this instanceof Monad) { return new Monad(data); } > if (data instanceof Monad) { return data; } > this.data = data; > } > > Anyway, this now lets you chain functions on the data one after another > and each iteration of the chain will have the value of the previous > function. We can now compose functions: > > exports.run = function(ticket) { > if (!ticket) { > ticket = new Monad('currentTiddler') > .bind(this, 'getVariable') > .bind(this.wiki, 'getTiddler') > .data.getFieldString('ticket'); > } > if (!ticket) { return ''; } > > var url = 'https://mycompany.atlassian.net/browse/' + ticket; > > return '[[' + ticket + '|' + url + ']]'; > }; > > I had to split the context and function name to keep the correct context > when making the function call (JavaScript-ism). > > The full source of the plugin is at https://gist.github.com/11113680 > > I hope this pattern is helpful to other developers. Also it might be worth > while to offer a more permissive API in the > TiddlyWiki<http://localhost:8080/#TiddlyWiki> core > to allow plugins more access to needed functions. Perhaps adding a > getCurrentTiddler helper function or implement some kind of jQuery like > chaining API. Food for thought. > > Cheers, @Sukima > > -- > You received this message because you are subscribed to the Google Groups > "TiddlyWikiDev" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/tiddlywikidev. > For more options, visit https://groups.google.com/d/optout. > -- Jeremy Ruston mailto:[email protected] -- You received this message because you are subscribed to the Google Groups "TiddlyWikiDev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/tiddlywikidev. For more options, visit https://groups.google.com/d/optout.
