*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.

Attachment: A little monad in your plugin.tid
Description: Binary data

Reply via email to