Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Jamaica's opposition Labour Party wins power, first results show, but the governing party is not conceding.</html>
|''Type:''|file|
|''URL:''|http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml|
|''Workspace:''|(default)|
This tiddler was automatically created to record the details of this server
<html>The DR Congo army uses a helicopter gunship for the first time - saying it has killed 50 rebel fighters.</html>
<html>Patients still regularly wait in ambulances at casualty units in south east Wales, despite work to tackle the problem.</html>
<html>Patients still regularly wait in ambulances at casualty units in south east Wales, despite work to tackle the problem.</html>
<html>Michael Ancram's criticism of David Cameron's attempts to change the Tories is called "bizarre" by Stephen Dorrell.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Did you witness a news event? Got a good story idea?</html>
<html>At least 24 people are killed in two bomb blasts near the Pakistani army's base in the city of Rawalpindi.</html>
<html>Gordon Brown refuses to rule out a snap election in October, but says he is "getting on with the job".</html>
<html>Did you witness a news event? Got a good story idea?</html>
<html>US President George W Bush is due in Sydney for Apec, amid the tightest security Australia has ever seen.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>The Chinese government dismisses reports that its military hacked into the Pentagon's computer network.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Rebels in the DR Congo take control of large parts of Virunga National Park, home to rare mountain gorillas.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Ravi Bopara will miss the final two matches of the one-day series against India and the World Twenty20.</html>
<html>Cyber criminals are cashing in on their expertise by offering tool kits that let anyone craft attacks.</html>
<html>Danish police arrest eight people with alleged links to al-Qaeda on suspicion of planning a bomb attack.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>European Union plans to reduce the climate impact of aviation will not work, UK researchers conclude.</html>
<html>Eurostar arrives in London from Paris in a record time of just over two hours, via a new 186mph line.</html>
<html>Eurostar arrives in London from Paris in a record time of just over two hours, via a new 186mph line.</html>
<html>A former professional goalkeeper who seriously injured a builder is jailed for seven-and-a-half years.</html>
<html>Hurricane Felix weakens after making landfall in Nicaragua, but still has the potential to wreak havoc.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Many children with asthma in the UK are receiving inappropriate treatment, research suggests.</html>
<html>Many children with asthma in the UK are receiving inappropriate treatment, research suggests.</html>
<html>A 14-year-old girl pleads guilty to the manslaughter of her 16-year-old sister at their home in West Yorkshire.</html>
<html>The schools secretary writes to head teachers telling them to improve literacy, maths and classroom discipline.</html>
This [[TiddlyWiki|http://www.tiddlywiki.com]] is designed to showcase four things:
* A [[RSS server adaptor]], for pulling RSS content into ~TiddlyWiki via ImportTiddlers
* A [[regex development tool|regexTest intro]] for trying out regex
* A [[XMLHttp development tool|XMLHttpTest intro]] for trying out XMLHttpRequests
* A [[simple UI library|basicUI intro]] for putting together development tools
These are all written as plugins that extend the functionality of ~TiddlyWiki.
<html>Jane Tomlinson - the terminal cancer sufferer who raised £1.75m through gruelling challenges - dies aged 43.</html>
<html>The mother of a girl mauled to death by a pit bull terrier tells a court the dog was "jealous" of her daughter.</html>
<html> <p><a href="http://www.nbc.com/Law_&_Order/index.html"><img src="http://radio.weblogs.com/0001015/images/2002/09/29/lenny.gif" width="45" height="53" border="0" align="right" hspace="15" vspace="5" alt="A picture named lenny.gif"></a>A great line in a recent Law and Order. Lenny Briscoe, played by Jerry Orbach, is interrogating a suspect. The suspect tells a story and reaches a point where no one believes him, not even the suspect himself. Lenny says: "Now there's five minutes of my life that's lost forever." </p> </html>
<html>An MEP for South East England convicted of 21 charges of benefit fraud is imprisoned for nine months.</html>
[[Introduction]]
[[me]]
[[What's this about?]]
[[regexTest application]]
[[XMLHttpTest application]]
[[RSS adaptor code]]
[[regexTest code]]
[[basicUI code]]
<html>Packs of Maltesers and Revels are recalled after customers find small pieces of rubber in the sweets.</html>
<html>Three people are treated in hospital after two cars are involved in a collision with an escaped water buffalo.</html>
<html>Hopefuls including Amy Winehouse are set to find out the winner of the Mercury Prize in London.</html>
<html>France's first lady hits back at criticism of her role in securing the release of medical workers in Libya.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Did you witness a news event? Got a good story idea?</html>
<html>One person has died following a collision between two cars near the border in County Donegal.</html>
<html>The RMT union says it will hold talks with Tube officials aimed at ending the strike which has crippled the London Underground.</html>
/***
Server adaptor for talking to RSS 2.0 files
based on FileAdaptor
***/
//{{{
function RSSAdaptor()
{
this.host = null;
this.store = null;
this.context = null;
return this;
}
RSSAdaptor.NotLoadedError = "RSS file has not been loaded";
RSSAdaptor.serverType = 'RSS';
// Use the line below instead of the line above if you want to override the local file adaptor
// RSSAdaptor.serverType = 'file';
// Open the specified host/server
// Return true if successful, error string if not
RSSAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
this.host = host;
if(!context)
context = {};
context.adaptor = this;
context.callback = callback;
context.userParams = userParams;
var ret = loadRemoteFile(host,RSSAdaptor.openHostCallback,context);
return typeof(ret) == "string" ? ret : true;
};
RSSAdaptor.openHostCallback = function(status,context,responseText,url,xhr)
{
var adaptor = context.adaptor;
context.status = status;
if(!status) {
context.statusText = "Error reading file: " + xhr.statusText;
} else {
// CHANGE this bit to store RSS file appropriately (as part of the adaptor?) - DONE
// We're just storing the plain text rather than bring XML into it
adaptor.store = responseText;
// OLD CODE
// Load the content into a TiddlyWiki() object
// adaptor.store = new TiddlyWiki();
// if(!adaptor.store.importTiddlyWiki(responseText))
// context.statusText = config.messages.invalidFileError.format([url]);
}
context.callback(context,context.userParams);
};
// Gets the list of workspaces on a given server
// Sets context.workspaces, which is a list of workspaces
// Returns true if successful, error string if not (or it should)
// Default for RSS file as we don't have a workspace
RSSAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
if(!context)
context = {};
context.workspaces = [{title:"(default)"}];
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
// Open the specified workspace
// Returns true if successful, error string if not (or it should)
// Trivial in the case of RSS file where we don't have a workspace
RSSAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
if(!context)
context = {};
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
// Gets the list of tiddlers within a given workspace
// Returns true if successful, error string if not (or it should)
// Sets context.tiddlers, which is an array of tiddlers
// Set these variables if possible:
// title: tiddler.title, modified: tiddler.modified, modifier: tiddler.modifier, text: tiddler.text, tags: tiddler.tags, size: tiddler.text
// For RSS each item is a tiddler
RSSAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
if(!this.store)
return RSSAdaptor.NotLoadedError;
if(!context)
context = {};
context.tiddlers = [];
// First thing to do is strip out any \r characters in the file, as TiddlyWiki doesn't deal with them
this.store = this.store.replace(/\r+/mg,"");
// regex_item matches on the items
var regex_item = /<item>(.|\n)*?<\/item>/mg;
// regex_title matches for the titles
var regex_title = /<title>(.|\n)*?<\/title>/mg;
var regex_guid = /<guid>(.|\n)*?<\/guid>/mg;
var regex_desc = /<description>(.|\n)*?<\/description>/mg;
var item_match = this.store.match(regex_item);
for (var i=0;i<item_match.length;i++) {
// create a new Tiddler in context.tiddlers with the finished item object
// grab a title
item = {};
var title = item_match[i].match(regex_title);
if (title)
item.title = title[0].replace(/^<title>|<\/title>$/mg,"");
else {
// something went wrong grabbing the title, grab the guid instead
title = item_match[i].match(regex_guid);
displayMessage("problem with getting title: " + item_match[i])
if (title)
item.title = title[0].replace(/^<guid>|<\/guid>$/mg,"");
else {
item.title = new Date();
displayMessage("problem with getting title AND guid: " + item_match[i]);
}
}
// This line makes sure any html-encoding in the title is reversed
item.title = item.title.htmlDecode();
// There is a problem with the title, which is that it is not formatted, so characters like ' are not converted at render time
// renderHtmlText() extends String and sorts out the problem
item.title = item.title.renderHtmlText();
// grab a description
desc = item_match[i].match(regex_desc);
if (desc) item.text = desc[0].replace(/^<description>|<\/description>$/mg,"");
else {
item.text = "empty, something seriously wrong with this item";
displayMessage("description empty for item: " + item_match[i]);
}
var t = new Tiddler(item.title);
t.text = "<html>" + item.text.htmlDecode() + "</html>";
context.tiddlers.push(t);
}
// OLD CODE
// this.store.forEachTiddler(function(title,tiddler)
// {
// var t = new Tiddler(title);
// t.text = tiddler.text;
// t.modified = tiddler.modified;
// t.modifier = tiddler.modifier;
// t.fields['server.page.revision'] = tiddler.modified.convertToYYYYMMDDHHMM();
// t.tags = tiddler.tags;
// context.tiddlers.push(t);
// });
context.status = true;
// Set this.context so that we can refer to the tiddler list even if it is not passed on to us
this.context = context;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
// QUERY: what actually calls this and does it always pass in a real tiddler?
RSSAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
info.uri = tiddler.fields['server.host'] + "#" + tiddler.title;
return info;
};
// Retrieves a tiddler from a given workspace on a given server
// Sets context.tiddler to the requested tiddler
// Context object passed in from importTiddlers is empty so we use this.context
// Returns true if successful, error string if not (or it should)
RSSAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
if(!this.store)
return RSSAdaptor.NotLoadedError;
if(!context)
context = {};
// Retrieve the tiddler from the this.context.tiddlers array
for (var i=0; i<this.context.tiddlers.length; i++) {
if (this.context.tiddlers[i].title == title) {
context.tiddler = this.context.tiddlers[i];
}
}
if(context.tiddler) {
context.tiddler.fields['server.type'] = RSSAdaptor.serverType;
context.tiddler.fields['server.host'] = this.host;
context.tiddler.fields['server.page.revision'] = context.tiddler.modified.convertToYYYYMMDDHHMM();
context.status = true;
} else {
context.status = false;
context.statusText = "error retrieving tiddler: " + title;
return context.statusText;
}
if(context.allowSynchronous) {
context.isSynchronous = true;
callback(context,userParams);
} else {
window.setTimeout(function() {callback(context,userParams);},10);
}
return true;
};
RSSAdaptor.prototype.close = function()
{
delete this.store;
this.store = null;
};
config.adaptors[RSSAdaptor.serverType] = RSSAdaptor;
// Hack to override the ImportTiddlers local file behaviour
config.macros.importTiddlers.onBrowseChange = function(e)
{
var wizard = new Wizard(this);
var fileInput = wizard.getElement("txtPath");
fileInput.value = "file://" + this.value;
var serverType = wizard.getElement("selTypes");
if(serverType.value != "RSS") {
serverType.value = "file";
}
return false;
};
// renderHtmlText puts a string through the browser render process and then extracts the text - useful to turn HTML entities into literals
String.prototype.renderHtmlText = function() {
var e = createTiddlyElement(document.body,"div");
e.innerHTML = this;
var text = getPlainText(e);
removeNode(e);
return text;
};
//}}}
The RSS server adaptor is built to the [[server adaptor interface|http://tiddlywiki.com/#ServerAdaptorMechanism]] specified as part of ~TiddlyWiki.
Lots of detail is provided at the link above, but the basic concept behind server adaptors is to provide a standard mechanism for bringing content into a TiddlyWiki. This adaptor can pull content in from any RSS feed (currently only RSS 2.0 is supported).
An example use of this adaptor is in the ImportTiddlers tiddler: the RSS content is downloaded and placed into [[tiddlers|http://tiddlywiki.com/#MicroContent]] using the ImportTiddlers macro, which uses the RSS adaptor to interact with the RSS feed. You can import from the [[backstage|http://tiddlywiki.com/#BackstageArea]] area (this is only visible is you are accessing this page offline and is a black strip at the top of the page). Repeated imports allow you to stay up-to-date with the RSS feed.
The [[BBC feed|(default) on http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml]] tiddler contains information to use as an example feed during the ImportTiddlers process. You can select it from the drop-down that appears during the first step.
The code for this plugin is in the [[RSS adaptor code]] tiddler. It contains a small [[hack]] to override the ImportTiddlers local file behaviour.
<html> <p>One of the lessons I've learned in 47.4 years: When someone accuses you of a <a href="http://www.dictionary.com/search?q=deceit">deceit</a>, there's a very good chance the accuser practices that form of deceit, and a reasonable chance that he or she is doing it as they point the finger. </p> <p><a href="http://www.docuverse.com/blog/donpark/2002/09/28.html#a66">Don Park</a>: "He poured a barrel full of pig urine all over the Korean Congress because he was pissed off about all the dirty politics going on."</p> <p><a href="http://davenet.userland.com/1995/01/04/demoingsoftwareforfunprofi">1/4/95</a>: "By the way, the person with the big problem is probably a competitor."</p> <p>I've had a fair amount of experience in the last few years with what you might call standards work. XML-RPC, SOAP, RSS, OPML. Each has been different from the others. In all this work, the most positive experience was XML-RPC, and not just because of the technical excellence of the people involved. In the end, what matters more to me is <a href="http://www.dictionary.com/search?q=collegiality">collegiality</a>. Working together, person to person, for the sheer pleasure of it, is even more satisfying than a good technical result. Now, getting both is the best, and while XML-RPC is not perfect, it's pretty good. I also believe that if you have collegiality, technical excellence follows as a natural outcome.</p> <p>One more bit of philosophy. At my checkup earlier this week, one of the things my cardiologist asked was if I was experiencing any kind of intellectual dysfunction. In other words, did I lose any of my sharpness as a result of the surgery in June. I told him yes I had and thanked him for asking. In an amazing bit of synchronicity, the next day John Robb <a href="http://jrobb.userland.com/2002/09/25.html#a2598">located</a> an article in New Scientist that said that scientists had found a way to prevent this from happening. I hadn't talked with John about my experience or the question the doctor asked. Yesterday I was telling the story to my friend Dave Jacobs. He said it's not a problem because I always had excess capacity in that area. Exactly right Big Dave and thanks for the vote of confidence.</p> </html>
<html>Did you witness a news event? Got a good story idea?</html>
<html>England fly-half Jonny Wilkinson is ruled out of the defending champions' first World Cup match after twisting his ankle in training.</html>
<html> <p>In the discussions over namespaces in RSS 2.0, one thing I hear a lot of, that is just plain wrong, is that when you move up by a major version number, breakage is expected and is okay. In the world I come from it is, emphatically, <i>not okay.</i> We spend huge resources to make sure that files, scripts and apps built in version N work in version N+1 without modification. Even the smallest change in the core engine can break apps. It's just not acceptable. When we make changes we have to be sure there's no breakage. I don't know where these other people come from, or if they make software that anyone uses, but the users I know don't stand for that. As we expose the tradeoffs it becomes clear that <i>that's the issue here.</i> We are not in Year Zero. There are users. Breaking them is not an option. A conclusion to lift the confusion: Version 0.91 and 0.92 files are valid 2.0 files. This is where we started, what seems like years ago.</p> <p>BTW, you can ask anyone who's worked for me in a technical job to explain rules 1 and 1b. (I'll clue you in. Rule 1 is "No Breakage" and Rule 1b is "Don't Break Dave.")</p> </html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
mashups & javascript development in TiddlyWiki
<html>A stalker is banned from being alone with any woman without permission for five years, BBC Scotland learns.</html>
<html>New owners and a TV deal help English football clubs spend more than £530m on players, a survey says.</html>
<html>New owners and a TV deal help English football clubs spend more than £530m on players, a survey says.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Up to 42,000 NI motorists may have escaped speeding fines, due to an inability to process cases.</html>
Developing Javascript can often be a bit of a pain in the arse...
* Not-strongly typed so IDE's don't help out too much
* Hard to debug
* Cross-browser compatibility is a great big time-wasting black hole
[[Firebug|http://www.getfirebug.com]] is a ''really'' big help. But, we can go further...
TiddlyWiki is an application written entirely in javascript, html and css. It looks superficially like a wiki, but is really an environment for engineering client-side web applications.
TiddlyWiki has the quality that when you are accessing it from your local hard-drive, you are not subject to Javascript's [[same-origin policy|http://en.wikipedia.org/wiki/Same_origin_policy]]. This has a couple of useful consequences:
* you can make as many calls to remote API's and data sources as you like, without having to worry about proxying the request through a server-side script
* you can develop offline with local files, safe in the knowledge that when you swap to calling remote files you don't have to change your code
Because TiddlyWiki provides you with a lot of useful libraries for retrieving and presenting data, it is easy to create little helper applications to assist with development. The [[regexTest intro]] is an example.
Finally, because TiddlyWiki is a single html file, it is really easy to share what you've done with other people - you just attach the whole TiddlyWiki to an email, put it on the web or a USB stick... and the ability to read and extract information from other TiddlyWikis makes it really simple to pull the specific tiddlers out that you want.
TiddlyWiki is a single html file that you usually interact with locally. This lends itself to an approach to mashups where you pull content in from remote sources and store it in tiddlers, creating a big pool of data that you deal with later. An advantage to this approach is that you automatically get an offline version of your mashup.
TiddlyWiki defines an abstraction between the standard format of tiddlers and the data formats you get in the wild. You build adaptors to chop up the data you want into the tiddler format. The [[RSS server adaptor]] is an example of one of these, which allows interaction with RSS feeds. It's in the good company of adaptors for other TiddlyWikis, MediaWiki, TWiki and several more.
<html>Council tenants should receive state aid to help them buy a home and break up "ghettos", a Tory group says.</html>
<html>The Tories should restore the party's "soul" and not make "vacuous" reforms, a former deputy party leader warns.</html>
<html>Pupils who have been excluded from school in England will no longer be able to hang around the streets.</html>
<html>A routine check on the faulty points which led to a fatal rail crash failed to take place, a report reveals.</html>
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
<html>Gordon Brown rejects claims of any split between UK and US policy on Iraq, saying both are on the "same path".</html>
<html>The RMT union meets Tube officials in a bid to end a strike which has shut most of the London Underground.</html>
<html>Israel's supreme court orders the government to re-route the West Bank barrier near the village of Bilin.</html>
...two things, and they're kind of seperate...
* [[TiddlyWiki & Mashups]]
* [[TiddlyWiki & Javascript development]]
<html>Excluded pupils will no longer be able to roam the streets. Parents will have to keep pupils under supervision for the first five days of an exclusion. Is this a good idea?</html>
/***
XMLHttpTester
This is an example use of the using basicUI library and RSSAdaptor
***/
//{{{
config.macros.XMLHttpTest = {};
config.macros.XMLHttpTest.handler = function(place,macroName,params) {
// defaults is a named array with input defaults
// labels is a named array with input labels
// callback is the function to call on button press
var ui = new config.macros.basicUI();
var labels = {
"input_url" : "The envelope",
"input_control" : "The pen",
"ui_go_button" : "Go!",
"input_box" : "The paper",
"output_box" : "The results"
};
var defaults = {
"input_url" : "http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml",
"input_control" : "<item>"
};
var callback = config.macros.XMLHttpTest.go;
// Let's get going
ui.buildUI(place,labels,defaults,callback);
};
config.macros.XMLHttpTest.go = function(boxes,userParams) {
var adaptor = new RSSAdaptor();
// As we're communicating between a UI and this macro
// use the context object to store macro variables
var context = {};
context.adaptor = adaptor;
context.boxes = boxes;
context.host = userParams.input_url;
var ret = adaptor.openHost(context.host,context,userParams,config.macros.XMLHttpTest.onOpenHost);
if (!ret) {
displayMessage("problem opening host: " + ret);
return false;
}
return typeof(ret) == "string" ? ret : true;
};
// Display the input text and proceed
config.macros.XMLHttpTest.onOpenHost = function(context,userParams) {
context.boxes.input_box.value = context.adaptor.store;
// Next line calls custom version of the adaptor's getTiddlerList to allow for user-defined regex
var ret = config.macros.XMLHttpTest.getTiddlerList(context,userParams);
if (typeof(ret) == "string") {
displayMessage("problem opening tiddler list: " + ret);
}
};
// This is a customised version of the getTiddlerList RSSAdaptor function
// We just print the responseText
config.macros.XMLHttpTest.getTiddlerList = function(context,userParams) {
if(!context.adaptor.store) {
return RSSAdaptor.NotLoadedError;
}
var place = context.boxes.output_box;
context.boxes.output_box.value = context.adaptor.store;
return true;
};
//}}}
<html>Did you witness a news event? Got a good story idea?</html>
/***
basicUI class - create a simple, configurable UI for processing
data through an aribitrary control function and seeing the results
First use-case that this supports is where we have an input box,
an output box and a go button, which calls a function
The box labels and default values are optional parameters
defaults is a named array with input defaults
labels is a named array with input labels
callback is the function to call on button press
this.boxes contains references to all the UI elements
***/
//{{{
config.macros.basicUI = function() {
this.labels = {
"input_url" : "Please input a url to get some information from",
"input_control" : "Please input a control string",
"input_box" : "Input text",
"ui_go_button" : "go!",
"output_box" : "The results"
};
this.defaults = {
"input_url" : "http://",
"input_control" : "e.g. for a regex: / .. /mg"
};
this.callback = function() { alert("no behaviour defined for ui go button!") };
};
config.macros.basicUI.prototype.buildUI = function(place,labels,defaults,callback) {
if(labels) { this.labels = labels; }
if(defaults) { this.defaults = defaults; }
if(callback) { this.callback = callback; }
var ui_wrapper = createTiddlyElement(place,"div","ui_wrapper");
var input_url_label = createTiddlyElement(ui_wrapper,"span",null,null,this.labels["input_url"]);
createTiddlyElement(ui_wrapper,"br");
var input_url = createTiddlyElement(ui_wrapper,"input","input_url");
input_url.setAttribute("size","50");
input_url.setAttribute("value",this.defaults["input_url"]);
createTiddlyElement(ui_wrapper,"br");
var input_control_label = createTiddlyElement(ui_wrapper,"span",null,null,this.labels["input_control"]);
createTiddlyElement(ui_wrapper,"br");
var input_control = createTiddlyElement(ui_wrapper,"input","input_control");
input_control.setAttribute("size","50");
input_control.setAttribute("value",this.defaults["input_control"]);
createTiddlyElement(ui_wrapper,"br");
var ui_go_button = createTiddlyElement(ui_wrapper,"input","ui_go_button");
ui_go_button.setAttribute("type","button");
ui_go_button.setAttribute("value",labels["ui_go_button"]);
ui_go_button.onclick = this.editorOnClick;
ui_go_button.callback = callback;
createTiddlyElement(ui_wrapper,"br");
var input_box_label = createTiddlyElement(ui_wrapper,"span",null,null,this.labels["input_box"]);
createTiddlyElement(ui_wrapper,"br");
var input_box = createTiddlyElement(ui_wrapper,"textarea","input_box");
input_box.setAttribute("cols","50");
input_box.setAttribute("rows","30");
createTiddlyElement(ui_wrapper,"br");
var output_box_label = createTiddlyElement(ui_wrapper,"span",null,null,this.labels["output_box"]);
createTiddlyElement(ui_wrapper,"br");
var output_box = createTiddlyElement(ui_wrapper,"textarea","output_box");
output_box.setAttribute("cols","50");
output_box.setAttribute("rows","30");
};
// The onclick function for the UI go button
config.macros.basicUI.prototype.editorOnClick = function() {
// that points at the button clicked
var that = this;
return (function() {
// ui_wrapper refers to the containing div
var ui_wrapper = that.parentNode;
var boxes = {};
boxes.input_url = ui_wrapper.childNodes[2];
boxes.input_control = ui_wrapper.childNodes[6];
boxes.input_go_button = ui_wrapper.childNodes[8];
boxes.input_box = ui_wrapper.childNodes[12];
boxes.output_box = ui_wrapper.childNodes[16];
var userParams = {};
userParams.input_url = ui_wrapper.childNodes[2].value;
userParams.input_control = ui_wrapper.childNodes[6].value;
if(!userParams.input_url) {
displayMessage("error: check input url!");
} else if(!userParams.input_control) {
displayMessage("error: check input control!");
} else {
boxes.input_go_button.callback(boxes,userParams);
}
})();
};
// Utility function to clear a box
// box_id is the id of a box in this.boxes
config.macros.basicUI.clearBox = function(boxes,box_id) {
var box = boxes[box_id];
if (box && box.hasChildNodes()) {
var count=box.childNodes.length;
for (var i=0;i<count;i++) {
removeNode(box.childNodes[0]);
}
}
};
//}}}
The basicUI library provides a simple way to create a generic user interface for pulling in data, processing it and displaying the result.
This is used in the [[regexTest application]] to build the UI and attach the regex processing function to the button you press.
The code is [[here|basicUI code]].
|name:|"XMLHttpRequest"|
|function:|function f(params) { return params; };|
|''Type:''|file|
|''URL:''|file:///Users/jonathanlister/Documents/osmosoft/tiddlywikis/rssadaptor/rsstest.xml|
|''Workspace:''||
This tiddler was automatically created to record the details of this server
The standard ImportTiddlers macro deals with local files using the [[FileAdaptor|http://tiddlywiki.com/#MicroContent]] macro. This assumes the target file is a ~TiddlyWiki. Because it is valid to want to import local RSS files, we need to override this behaviour.
The offending function is ~onBrowseChange, so we change it from this:
{{{
config.macros.importTiddlers.onBrowseChange = function(e)
{
var wizard = new Wizard(this);
var fileInput = wizard.getElement("txtPath");
fileInput.value = "file://" + this.value;
var serverType = wizard.getElement("selTypes");
serverType.value = "file";
return false;
};
}}}
...to this:
{{{
config.macros.importTiddlers.onBrowseChange = function(e)
{
var wizard = new Wizard(this);
var fileInput = wizard.getElement("txtPath");
fileInput.value = "file://" + this.value;
var serverType = wizard.getElement("selTypes");
if(serverType.value != "RSS") {
serverType.value = "file";
}
return false;
};
}}}
<html><a href="http://scriptingnews.userland.com/stories/storyReader$1768">Three Sunday Morning Options</a>. "I just got off the phone with Tim Bray, who graciously returned my call on a Sunday morning while he was making breakfast for his kids." We talked about three options for namespaces in RSS 2.0, and I think I now have the tradeoffs well outlined, and ready for other developers to review. If there is now a consensus, I think we can easily move forward. </html>
<html><a href="http://blog.mediacooperative.com/mt-comments.cgi?entry_id=1435">Mark Pilgrim</a> weighs in behind option 1 on a Ben Hammersley thread. On the RSS2-Support list, Phil Ringnalda lists a set of <a href="http://groups.yahoo.com/group/RSS2-Support/message/54">proposals</a>, the first is equivalent to option 1. </html>
<html>Joshua Allen: <a href="http://www.netcrucible.com/blog/2002/09/29.html#a243">Who loves namespaces?</a></html>
<html><a href="http://www.docuverse.com/blog/donpark/2002/09/29.html#a68">Don Park</a>: "It is too easy for engineer to anticipate too much and XML Namespace is a frequent host of over-anticipation."</html>
<html>"rssflowersalignright"With any luck we should have one or two more days of namespaces stuff here on Scripting News. It feels like it's winding down. Later in the week I'm going to a <a href="http://harvardbusinessonline.hbsp.harvard.edu/b02/en/conferences/conf_detail.jhtml?id=s775stg&pid=144XCF">conference</a> put on by the Harvard Business School. So that should change the topic a bit. The following week I'm off to Colorado for the <a href="http://www.digitalidworld.com/conference/2002/index.php">Digital ID World</a> conference. We had to go through namespaces, and it turns out that weblogs are a great way to work around mail lists that are clogged with <a href="http://www.userland.com/whatIsStopEnergy">stop energy</a>. I think we solved the problem, have reached a consensus, and will be ready to move forward shortly.</html>
<html><a href="http://effbot.org/zone/effnews-4.htm">Fredrik Lundh breaks</a> through, following Simon Fell's lead, now his Python aggregator works with Scripting News <a href="http://www.scripting.com/rss.xml">in</a> RSS 2.0. BTW, the spec is imperfect in regards to namespaces. We anticipated a 2.0.1 and 2.0.2 in the Roadmap for exactly this purpose. Thanks for your help, as usual, Fredrik. </html>
Jonathan Lister
Client-side web developer, [[Osmosoft|http://www.osmosoft.com]]
http://jayfresh.wordpress.com
Interests: mashups, making it easier for less-technical people to program
<<param_test "example func">>
config.macros.param_test = {};
config.macros.param_test.handler = function(place,macroName,params) {
// params[0] is the name of a tiddler with the function in it
if (store.tiddlerExists(params[0])) {
// get the slice named "function"
var s = store.getTiddlerSlice(params[0],"function");
console.log(s);
var func_string = "var func = " + s;
console.log(func_string);
eval(func_string);
console.log(func);
return func;
} else {
displayMessage("error opening tiddler: " + params[0]);
}
};
/***
Visual regex query builder to debug any regex problems
This is an example use of the using basicUI library and RSSAdaptor
***/
//{{{
config.macros.regexTest = {};
config.macros.regexTest.handler = function(place,macroName,params) {
// defaults is a named array with input defaults
// labels is a named array with input labels
// callback is the function to call on button press
var ui = new config.macros.basicUI();
var labels = {
"input_url" : "The envelope",
"input_control" : "The pen",
"ui_go_button" : "Go!",
"input_box" : "The paper",
"output_box" : "The results"
};
var defaults = {
"input_url" : "http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml",
"input_control" : "<item>"
};
var callback = config.macros.regexTest.go;
// Let's get going
ui.buildUI(place,labels,defaults,callback);
};
config.macros.regexTest.go = function(boxes,userParams) {
var adaptor = new RSSAdaptor();
// As we're communicating between a UI and this macro
// use the context object to store macro variables
var context = {};
context.adaptor = adaptor;
context.boxes = boxes;
context.host = userParams.input_url;
var ret = adaptor.openHost(context.host,context,userParams,config.macros.regexTest.onOpenHost);
if (!ret) {
displayMessage("problem opening host: " + ret);
return false;
}
return typeof(ret) == "string" ? ret : true;
};
// Display the input text and proceed
config.macros.regexTest.onOpenHost = function(context,userParams) {
context.boxes.input_box.value = context.adaptor.store;
// Next line calls custom version of the adaptor's getTiddlerList to allow for user-defined regex
var ret = config.macros.regexTest.getTiddlerList(context,userParams);
if (typeof(ret) == "string") {
displayMessage("problem opening tiddler list: " + ret);
}
};
// This is a customised version of the getTiddlerList RSSAdaptor function
// We just apply the regex and print out to the output box
config.macros.regexTest.getTiddlerList = function(context,userParams) {
if(!context.adaptor.store) {
return RSSAdaptor.NotLoadedError;
}
var place = context.boxes.output_box;
var regex_item = new RegExp(userParams.input_control,"mg");
var item_match = context.adaptor.store.match(regex_item);
// item_match will be an array
if (item_match) {
var result_string = "";
for (var i=0; i<item_match.length; i++) {
// Print out results to the output box
result_string += item_match[i];
result_string += "\n\n";
}
context.boxes.output_box.value = result_string;
} else {
displayMessage("error: check your regex");
}
return true;
};
//}}}
This plugin demonstrates an example of how ~TiddlyWiki can be used as an interactive development environment for writing web applications in ~JavaScript.
The [[regexTest application]] allows you test out arbitrary [[regex|http://en.wikipedia.org/wiki/Regex]] on any remote or local file.
The regex tool makes use of parts of the [[RSS server adaptor]] to get hold of the file and the [[basicUI library|basicUI intro]] to lay out the user interface.
The code is [[here|regexTest code]].