If you'd like to donate some money to the ~TiddlySpot developers you can do so by /%%/visiting the new donate page at http://tiddlyspot.com/?page=donate
A small number of sites have been affected by a problem which caused "save to web" to fail with an error message. The bug was introduced late yesterday and has now been fixed. Apologies for any inconvenience this may have caused.
!Welcome to your ''tiddlyspot.com'' ~TiddlyWiki!\n''[[tiddlyspot.com|http://tiddlyspot.com]]'' gives you an instant [[TiddlyWiki|http://tiddlywiki.com]] hosted on our ''tiddlyspot.com'' servers.\n\nWant to work online? No problem, you can go to your ''tiddlyspot.com'' URL (which is http://tiddlyspot.com/announce/index.html ) and start editing. Click "save to web" and your changes are saved directly to your ''tiddlyspot.com'' home -- no messing about with local files or ftp.\n\nWant to work offline? No problem, your ''tiddlyspot.com'' ~TiddlyWiki is a real, fully functioning ~TiddlyWiki that you can save onto your hard drive or USB stick. Use the link below to save to your local computer. As you make changes, use the "save to disk" button to save to your local file. Whenever you're ready to sync up again, just click "save to web".\n\n!To save online\nEnter the upload password provided when you created your ~TiddlyWiki. Then click the "save to web" button below (or in the right side column) to save your ~TiddlyWiki.\nUpload Password: <<option pasUploadPassword>>\n<<upload http://tiddlyspot.com/announce/store.php index.html . . announce>>\n\n!To save offline\nTo take this ~TiddlyWiki offline, right click on this link: http://tiddlyspot.com/announce/index.html and choose "save as.."\n\n!Learn more about ~TiddlyWiki\nFind out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki.\n\nThe [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]] is an excellent place to ask questions and get help.\n\n!Enjoy!\nWe hope you like using your ''tiddlyspot.com'' ~TiddlyWiki. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments.\n\n----
This is the official announcements page for ''[[tiddlyspot.com|http://tiddlyspot.com/]]''.\n{{blog{\n<<forEachTiddler\n where\n 'tiddler.tags.contains("Announcements")'\n sortBy\n 'tiddler.created'\n descending\n write\n 'index<6?"\sn!![["+tiddler.title+"]]@@color:#999;font-size:70%;" +\n tiddler.created.formatString(" - DD/MM/YY")+" - posted by "+tiddler.modifier+"@@\sn" +\n "{{excerpt{\sn" + \n (tiddler.text.match("/%%/") ?\n tiddler.text.substr(0,tiddler.text.indexOf("/%%/")) : \n tiddler.text.substr(0,100)) + \n " ...\sn[[read more...|"+tiddler.title+"]]\sn}}}":"";'\n>>\n}}}\n[[Older Announcements]]\n\n
/% see ViewTemplate %/\n~~[[back to index...|Announcements]]~~
The subject says it all. [[String#dump|http://www.ruby-doc.org/core/classes/String.html#M000597]] is our new best friend. Thanks to Mark J. for reporting this bug./%%/
/***\nJust some bits and pieces\n***/\n//{{{\nconfig.messages.messageClose.text = "X"; // default is "close"\nconfig.views.wikified.defaultText = ""; // default is "The tiddler '%0' doesn't yet exist. Double-click to create it"\nconfig.options.chkHttpReadOnly = false; // Enable editing so that visitors can experiment with it\n//}}}
Firstly we had a problem where the signup page would appear to let you create a site that already existed instead of telling you that the site id was unavailable. This would have caused a lot of confusion because when you went to look at your "new" site you would see the existing site. This had actually been happening for quite a while without us knowing about it. It has been fixed now. \n\nSecondly there was a problem with proxy configuration file containing the list of allowed sites. Somehow it got corrupted which would have caused the proxy service to fail. This is also fixed now so try again if you were doing some proxy fetches and you were having problems.\n\nPlease accept our apologies if either of these problems affected you.
See [[Tiddlyspot FAQ|http://tiddlyspot.com/faq/]]. Thanks to Yann for his suggestions.
And added a few announcements. Tweaked the colours and layout a little.
For details see the blog post at /%%/[[this url|http://tiddlyspot.com/blog/archives/general/default-value-of-public-listing-okay-is-now-true/]].
<!---\n| Name:|~TagglyTaggingEditTemplate |\n| Version:|1.1 (12-Jan-2006)|\n| Source:|http://simonbaird.com/mptw/#TagglyTaggingEditTemplate|\n| Purpose:|See TagglyTagging for more info|\n| Requires:|You need the CSS in TagglyTaggingStyles to make it look right|\n--->\n<!--{{{-->\n<div class="toolbar" macro="toolbar +saveTiddler closeOthers cancelTiddler deleteTiddler"></div>\n<div class="title" macro="view title"></div>\n<div class="editLabel">Title</div><div class="editor" macro="edit title"></div>\n<div class="editLabel">Tags</div><div class="editor" macro="edit tags"></div>\n<div class="editorFooter"><span macro="message views.editor.tagPrompt"></span><span macro="tagChooser"></span></div>\n<div class="editor" macro="edit text"></div>\n<br/>\n<!--}}}-->
/***\n|''Name:''|ForEachTiddlerPlugin|\n|''Version:''|1.0.5 (2006-02-05)|\n|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|\n|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|\n|''Licence:''|[[BSD open source license]]|\n|''Macros:''|[[ForEachTiddlerMacro]] v1.0.5|\n|''TiddlyWiki:''|1.2.38+, 2.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n!Description\n\nCreate customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.\n\n''Syntax:'' \n|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|\n|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|\n|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|\n|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|\n|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|\n|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|\n|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|\n|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|\n\nSee details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].\n\n!Revision history\n* v1.0.5\n** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.\n** Support Firefox\n** Internal\n*** Make "JSLint" conform\n*** "Only install once"\n* v1.0.4 (2006-01-06)\n** Support TiddlyWiki 2.0\n* v1.0.3 (2005-12-22)\n** Features: \n*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) \n*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)\n** Enhancements:\n*** Improved error messages on InternetExplorer.\n* v1.0.2 (2005-12-10)\n** Features: \n*** context object also holds reference to store (TiddlyWiki)\n** Fixed Bugs: \n*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)\n* v1.0.1 (2005-12-08)\n** Features: \n*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".\n*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.\n*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).\n*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .\n*** Improved script evaluation (for where/sort clause and write scripts).\n* v1.0.0 (2005-11-20)\n** initial version\n\n!Code\n***/\n//{{{\n\n \n//============================================================================\n//============================================================================\n// ForEachTiddlerPlugin\n//============================================================================\n//============================================================================\n\n// Only install once\nif (!version.extensions.ForEachTiddlerPlugin) {\n\nversion.extensions.ForEachTiddlerPlugin = {major: 1, minor: 0, revision: 5, date: new Date(2006,2,5), source: "http://tiddlywiki.abego-software.de/#ForEachTiddlergPlugin"};\n\n// For backward compatibility with TW 1.2.x\n//\nif (!TiddlyWiki.prototype.forEachTiddler) {\n TiddlyWiki.prototype.forEachTiddler = function(callback) {\n for(var t in this.tiddlers) {\n callback.call(this,t,this.tiddlers[t]);\n }\n };\n}\n\n//============================================================================\n// forEachTiddler Macro\n//============================================================================\n\nversion.extensions.forEachTiddler = {major: 1, minor: 0, revision: 5, date: new Date(2006,2,5), provider: "http://tiddlywiki.abego-software.de"};\n\n// ---------------------------------------------------------------------------\n// Configurations and constants \n// ---------------------------------------------------------------------------\n\nconfig.macros.forEachTiddler = {\n // Standard Properties\n label: "forEachTiddler",\n prompt: "Perform actions on a (sorted) selection of tiddlers",\n\n // actions\n actions: {\n addToList: {},\n write: {}\n }\n};\n\n// ---------------------------------------------------------------------------\n// The forEachTiddler Macro Handler \n// ---------------------------------------------------------------------------\n\nconfig.macros.forEachTiddler.getContainingTiddler = function(e) {\n while(e && !hasClass(e,"tiddler"))\n e = e.parentNode;\n var title = e ? e.getAttribute("tiddler") : null; \n return title ? store.getTiddler(title) : null;\n};\n\nconfig.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n // config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);\n\n if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);\n // --- Parsing ------------------------------------------\n\n var i = 0; // index running over the params\n // Parse the "in" clause\n var tiddlyWikiPath = undefined;\n if ((i < params.length) && params[i] == "in") {\n i++;\n if (i >= params.length) {\n this.handleError(place, "TiddlyWiki path expected behind 'in'.");\n return;\n }\n tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");\n i++;\n }\n\n // Parse the where clause\n var whereClause ="true";\n if ((i < params.length) && params[i] == "where") {\n i++;\n whereClause = this.paramEncode((i < params.length) ? params[i] : "");\n i++;\n }\n\n // Parse the sort stuff\n var sortClause = null;\n var sortAscending = true; \n if ((i < params.length) && params[i] == "sortBy") {\n i++;\n if (i >= params.length) {\n this.handleError(place, "sortClause missing behind 'sortBy'.");\n return;\n }\n sortClause = this.paramEncode(params[i]);\n i++;\n\n if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {\n sortAscending = params[i] == "ascending";\n i++;\n }\n }\n\n // Parse the script\n var scriptText = null;\n if ((i < params.length) && params[i] == "script") {\n i++;\n scriptText = this.paramEncode((i < params.length) ? params[i] : "");\n i++;\n }\n\n // Parse the action. \n // When we are already at the end use the default action\n var actionName = "addToList";\n if (i < params.length) {\n if (!config.macros.forEachTiddler.actions[params[i]]) {\n this.handleError(place, "Unknown action '"+params[i]+"'.");\n return;\n } else {\n actionName = params[i]; \n i++;\n }\n } \n \n // Get the action parameter\n // (the parsing is done inside the individual action implementation.)\n var actionParameter = params.slice(i);\n\n\n // --- Processing ------------------------------------------\n try {\n this.performMacro({\n place: place, \n inTiddler: tiddler,\n whereClause: whereClause, \n sortClause: sortClause, \n sortAscending: sortAscending, \n actionName: actionName, \n actionParameter: actionParameter, \n scriptText: scriptText, \n tiddlyWikiPath: tiddlyWikiPath});\n\n } catch (e) {\n this.handleError(place, e);\n }\n};\n\n// Returns an object with properties "tiddlers" and "context".\n// tiddlers holds the (sorted) tiddlers selected by the parameter,\n// context the context of the execution of the macro.\n//\n// The action is not yet performed.\n//\n// @parameter see performMacro\n//\nconfig.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {\n\n var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);\n\n var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;\n context["tiddlyWiki"] = tiddlyWiki;\n \n // Get the tiddlers, as defined by the whereClause\n var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);\n context["tiddlers"] = tiddlers;\n\n // Sort the tiddlers, when sorting is required.\n if (parameter.sortClause) {\n this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);\n }\n\n return {tiddlers: tiddlers, context: context};\n};\n\n// Returns the (sorted) tiddlers selected by the parameter.\n//\n// The action is not yet performed.\n//\n// @parameter see performMacro\n//\nconfig.macros.forEachTiddler.getTiddlers = function(parameter) {\n return this.getTiddlersAndContext(parameter).tiddlers;\n};\n\n// Performs the macros with the given parameter.\n//\n// @param parameter holds the parameter of the macro as separate properties.\n// The following properties are supported:\n//\n// place\n// whereClause\n// sortClause\n// sortAscending\n// actionName\n// actionParameter\n// scriptText\n// tiddlyWikiPath\n//\n// All properties are optional. \n// For most actions the place property must be defined.\n//\nconfig.macros.forEachTiddler.performMacro = function(parameter) {\n var tiddlersAndContext = this.getTiddlersAndContext(parameter);\n\n // Perform the action\n var actionName = parameter.actionName ? parameter.actionName : "addToList";\n var action = config.macros.forEachTiddler.actions[actionName];\n if (!action) {\n this.handleError(parameter.place, "Unknown action '"+actionName+"'.");\n return;\n }\n\n var actionHandler = action.handler;\n actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);\n};\n\n// ---------------------------------------------------------------------------\n// The actions \n// ---------------------------------------------------------------------------\n\n// Internal.\n//\n// --- The addToList Action -----------------------------------------------\n//\nconfig.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {\n // Parse the parameter\n var p = 0;\n\n // Check for extra parameters\n if (parameter.length > p) {\n config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);\n return;\n }\n\n // Perform the action.\n var list = document.createElement("ul");\n place.appendChild(list);\n for (var i = 0; i < tiddlers.length; i++) {\n var tiddler = tiddlers[i];\n var listItem = document.createElement("li");\n list.appendChild(listItem);\n createTiddlyLink(listItem, tiddler.title, true);\n }\n};\n\n// Internal.\n//\n// --- The write Action ---------------------------------------------------\n//\nconfig.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {\n // Parse the parameter\n var p = 0;\n if (p >= parameter.length) {\n this.handleError(place, "Missing expression behind 'write'.");\n return;\n }\n\n var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);\n p++;\n\n // Parse the "toFile" option\n var filename = null;\n var lineSeparator = undefined;\n if ((p < parameter.length) && parameter[p] == "toFile") {\n p++;\n if (p >= parameter.length) {\n this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");\n return;\n }\n \n filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));\n p++;\n if ((p < parameter.length) && parameter[p] == "withLineSeparator") {\n p++;\n if (p >= parameter.length) {\n this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");\n return;\n }\n lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);\n p++;\n }\n }\n \n // Check for extra parameters\n if (parameter.length > p) {\n config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);\n return;\n }\n\n // Perform the action.\n var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);\n var count = tiddlers.length;\n var text = "";\n for (var i = 0; i < count; i++) {\n var tiddler = tiddlers[i];\n text += func(tiddler, context, count, i);\n }\n \n if (filename) {\n if (lineSeparator !== undefined) {\n lineSeparator = lineSeparator.replace(/\s\sn/mg, "\sn").replace(/\s\sr/mg, "\sr");\n text = text.replace(/\sn/mg,lineSeparator);\n }\n saveFile(filename, convertUnicodeToUTF8(text));\n } else {\n var wrapper = createTiddlyElement(place, "span");\n wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);\n }\n};\n\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n// Internal.\n//\nconfig.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {\n return {\n place : placeParam, \n whereClause : whereClauseParam, \n sortClause : sortClauseParam, \n sortAscending : sortAscendingParam, \n script : scriptText,\n actionName : actionNameParam, \n actionParameter : actionParameterParam,\n tiddlyWikiPath : tiddlyWikiPathParam,\n inTiddler : inTiddlerParam\n };\n};\n\n// Internal.\n//\n// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of \n// the given path.\n//\nconfig.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {\n if (!idPrefix) {\n idPrefix = "store";\n }\n var lenPrefix = idPrefix.length;\n \n // Read the content of the given file\n var content = loadFile(this.getLocalPath(path));\n if(content === null) {\n throw "TiddlyWiki '"+path+"' not found.";\n }\n \n // Locate the storeArea div's\n var posOpeningDiv = content.indexOf(startSaveArea);\n var posClosingDiv = content.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1)) {\n throw "File '"+path+"' is not a TiddlyWiki.";\n }\n var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);\n \n // Create a "div" element that contains the storage text\n var myStorageDiv = document.createElement("div");\n myStorageDiv.innerHTML = storageText;\n myStorageDiv.normalize();\n \n // Create all tiddlers in a new TiddlyWiki\n // (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)\n var tiddlyWiki = new TiddlyWiki();\n var store = myStorageDiv.childNodes;\n for(var t = 0; t < store.length; t++) {\n var e = store[t];\n var title = null;\n if(e.getAttribute)\n title = e.getAttribute("tiddler");\n if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)\n title = e.id.substr(lenPrefix);\n if(title && title !== "") {\n var tiddler = tiddlyWiki.createTiddler(title);\n tiddler.loadFromDiv(e,title);\n }\n }\n tiddlyWiki.dirty = false;\n\n return tiddlyWiki;\n};\n\n\n \n// Internal.\n//\n// Returns a function that has a function body returning the given javaScriptExpression.\n// The function has the parameters:\n// \n// (tiddler, context, count, index)\n//\nconfig.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {\n var script = context["script"];\n var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";\n var fullText = (script ? script+";" : "")+functionText+";theFunction;";\n return eval(fullText);\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {\n var result = [];\n var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);\n tiddlyWiki.forEachTiddler(function(title,tiddler) {\n if (func(tiddler, context, undefined, undefined)) {\n result.push(tiddler);\n }\n });\n return result;\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {\n var message = "Extra parameter behind '"+actionName+"':";\n for (var i = firstUnusedIndex; i < parameter.length; i++) {\n message += " "+parameter[i];\n }\n this.handleError(place, message);\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {\n var result = \n (tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) \n ? 0\n : (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)\n ? -1 \n : +1; \n return result;\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {\n var result = \n (tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) \n ? 0\n : (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)\n ? +1 \n : -1; \n return result;\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {\n // To avoid evaluating the sortClause whenever two items are compared \n // we pre-calculate the sortValue for every item in the array and store it in a \n // temporary property ("forEachTiddlerSortValue") of the tiddlers.\n var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);\n var count = tiddlers.length;\n var i;\n for (i = 0; i < count; i++) {\n var tiddler = tiddlers[i];\n tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);\n }\n\n // Do the sorting\n tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);\n\n // Delete the temporary property that holds the sortValue. \n for (i = 0; i < tiddlers.length; i++) {\n delete tiddlers[i].forEachTiddlerSortValue;\n }\n};\n\n\n// Internal.\n//\nconfig.macros.forEachTiddler.trace = function(message) {\n displayMessage(message);\n};\n\n// Internal.\n//\nconfig.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {\n var message ="<<"+macroName;\n for (var i = 0; i < params.length; i++) {\n message += " "+params[i];\n }\n message += ">>";\n displayMessage(message);\n};\n\n\n// Internal.\n//\n// Creates an element that holds an error message\n// \nconfig.macros.forEachTiddler.createErrorElement = function(place, exception) {\n var message = (exception.description) ? exception.description : exception.toString();\n return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);\n};\n\n// Internal.\n//\n// @param place [may be null]\n//\nconfig.macros.forEachTiddler.handleError = function(place, exception) {\n if (place) {\n this.createErrorElement(place, exception);\n } else {\n throw exception;\n }\n};\n\n// Internal.\n//\n// Encodes the given string.\n//\n// Replaces \n// "$))" to ">>"\n// "$)" to ">"\n//\nconfig.macros.forEachTiddler.paramEncode = function(s) {\n var reGTGT = new RegExp("\s\s$\s\s)\s\s)","mg");\n var reGT = new RegExp("\s\s$\s\s)","mg");\n return s.replace(reGTGT, ">>").replace(reGT, ">");\n};\n\n// Internal.\n//\n// Returns the given original path (that is a file path, starting with "file:")\n// as a path to a local file, in the systems native file format.\n//\n// Location information in the originalPath (i.e. the "#" and stuff following)\n// is stripped.\n// \nconfig.macros.forEachTiddler.getLocalPath = function(originalPath) {\n // Remove any location part of the URL\n var hashPos = originalPath.indexOf("#");\n if(hashPos != -1)\n originalPath = originalPath.substr(0,hashPos);\n // Convert to a native file format assuming\n // "file:///x:/path/path/path..." - pc local file --> "x:\spath\spath\spath..."\n // "file://///server/share/path/path/path..." - FireFox pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n // "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."\n // "file://server/share/path/path/path..." - pc network file --> "\s\sserver\sshare\spath\spath\spath..."\n var localPath;\n if(originalPath.charAt(9) == ":") // pc local file\n localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\s\s");\n else if(originalPath.indexOf("file:///") === 0) // mac/unix local file\n localPath = unescape(originalPath.substr(7));\n else if(originalPath.indexOf("file:/") === 0) // mac/unix local file\n localPath = unescape(originalPath.substr(5));\n else // pc network file\n localPath = "\s\s\s\s" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\s\s"); \n return localPath;\n};\n\n// ---------------------------------------------------------------------------\n// Stylesheet Extensions (may be overridden by local StyleSheet)\n// ---------------------------------------------------------------------------\n//\nsetStylesheet(\n ".forEachTiddlerError{color: #ffffff;background-color: #880000;}",\n "forEachTiddler");\n\n//============================================================================\n// End of forEachTiddler Macro\n//============================================================================\n\n\n//============================================================================\n// String.startsWith Function\n//============================================================================\n//\n// Returns true if the string starts with the given prefix, false otherwise.\n//\nversion.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nString.prototype.startsWith = function(prefix) {\n var n = prefix.length;\n return (this.length >= n) && (this.slice(0, n) == prefix);\n};\n\n\n\n//============================================================================\n// String.endsWith Function\n//============================================================================\n//\n// Returns true if the string ends with the given suffix, false otherwise.\n//\nversion.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nString.prototype.endsWith = function(suffix) {\n var n = suffix.length;\n return (this.length >= n) && (this.right(n) == suffix);\n};\n\n\n//============================================================================\n// String.contains Function\n//============================================================================\n//\n// Returns true when the string contains the given substring, false otherwise.\n//\nversion.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nString.prototype.contains = function(substring) {\n return this.indexOf(substring) >= 0;\n};\n\n//============================================================================\n// Array.indexOf Function\n//============================================================================\n//\n// Returns the index of the first occurance of the given item in the array or \n// -1 when no such item exists.\n//\n// @param item [may be null]\n//\nversion.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.indexOf = function(item) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] == item) {\n return i;\n }\n }\n return -1;\n};\n\n//============================================================================\n// Array.contains Function\n//============================================================================\n//\n// Returns true when the array contains the given item, otherwise false. \n//\n// @param item [may be null]\n//\nversion.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.contains = function(item) {\n return (this.indexOf(item) >= 0);\n};\n\n//============================================================================\n// Array.containsAny Function\n//============================================================================\n//\n// Returns true when the array contains at least one of the elements \n// of the item. Otherwise (or when items contains no elements) false is returned.\n//\nversion.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.containsAny = function(items) {\n for(var i = 0; i < items.length; i++) {\n if (this.contains(items[i])) {\n return true;\n }\n }\n return false;\n};\n\n\n//============================================================================\n// Array.containsAll Function\n//============================================================================\n//\n// Returns true when the array contains all the items, otherwise false.\n// \n// When items is null false is returned (even if the array contains a null).\n//\n// @param items [may be null] \n//\nversion.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};\n//\nArray.prototype.containsAll = function(items) {\n for(var i = 0; i < items.length; i++) {\n if (!this.contains(items[i])) {\n return false;\n }\n }\n return true;\n};\n\n\n} // of "install only once"\n\n// Used Globals (for JSLint) ==============\n// ... DOM\n/*global document */\n// ... TiddlyWiki Core\n/*global convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, \n displayMessage, endSaveArea, hasClass, loadFile, saveFile, \n startSaveArea, store, wikify */\n//}}}\n\n\n/***\n!Licence and Copyright\nCopyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\nRedistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright notice, this\nlist of conditions and the following disclaimer in the documentation and/or other\nmaterials provided with the distribution.\n\nNeither the name of abego Software nor the names of its contributors may be\nused to endorse or promote products derived from this software without specific\nprior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY\nEXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\nSHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGE.\n***/\n\n
Welcome to your brand new [[MonkeyPirateTiddlyWiki|http://simonbaird.com/mptw/]]. This is the standard empty [[TiddlyWiki|http://www.tiddlywiki.com/]] (version <<version>>) preconfigured with a few bits and pieces from MPTW, in particular the layout, the colours, and the popular [[TagglyTagging|http://simonbaird.com/mptw/#TagglyTagging]]. If you're new to ~TagglyTagging then try the (slightly out-of-date) [[FAQ|http://simonbaird.com/mptw/#TagglyTaggingFAQ]] and [[Tutorial|http://simonbaird.com/mptw/#TagglyTaggingTutorial]].\n\nTo get started with this blank TiddlyWiki, you'll need to modify the following tiddlers:\n* SiteTitle & SiteSubtitle: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)\n* MainMenu: The menu (usually on the left)\n* DefaultTiddlers: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened\nYou'll also need to enter your username for signing your edits: <<option txtUserName>>\n\nTo create your own tiddlers, click 'new tiddler' in the right sidebar. To edit a tiddler click the 'edit' button in the tiddler's toolbar. To save all your tiddlers click 'save changes' in the right sidebar. If you're new to TiddlyWiki check out the formatting info [[here|http://www.tiddlywiki.com/#MainFeatures]].\n\nUse this to import tiddlers from another TiddlyWiki. You can use a local file (click Browse...) or type the url of an online TiddlyWiki.\n<<importTiddlers inline>>\nTo change your colour scheme you can edit the styles in StyleSheet. (Refer to StyleSheetColors and StyleSheetLayout for all styles used).\n\n
/***\n|Name|HaloscanMacro|\n|Created by|JimSpeth|\n|Location|http://end.com/~speth/HaloscanMacro.html|\n|Version|1.1.0|\n|Requires|~TW2.x|\n\n!Description\nComment and trackback support for TiddlyWiki (via Haloscan).\n\n!History\n* 16-Feb-06, version 1.1.0, drastic changes, now uses settings from haloscan account config\n* 31-Jan-06, version 1.0.1, fixed display of counts for default tiddlers\n* 30-Jan-06, version 1.0, initial release\n\n!Examples\n|!Source|!Output|h\n|{{{<<haloscan comments>>}}}|<<haloscan comments>>|\n|{{{<<haloscan trackbacks>>}}}|<<haloscan trackbacks>>|\n\n!Installation\nRegister for a [[Haloscan|http://www.haloscan.com]] account. It's free and painless.\nInstall the HaloscanMacro in a new tiddler with a tag of systemConfig (save and reload to activate).\nIn the macro configuration code (below), change //YourName// to your Haloscan account name.\nUse the macro somewhere in a tiddler (see ViewTemplate for an example).\n\n!Settings\nYou can adjust various options for your account in the member configuration area of Haloscan's web site. The macro will use these settings when formatting the links.\n\n!Code\n***/\n//{{{\n\n/* change "YourName" to your Haloscan account name */\nconfig.macros.haloscan = {account: "glosoli", baseURL: "http://www.haloscan.com/load/"};\n\nvar haloscanLoaded = 0;\nconfig.macros.haloscan.load = function ()\n{\n if (haloscanLoaded == 1)\n return;\n \n account = config.macros.haloscan.account;\n if (!account || (account == "YourName"))\n account = store.getTiddlerText("SiteTitle");\n \n var el = document.createElement('script');\n el.language = 'JavaScript'; \n el.type = 'text/javascript'; \n el.src = config.macros.haloscan.baseURL + account;\n document.documentElement.childNodes[0].appendChild(el);\n \n haloscanLoaded = 1;\n}\nconfig.macros.haloscan.load();\n\n/* this totally clobbers document.write, i hope that's ok */\nvar safeWrite = function(s)\n{\n document.written = s;\n return s;\n};\ndocument.write = safeWrite;\n\nconfig.macros.haloscan.refreshDefaultTiddlers = function ()\n{\n var start = store.getTiddlerText("DefaultTiddlers");\n if (start)\n {\n var titles = start.readBracketedList();\n for (var t=titles.length-1; t>=0; t--)\n story.refreshTiddler(titles[t], DEFAULT_VIEW_TEMPLATE, 1);\n }\n}\n\nvar haloscanRefreshed = 0;\nconfig.macros.haloscan.handler = function (place, macroName, params, wikifier, paramString, tiddler)\n{\n if (typeof HaloScan == 'undefined')\n {\n if (haloscanRefreshed == 0)\n {\n setTimeout("config.macros.haloscan.refreshDefaultTiddlers()", 1);\n haloscanRefreshed = 1;\n }\n return;\n }\n \n var id = story.findContainingTiddler(place).id.substr(7);\n var hs_search = new RegExp('\s\sW','gi');\n id = id.replace(hs_search,"_");\n \n account = config.macros.haloscan.account;\n if (!account || (account == "YourName"))\n account = store.getTiddlerText("SiteTitle");\n \n var haloscanError = function (msg)\n {\n createTiddlyError(place, config.messages.macroError.format(["HaloscanMacro"]), config.messages.macroErrorDetails.format(["HaloscanMacro", msg]));\n }\n \n if (params.length == 1)\n {\n if (params[0] == "comments")\n {\n postCount(id);\n commentsLabel = "Add/view comments"; //document.written;\n commentsPrompt = "Comments on this tiddler";\n var commentsHandler = function(e) { HaloScan(id); return false; };\n var commentsButton = createTiddlyButton(place, commentsLabel, commentsPrompt, commentsHandler);\n }\n else if (params[0] == "trackbacks")\n {\n postCountTB(id);\n trackbacksLabel = "Add/view trackbacks"; // document.written;\n trackbacksPrompt = "Trackbacks for this tiddler";\n var trackbacksHandler = function(e) { HaloScanTB(id); return false; };\n var trackbackButton = createTiddlyButton(place, trackbacksLabel, trackbacksPrompt, trackbacksHandler);\n }\n else\n haloscanError("unknown parameter: " + params[0]);\n }\n else if (params.length == 0)\n haloscanError("missing parameter");\n else\n haloscanError("bad parameter count");\n}\n\n//}}}\n
/***\n|Name:|HideWhenMacro|\n|Author:|SimonBaird|\n|Source:|http://tiddlyspot.com/mptw/#HideWhenMacro|\n|Version:|1.0.1|\n|Date:|30-Jul-2006|\n\n!Description\nImplements hideWhen and showWhen macros for use in ViewTemplate\n\n!Example\n{{{<div macro="showWhen tiddler.tags.contains('Task')">[[TaskToolbar]]</div>}}}\n\n***/\n//{{{\n\nmerge(config.macros,{\n\n hideWhen: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n if (eval(paramString)) {\n removeChildren(place);\n place.parentNode.removeChild(place);\n }\n }},\n\n showWhen: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {\n config.macros.hideWhen.handler(place,macroName,params,wikifier,'!('+paramString+')',tiddler);\n }}\n \n});\n\n//}}}\n
/***\nTo use, add {{{[[HorizontalMainMenuStyles]]}}} to your StyleSheet tiddler, or you can just paste the CSS in directly. See also HorizontalMainMenu and PageTemplate.\n***/\n/*{{{*/\n\n#topMenu br {display:none; }\n#topMenu { background: #39a; }\n#topMenu { padding:2px; }\n#topMenu .button, #topMenu .tiddlyLink {\n margin-left:0.5em; margin-right:0.5em;\n padding-left:3px; padding-right:3px;\n color:white; font-size:115%;\n}\n#topMenu .button:hover, #topMenu .tiddlyLink:hover { background:#178;}\n\n#displayArea { margin: 1em 15.7em 0em 1em; } /* so we use the freed up space */\n\n/* just in case want some QuickOpenTags in your topMenu */\n#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }\n#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }\n#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }\n\n\n/*}}}*/
/***\n''Import Tiddlers Plugin for TiddlyWiki version 1.2.x and 2.0''\n^^author: Eric Shulman - ELS Design Studios\nsource: http://www.TiddlyTools.com/#ImportTiddlersPlugin\nlicense: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^\n\nWhen many people share and edit copies of the same TiddlyWiki document, the ability to quickly collect all these changes back into a single, updated document that can then be redistributed to the entire group is very important. This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents. It can also be very useful when moving your own tiddlers from document to document (e.g., when upgrading to the latest version of TiddlyWiki, or 'pre-loading' your favorite stylesheets into a new 'empty' TiddlyWiki document.)\n\n!!!!!Inline interface (live)\n<<<\n<<importTiddlers inline>>\n<<<\n!!!!!Macro Syntax\n<<<\n{{{<<importTiddlers>>}}}\ncreates "import tiddlers" link. click to show/hide import control panel\n\n{{{<<importTiddlers inline>>}}}\ncreates import control panel directly in tiddler content\n\n{{{<<importTiddlers filter source quiet ask>>}}}\nnon-interactive 'automatic' import.\n''filter'' determines which tiddlers will be automatically selected for importing. Use one of the following keywords:\n>''"new"'' retrieves only tiddlers that are found in the import source document, but do not yet exist in the destination document\n>''"changes"'' retrieves only tiddlers that exist in both documents for which the import source tiddler is newer than the existing tiddler\n>''"updates"'' retrieves both ''new'' and ''changed'' tiddlers (this is the default action when none is specified)\n>''"all"'' retrieves ALL tiddlers from the import source document, even if they have not been changed.\n''source'' is the location of the imported document. It can be either a local document or an URL:\n>filename is any local path/file, in whatever format your system requires\n>URL is any remote web location that starts with "http://" or "https://"\n''"quiet"'' (optional)\n>supresses all status message during the import processing (e.g., "opening local file...", "found NN tiddlers..." etc). Note that if ANY tiddlers are actualy imported, a final information message will still be displayed (along with the ImportedTiddlers report), even when 'quiet' is specified. This ensures that changes to your document cannot occur without any visible indication at all.\n''"ask"'' (optional)\n>adds interactive confirmation. A browser message box (OK/Cancel) is displayed for each tiddler that will be imported, so that you can manually bypass any tiddlers that you do not want to import.\n\n''Special tag values: importReplace and importPublic''\n\nBy adding these special tags to an existing tiddler, you can precisely control whether or not to allow updates to that tiddler as well as decide which tiddlers in your document can be automatically imported by others.\n*''For maximum safety, the default action is to prevent existing tiddlers from being unintentionally overwritten by incoming tiddlers.'' To allow an existing tiddler to be overwritten by an imported tiddler, you must tag the existing tiddler with ''<<tag importReplace>>''\n*''For maximum privacy, the default action for //outgoing// tiddlers is to NOT automatically share your tiddlers with others.'' To allow a tiddler in your document to be shared via auto-import actions by others, you must tag it with ''<<tag importPublic>>''\n//Note: these tags are only applied when using the auto-import processing. When using the interactive control panel, all tiddlers in the imported document are available in the listbox, regardless of their tag values.//\n<<<\n!!!!!Interactive Usage\n<<<\nWhen used interactively, a control panel is displayed consisting of an "import source document" filename input (text field plus a ''[Browse...]'' button), a listbox of available tiddlers, a "differences only" checkbox, an "add tags" input field and four push buttons: ''[open]'', ''[select all]'', ''[import]'' and ''[close]''.\n\nPress ''[browse]'' to select a TiddlyWiki document file to import. You can also type in the path/filename or a remote document URL (starting with http://)and press ''[open]''. //Note: There may be some delay to permit the browser time to access and load the document before updating the listbox with the titles of all tiddlers that are available to be imported.//\n\nSelect one or more titles from the listbox (hold CTRL or SHIFT while clicking to add/remove the highlight from individual list items). You can press ''[select all]'' to quickly highlight all tiddler titles in the list. Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time. When you have chosen the tiddlers you want to import and entered any extra tags, press ''[import]'' to begin copying them to the current TiddlyWiki document.\n\n''select: all, new, changes, or differences''\n\nYou can click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list. This makes it very quick and easy to find and import just the updated tiddlers you are interested in:\n>''"all"'' selects ALL tiddlers from the import source document, even if they have not been changed.\n>''"new"'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document\n>''"changes"'' selects only tiddlers that exist in both documents but that are newer in the source document\n>''"differences"'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)\n\n''Import Tagging:''\n\nTiddlers that have been imported can be automatically tagged, so they will be easier to find later on, after they have been added to your document. New tags are entered into the "add tags" input field, and then //added// to the existing tags for each tiddler as it is imported.\n\n''Skip, Rename, Merge, or Replace:''\n\nWhen importing a tiddler whose title is identical to one that already exists, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''[skip]'', ''[rename]'', ''[merge]'' and ''[replace]''.\n\nTo bypass importing this tiddler, press ''[skip]''. To import the tiddler with a different name (so that both the tiddlers will exist when the import is done), enter a new title in the input field and then press ''[rename]''. Press ''[merge]'' to combine the content from both tiddlers into a single tiddler. Press ''[replace]'' to overwrite the existing tiddler with the imported one, discarding the previous tiddler content.\n\n//Note: if both the title ''and'' modification date/////time match, the imported tiddler is assumed to be identical to the existing one, and will be automatically skipped (i.e., not imported) without asking.//\n\n''Import Report History''\n\nWhen tiddlers are imported, a report is generated into ImportedTiddlers, indicating when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom. It also includes a list with the title, date and author of each tiddler that was imported.\n\nWhen the import process is completed, the ImportedTiddlers report is automatically displayed for your review. If more tiddlers are subsequently imported, a new report is //added// to ImportedTiddlers, above the previous report (i.e., at the top of the tiddler), so that a reverse-chronological history of imports is maintained.\n\nIf a cumulative record is not desired, the ImportedTiddlers report may be deleted at any time. A new ImportedTiddlers report will be created the next time tiddlers are imported.\n\nNote: You can prevent the ImportedTiddlers report from being generated for any given import activity by clearing the "create a report" checkbox before beginning the import processing.\n\n<<<\n!!!!!Installation\n<<<\ncopy/paste the following tiddlers into your document:\n''ImportTiddlersPlugin'' (tagged with <<tag systemConfig>>)\n\ncreate/edit ''SideBarOptions'': (sidebar menu items) \n^^Add "< < ImportTiddlers > >" macro^^\n\n''Quick Installation Tip #1:''\nIf you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.\n<<<\n!!!!!Revision History\n<<<\n''2006.02.17 [2.6.0]''\nRemoved "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences. Also fixed initialization handling for "add new tags" so that checkbox state is correctly tracked when panel is first displayed.\n''2006.02.16 [2.5.4]''\nadded checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.\n''2006.02.14 [2.5.3]''\nFF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()\n''2006.02.10 [2.5.2]''\ncorrected unintended global variable in importReport().\n''2006.02.05 [2.5.1]''\nmoved globals from window.* to config.macros.importTiddlers.* to avoid FireFox crash bug when referencing globals\n''2006.01.18 [2.5.0]''\nadded checkbox for "create a report". Default is to create/update the ImportedTiddlers report. Clear the checkbox to skip this step.\n''2006.01.15 [2.4.1]''\nadded "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic\n''2006.01.15 [2.4.0]''\nAdded support for tagging individual tiddlers with importSkip, importReplace, and/or importPrivate to control which tiddlers can be overwritten or shared with others when using auto-import macro syntax. Defaults are to SKIP overwriting existing tiddlers with imported tiddlers, and ALLOW your tiddlers to be auto-imported by others.\n''2006.01.15 [2.3.2]''\nAdded "ask" parameter to confirm each tiddler before importing (for use with auto-importing)\n''2006.01.15 [2.3.1]''\nStrip TW core scripts from import source content and load just the storeArea into the hidden IFRAME. Makes loading more efficient by reducing the document size and by preventing the import document from executing its TW initialization (including plugins). Seems to resolve the "Found 0 tiddlers" problem. Also, when importing local documents, use convertUTF8ToUnicode() to convert the file contents so support international characters sets.\n''2006.01.12 [2.3.0]''\nReorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest. Let's processing continue while waiting for remote hosts to respond to URL requests. Added non-interactive 'batch' macro mode, using parameters to specify which tiddlers to import, and from what document source. Improved error messages and diagnostics, plus an optional 'quiet' switch for batch mode to eliminate //most// feedback.\n''2006.01.11 [2.2.0]''\nAdded "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck\n''2006.01.09 [2.1.1]''\nWhen a URL is typed in, and then the "open" button is pressed, it generates both an onChange event for the file input and a click event for open button. This results in multiple XMLHttpRequest()'s which seem to jam things up quite a bit. I removed the onChange handling for file input field. To open a file (local or URL), you must now explicitly press the "open" button in the control panel.\n''2006.01.08 [2.1.0]''\nIMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements. Adapted from example code and techniques courtesy of Jonny LeRoy.\n''2006.01.06 [2.0.2]''\nWhen refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.\n''2006.01.04 [2.0.1]''\nWhen "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.\n''2005.12.27 [2.0.0]''\nUpdate for TW2.0\nDefer initial panel creation and only register a notification function when panel first is created\n''2005.12.22 [1.3.1]''\ntweak formatting in importReport() and add 'discard report' link to output\n''2005.12.03 [1.3.0]''\nDynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding. Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)\n''2005.11.29 [1.2.1]''\nfixed formatting of 'detail info' in importReport()\n''2005.11.11 [1.2.0]''\nadded 'inline' param to embed controls in a tiddler\n''2005.11.09 [1.1.0]''\nonly load HTML and CSS the first time the macro handler is called. Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.\n''2005.10.25 [1.0.5]''\nfixed typo in importReport() that prevented reports from being generated\n''2005.10.09 [1.0.4]''\ncombined documentation with plugin code instead of using separate tiddlers\n''2005.08.05 [1.0.3]''\nmoved CSS and HTML definitions into plugin code instead of using separate tiddlers\n''2005.07.27 [1.0.2]''\ncore update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()\n''2005.07.23 [1.0.1]''\nadded parameter checks and corrected addNotification() usage\n''2005.07.20 [1.0.0]''\nInitial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]\n<<<\n!!!!!Code\n***/\n\n// // Version\n//{{{\nversion.extensions.importTiddlers = {major: 2, minor: 6, revision: 0, date: new Date(2006,2,17)};\n//}}}\n\n// // 1.2.x compatibility\n//{{{\nif (!window.story) window.story=window;\nif (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}\nif (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}\nif (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}\n//}}}\n\n// // IE needs explicit global scoping for functions/vars called from browser events\n//{{{\nwindow.onClickImportButton=onClickImportButton;\nwindow.loadImportFile=loadImportFile;\nwindow.refreshImportList=refreshImportList;\n//}}}\n\n// // default cookie/option values\n//{{{\nif (!config.options.chkImportReport) config.options.chkImportReport=true;\n//}}}\n\n\n// // ''MACRO DEFINITION''\n\n//{{{\nconfig.macros.importTiddlers = { };\nconfig.macros.importTiddlers = {\n label: "import tiddlers",\n prompt: "Copy tiddlers from another document",\n countMsg: "%0 tiddlers selected for import",\n src: "", // path/filename or URL of document to import\n inbound: null, // hash-indexed array of tiddlers from other document\n newTags: "", // text of tags added to imported tiddlers\n addTags: true, // add new tags to imported tiddlers\n listsize: 8, // # of lines to show in imported tiddler list\n importTags: true, // include tags from remote source document when importing a tiddler\n keepTags: true, // retain existing tags when replacing a tiddler\n index: 0, // current processing index in import list\n sort: "" // sort order for imported tiddler listbox\n};\n\nconfig.macros.importTiddlers.handler = function(place,macroName,params) {\n // LINK WITH FLOATING PANEL\n if (!params[0]) {\n createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);\n return;\n }\n // INLINE TIDDLER CONTENT\n if (params[0]=="inline") {\n createImportPanel(place);\n document.getElementById("importPanel").style.position="static";\n document.getElementById("importPanel").style.display="block";\n return;\n }\n // NON-INTERACTIVE BATCH MODE\n switch (params[0]) {\n case 'all':\n case 'new':\n case 'changes':\n case 'updates':\n var filter=params.shift();\n break;\n default:\n var filter="updates";\n break;\n } \n if (!params[0]||!params[0].length) return; // filename is required\n config.macros.importTiddlers.src=params.shift();\n var quiet=(params[0]=="quiet"); if (quiet) params.shift();\n var ask=(params[0]=="ask"); if (ask) params.shift();\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n // load storeArea from a hidden IFRAME, then apply import rules and add/replace tiddlers\n loadImportFile(config.macros.importTiddlers.src,filter,quiet,ask,autoImportTiddlers);\n}\n//}}}\n\n// // ''READ TIDDLERS FROM ANOTHER DOCUMENT''\n\n//{{{\nfunction loadImportFile(src,filter,quiet,ask,callback) {\n if (!quiet) clearMessage();\n // LOCAL FILE\n if ((src.substr(0,7)!="http://")&&(src.substr(0,8)!="https://")) {\n if (!quiet) displayMessage("Opening local document: "+ src);\n var txt=loadFile(src);\n if(!txt) { if (!quiet) displayMessage("Could not open local document: "+src); }\n else {\n var s="<html><body>"+txt.substr(txt.indexOf('<div id="storeArea">'));\n if (!quiet) displayMessage(txt.length+" bytes in document. ("+s.length+" bytes used for tiddler storage)");\n config.macros.importTiddlers.inbound = readImportedTiddlers(convertUTF8ToUnicode(s));\n var count=config.macros.importTiddlers.inbound?config.macros.importTiddlers.inbound.length:0;\n if (!quiet) displayMessage("Found "+count+" tiddlers in "+src);\n if (callback) callback(src,filter,quiet,ask);\n }\n return;\n }\n // REMOTE FILE\n var x; // XML object\n try {x = new XMLHttpRequest()}\n catch(e) {\n try {x = new ActiveXObject("Msxml2.XMLHTTP")}\n catch (e) {\n try {x = new ActiveXObject("Microsoft.XMLHTTP")}\n catch (e) { return }\n }\n }\n x.onreadystatechange = function() {\n if (x.readyState == 4) {\n if (x.status == 200) {\n var sa="<html><body>"+x.responseText.substr(x.responseText.indexOf('<div id="storeArea">'));\n if (!quiet) displayMessage(x.responseText.length+" bytes in document. ("+sa.length+" bytes used for tiddler storage)");\n config.macros.importTiddlers.inbound = readImportedTiddlers(sa);\n var count=config.macros.importTiddlers.inbound?config.macros.importTiddlers.inbound.length:0;\n if (!quiet) displayMessage("Found "+count+" tiddlers in "+src);\n if (callback) callback(src,filter,quiet,ask);\n }\n else\n if (!quiet) displayMessage("Could not open remote document:"+ src+" (error="+x.status+")");\n }\n }\n if (document.location.protocol=="file:") { // UniversalBrowserRead only works from a local file context\n try {netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead')}\n catch (e) { if (!quiet) displayMessage(e.description?e.description:e.toString()); }\n }\n if (!quiet) displayMessage("Opening remote document: "+ src);\n try {\n var url=src+(src.indexOf('?')<0?'?':'&')+'nocache='+Math.random();\n x.open("GET",url,true);\n x.overrideMimeType('text/html');\n x.send(null);\n }\n catch (e) {\n if (!quiet) {\n displayMessage("Could not open remote document: "+src);\n displayMessage(e.description?e.description:e.toString());\n }\n }\n}\n\nfunction readImportedTiddlers(txt)\n{\n var importedTiddlers = [];\n // create frame\n var f=document.getElementById("importFrame");\n if (f) document.body.removeChild(f);\n f=document.createElement("iframe");\n f.id="importFrame";\n f.style.width="0px"; f.style.height="0px"; f.style.border="0px";\n document.body.appendChild(f);\n // get document\n var d=f.document;\n if (f.contentDocument) d=f.contentDocument; // For NS6\n else if (f.contentWindow) d=f.contentWindow.document; // For IE5.5 and IE6\n // load source into document\n d.open(); d.writeln(txt); d.close();\n // read tiddler DIVs from storeArea DOM element \n var importStore = [];\n var importStoreArea = d.getElementById("storeArea");\n if (!importStoreArea || !(importStore=importStoreArea.childNodes) || (importStore.length==0)) { return null; }\n importStoreArea.normalize();\n for(var t = 0; t < importStore.length; t++) {\n var e = importStore[t];\n var title = null;\n if(e.getAttribute)\n title = e.getAttribute("tiddler");\n if(!title && e.id && (e.id.substr(0,5) == "store"))\n title = e.id.substr(5);\n if(title && title != "") {\n var theImported = new Tiddler();\n theImported.loadFromDiv(e,title);\n importedTiddlers.push(theImported);\n }\n }\n return importedTiddlers;\n}\n//}}}\n\n// // ''NON-INTERACTIVE IMPORT''\n\n// // import all/new/changed tiddlers into store, replacing or adding tiddlers as needed\n//{{{\nfunction autoImportTiddlers(src,filter,quiet,ask)\n{\n var count=0;\n if (config.macros.importTiddlers.inbound) for (var t=0;t<config.macros.importTiddlers.inbound.length;t++) {\n var theImported = config.macros.importTiddlers.inbound[t];\n var theExisting = store.getTiddler(theImported.title);\n\n // only import tiddlers if tagged with "importPublic"\n if (theImported.tags && theImported.tags.find("importPublic")==null)\n { config.macros.importTiddlers.inbound[t].status=""; continue; } // status=="" means don't show in report\n\n // never import the "ImportedTiddlers" history from the other document...\n if (theImported.title=='ImportedTiddlers')\n { config.macros.importTiddlers.inbound[t].status=""; continue; } // status=="" means don't show in report\n\n // check existing tiddler for importReplace, or systemConfig tags\n config.macros.importTiddlers.inbound[t].status="added"; // default - add any tiddlers not filtered out\n if (store.tiddlerExists(theImported.title)) {\n config.macros.importTiddlers.inbound[t].status="replaced";\n if (!theExisting.tags||(theExisting.tags.find("importReplace")==null))\n { config.macros.importTiddlers.inbound[t].status="not imported - tiddler already exists (use importReplace to allow changes)"; continue; }\n if ((theExisting.tags.find("systemConfig")!=null)||(theImported.tags.find("systemConfig")!=null))\n config.macros.importTiddlers.inbound[t].status+=" - WARNING: an active systemConfig plugin has been added or updated";\n }\n\n // apply the all/new/changes/updates filter \n if (filter!="all") {\n if ((filter=="new") && store.tiddlerExists(theImported.title))\n { config.macros.importTiddlers.inbound[t].status="not imported - tiddler already exists"; continue; }\n if ((filter=="changes") && !store.tiddlerExists(theImported.title))\n { config.macros.importTiddlers.inbound[t].status="not imported - new tiddler"; continue; }\n if (store.tiddlerExists(theImported.title) && ((theExisting.modified.getTime()-theImported.modified.getTime())>=0))\n { config.macros.importTiddlers.inbound[t].status="not imported - tiddler is unchanged"; continue; }\n }\n\n // get confirmation if required\n if (ask && !confirm("Import "+(theExisting?"updated":"new")+" tiddler '"+theImported.title+"'\snfrom "+src))\n { config.macros.importTiddlers.inbound[t].status="skipped - cancelled by user"; continue; }\n\n // DO THE IMPORT!!\n store.addTiddler(theImported); count++;\n }\n importReport(quiet); // generate a report (as needed) and display it if not 'quiet'\n if (count) store.setDirty(true); \n // always show final message when tiddlers were actually imported\n if (!quiet||count) displayMessage("Imported "+count+" tiddler"+(count!=1?"s":"")+" from "+src);\n}\n//}}}\n\n// // ''REPORT GENERATOR''\n\n//{{{\nfunction importReport(quiet)\n{\n if (!config.macros.importTiddlers.inbound) return;\n // DEBUG alert('importReport: start');\n\n // if import was not completed, the Ask panel will still be open... close it now.\n var askpanel=document.getElementById('importAskPanel'); if (askpanel) askpanel.style.display='none'; \n // get the alphasorted list of tiddlers\n var tiddlers = config.macros.importTiddlers.inbound;\n tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // gather the statistics\n var count=tiddlers.length;\n var added=0; var replaced=0; var renamed=0; var skipped=0; var merged=0;\n for (var t=0; t<count; t++)\n if (tiddlers[t].status)\n {\n if (tiddlers[t].status=='added') added++;\n if (tiddlers[t].status.substr(0,7)=='skipped') skipped++;\n if (tiddlers[t].status.substr(0,6)=='rename') renamed++;\n if (tiddlers[t].status.substr(0,7)=='replace') replaced++;\n if (tiddlers[t].status.substr(0,6)=='merged') merged++;\n }\n var omitted=count-(added+replaced+renamed+skipped+merged);\n // DEBUG alert('stats done: '+count+' total, '+added+' added, '+skipped+' skipped, '+renamed+' renamed, '+replaced+' replaced, '+merged+' merged');\n // skip the report if nothing was imported\n if (added+replaced+renamed+merged==0) return;\n // skip the report if not desired by user\n if (!config.options.chkImportReport) {\n // reset status flags\n for (var t=0; t<count; t++) config.macros.importTiddlers.inbound[t].status="";\n // refresh display since tiddlers have been imported\n store.notifyAll();\n // quick message area summary report\n var msg=(added+replaced+renamed+merged)+' of '+count+' tiddler'+((count!=1)?'s':"");\n msg+=' imported from '+config.macros.importTiddlers.src.replace(/\s\s/g,'/')\n displayMessage(msg);\n return;\n }\n // create the report tiddler (if not already present)\n var tiddler = store.getTiddler('ImportedTiddlers');\n if (!tiddler) // create new report tiddler if it doesn't exist\n {\n tiddler = new Tiddler();\n tiddler.title = 'ImportedTiddlers';\n tiddler.text = "";\n }\n // format the report header\n var now = new Date();\n var newText = "";\n newText += "On "+now.toLocaleString()+", "+config.options.txtUserName+" imported tiddlers from\sn";\n newText += "[["+config.macros.importTiddlers.src+"|"+config.macros.importTiddlers.src+"]]:\sn";\n newText += "<"+"<"+"<\sn";\n newText += "Out of "+count+" tiddler"+((count!=1)?"s ":" ")+" in {{{"+config.macros.importTiddlers.src.replace(/\s\s/g,'/')+"}}}:\sn";\n if (added+renamed>0)\n newText += (added+renamed)+" new tiddler"+(((added+renamed)!=1)?"s were":" was")+" added to your document.\sn";\n if (merged>0)\n newText += merged+" tiddler"+((merged!=1)?"s were":" was")+" merged with "+((merged!=1)?"":"an ")+"existing tiddler"+((merged!=1)?"s":"")+".\sn"; \n if (replaced>0)\n newText += replaced+" existing tiddler"+((replaced!=1)?"s were":" was")+" replaced.\sn"; \n if (skipped>0)\n newText += skipped+" tiddler"+((skipped!=1)?"s were":" was")+" skipped after asking.\sn"; \n if (omitted>0)\n newText += omitted+" tiddler"+((omitted!=1)?"s":"")+((omitted!=1)?" were":" was")+" not imported.\sn";\n if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)\n newText += "imported tiddlers were tagged with: \s""+config.macros.importTiddlers.newTags+"\s"\sn";\n // output the tiddler detail and reset status flags\n for (var t=0; t<count; t++)\n if (tiddlers[t].status!="")\n {\n newText += "#["+"["+tiddlers[t].title+"]"+"]";\n newText += ((tiddlers[t].status!="added")?("^^\sn"+tiddlers[t].status+"^^"):"")+"\sn";\n config.macros.importTiddlers.inbound[t].status="";\n }\n newText += "<"+"<"+"<\sn";\n // output 'discard report' link\n newText += "<html><input type=\s"button\s" href=\s"javascript:;\s" ";\n newText += "onclick=\s"story.closeTiddler('"+tiddler.title+"'); store.deleteTiddler('"+tiddler.title+"');\s" ";\n newText += "value=\s"discard report\s"></html>";\n // update the ImportedTiddlers content and show the tiddler\n tiddler.text = newText+((tiddler.text!="")?'\sn----\sn':"")+tiddler.text;\n tiddler.modifier = config.options.txtUserName;\n tiddler.modified = new Date();\n store.addTiddler(tiddler);\n if (!quiet) story.displayTiddler(null,"ImportedTiddlers",1,null,null,false);\n story.refreshTiddler("ImportedTiddlers",1,true);\n // refresh the display\n store.notifyAll();\n}\n//}}}\n\n// // ''INTERFACE DEFINITION''\n\n// // Handle link click to create/show/hide control panel\n//{{{\nfunction onClickImportMenu(e)\n{\n if (!e) var e = window.event;\n var parent=resolveTarget(e).parentNode;\n var panel = document.getElementById("importPanel");\n if (panel==undefined || panel.parentNode!=parent)\n panel=createImportPanel(parent);\n var isOpen = panel.style.display=="block";\n if(config.options.chkAnimate)\n anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));\n else\n panel.style.display = isOpen ? "none" : "block" ;\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return(false);\n}\n//}}}\n\n// // Create control panel: HTML, CSS, register for notification\n//{{{\nfunction createImportPanel(place) {\n var panel=document.getElementById("importPanel");\n if (panel) { panel.parentNode.removeChild(panel); }\n setStylesheet(config.macros.importTiddlers.css,"importTiddlers");\n panel=createTiddlyElement(place,"span","importPanel",null,null)\n panel.innerHTML=config.macros.importTiddlers.html;\n store.addNotification(null,refreshImportList); // refresh listbox after every tiddler change\n refreshImportList();\n return panel;\n}\n//}}}\n\n// // CSS\n//{{{\nconfig.macros.importTiddlers.css = '\s\n#importPanel {\s\n display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\s\n padding: 0.5em; margin:0em; text-align:left; font-size: 8pt;\s\n background-color: #eee; color:#000000; \s\n border:1px solid black; border-bottom-width: 3px; border-right-width: 3px; -moz-border-radius:1em;\s\n}\s\n#importPanel a { color:#009; }\s\n#importPanel input { width: 98%; margin: 1px; font-size:8pt; }\s\n#importPanel select { width: 98%; margin: 1px; font-size:8pt; }\s\n#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\s\n#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\s\n#importAskPanel { display:none; margin:0.5em 0em 0em 0em; }\s\n';\n//}}}\n\n// // HTML\n//{{{\nconfig.macros.importTiddlers.html = '\s\n<span style="float:left; padding:1px; white-space:nowrap">\s\n import from source document\s\n</span>\s\n<span style="float:right; padding:1px; white-space:nowrap">\s\n <input type=checkbox id="chkImportReport" checked style="height:1em; width:auto"\s\n onClick="config.options[\s'chkImportReport\s']=this.checked;">create a report\s\n</span>\s\n<input type="file" id="fileImportSource" size=56\s\n onKeyUp="config.macros.importTiddlers.src=this.value"\s\n onChange="config.macros.importTiddlers.src=this.value;">\s\n<span style="float:left; padding:1px; white-space:nowrap">\s\n select:\s\n <a href="JavaScript:;" id="importSelectAll"\s\n onclick="onClickImportButton(this)" title="select all tiddlers">\s\n &nbsp;all&nbsp;</a>\s\n <a href="JavaScript:;" id="importSelectNew"\s\n onclick="onClickImportButton(this)" title="select tiddlers not already in destination document">\s\n &nbsp;added&nbsp;</a> \s\n <a href="JavaScript:;" id="importSelectChanges"\s\n onclick="onClickImportButton(this)" title="select tiddlers that have been updated in source document">\s\n &nbsp;changes&nbsp;</a> \s\n <a href="JavaScript:;" id="importSelectDifferences"\s\n onclick="onClickImportButton(this)" title="select tiddlers that have been added or are different from existing tiddlers">\s\n &nbsp;differences&nbsp;</a> \s\n <a href="JavaScript:;" id="importToggleFilter"\s\n onclick="onClickImportButton(this)" title="show/hide selection filter">\s\n &nbsp;filter&nbsp;</a> \s\n</span>\s\n<span style="float:right; padding:1px; white-space:nowrap">\s\n <a href="JavaScript:;" id="importListSmaller"\s\n onclick="onClickImportButton(this)" title="reduce list size">\s\n &nbsp;&#150;&nbsp;</a>\s\n <a href="JavaScript:;" id="importListLarger"\s\n onclick="onClickImportButton(this)" title="increase list size">\s\n &nbsp;+&nbsp;</a>\s\n <a href="JavaScript:;" id="importListMaximize"\s\n onclick="onClickImportButton(this)" title="maximize/restore list size">\s\n &nbsp;=&nbsp;</a>\s\n</span>\s\n<select id="importList" size=8 multiple\s\n onchange="setTimeout(\s'refreshImportList(\s'+this.selectedIndex+\s')\s',1)">\s\n <!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\s\n</select>\s\n<input type=checkbox id="chkAddTags" checked style="height:1em; width:auto"\s\n onClick="config.macros.importTiddlers.addTags=this.checked;">add new tags &nbsp;\s\n<input type=checkbox id="chkImportTags" checked style="height:1em; width:auto"\s\n onClick="config.macros.importTiddlers.importTags=this.checked;">import source tags &nbsp;\s\n<input type=checkbox id="chkKeepTags" checked style="height:1em; width:auto"\s\n onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing tags\s\n<input type=text id="txtNewTags" size=15 onKeyUp="config.macros.importTiddlers.newTags=this.value" autocomplete=off>\s\n<div align=center>\s\n <input type=button id="importOpen" class="importButton" style="width:32%" value="open"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importStart" class="importButton" style="width:32%" value="import"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importClose" class="importButton" style="width:32%" value="close"\s\n onclick="onClickImportButton(this)">\s\n</div>\s\n<div id="importAskPanel">\s\n tiddler already exists:\s\n <input type=text id="importNewTitle" size=15 autocomplete=off">\s\n <div align=center>\s\n <input type=button id="importSkip" class="importButton" style="width:23%" value="skip"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importRename" class="importButton" style="width:23%" value="rename"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importMerge" class="importButton" style="width:23%" value="merge"\s\n onclick="onClickImportButton(this)">\s\n <input type=button id="importReplace" class="importButton" style="width:23%" value="replace"\s\n onclick="onClickImportButton(this)">\s\n </div>\s\n</div>\s\n';\n//}}}\n\n// // refresh listbox\n//{{{\nfunction refreshImportList(selectedIndex)\n{\n var theList = document.getElementById("importList");\n if (!theList) return;\n // if nothing to show, reset list content and size\n if (!config.macros.importTiddlers.inbound) \n {\n while (theList.length > 0) { theList.options[0] = null; }\n theList.options[0]=new Option('please open a document...',"",false,false);\n theList.size=config.macros.importTiddlers.listsize;\n return;\n }\n // get the sort order\n if (!selectedIndex) selectedIndex=0;\n if (selectedIndex==0) config.macros.importTiddlers.sort='title'; // heading\n if (selectedIndex==1) config.macros.importTiddlers.sort='title';\n if (selectedIndex==2) config.macros.importTiddlers.sort='modified';\n if (selectedIndex==3) config.macros.importTiddlers.sort='tags';\n if (selectedIndex>3) {\n // display selected tiddler count\n for (var t=0,count=0; t < theList.options.length; t++) count+=(theList.options[t].selected&&theList.options[t].value!="")?1:0;\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n return; // no refresh needed\n }\n\n // get the alphasorted list of tiddlers (optionally, filter out unchanged tiddlers)\n var tiddlers=config.macros.importTiddlers.inbound;\n tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });\n // clear current list contents\n while (theList.length > 0) { theList.options[0] = null; }\n // add heading and control items to list\n var i=0;\n var indent=String.fromCharCode(160)+String.fromCharCode(160);\n theList.options[i++]=new Option(tiddlers.length+' tiddler'+((tiddlers.length!=1)?'s are':' is')+' in the document',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="title" )?">":indent)+' [by title]',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="modified")?">":indent)+' [by date]',"",false,false);\n theList.options[i++]=new Option(((config.macros.importTiddlers.sort=="tags")?">":indent)+' [by tags]',"",false,false);\n // output the tiddler list\n switch(config.macros.importTiddlers.sort)\n {\n case "title":\n for(var t = 0; t < tiddlers.length; t++)\n theList.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);\n break;\n case "modified":\n // sort descending for newest date first\n tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });\n var lastSection = "";\n for(var t = 0; t < tiddlers.length; t++) {\n var tiddler = tiddlers[t];\n var theSection = tiddler.modified.toLocaleDateString();\n if (theSection != lastSection) {\n theList.options[i++] = new Option(theSection,"",false,false);\n lastSection = theSection;\n }\n theList.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);\n }\n break;\n case "tags":\n var theTitles = {}; // all tiddler titles, hash indexed by tag value\n var theTags = new Array();\n for(var t=0; t<tiddlers.length; t++) {\n var title=tiddlers[t].title;\n var tags=tiddlers[t].tags;\n for(var s=0; s<tags.length; s++) {\n if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }\n theTitles[tags[s]].push(title);\n }\n }\n theTags.sort();\n for(var tagindex=0; tagindex<theTags.length; tagindex++) {\n var theTag=theTags[tagindex];\n theList.options[i++]=new Option(theTag,"",false,false);\n for(var t=0; t<theTitles[theTag].length; t++)\n theList.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);\n }\n break;\n }\n theList.selectedIndex=selectedIndex; // select current control item\n if (theList.size<config.macros.importTiddlers.listsize) theList.size=config.macros.importTiddlers.listsize;\n if (theList.size>theList.options.length) theList.size=theList.options.length;\n}\n//}}}\n\n// // Control interactions\n//{{{\nfunction onClickImportButton(which)\n{\n // DEBUG alert(which.id);\n var theList = document.getElementById('importList');\n if (!theList) return;\n var thePanel = document.getElementById('importPanel');\n var theAskPanel = document.getElementById('importAskPanel');\n var theNewTitle = document.getElementById('importNewTitle');\n var count=0;\n switch (which.id)\n {\n case 'fileImportSource':\n case 'importOpen': // load import source into hidden frame\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n if (config.macros.importTiddlers.src=="") break;\n // Load document into hidden iframe so we can read it's DOM and fill the list\n loadImportFile(config.macros.importTiddlers.src,"all",null,null,function(src,filter,quiet,ask){window.refreshImportList(0);});\n break;\n case 'importSelectAll': // select all tiddler list items (i.e., not headings)\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=true;\n count++;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectNew': // select tiddlers not in current document\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value=="") continue;\n theList.options[t].selected=!store.tiddlerExists(theList.options[t].value);\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectChanges': // select tiddlers that are updated from existing tiddlers\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value==""||!store.tiddlerExists(theList.options[t].value)) continue;\n for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler\n { var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }\n theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified>0); // updated tiddler\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importSelectDifferences': // select tiddlers that are new or different from existing tiddlers\n importReport(); // if an import was in progress, generate a report\n for (var t=0,count=0; t < theList.options.length; t++) {\n theList.options[t].selected=false;\n if (theList.options[t].value=="") continue;\n if (!store.tiddlerExists(theList.options[t].value)) { theList.options[t].selected=true; count++; continue; }\n for (var i=0; i<config.macros.importTiddlers.inbound.length; i++) // find matching inbound tiddler\n { var inbound=config.macros.importTiddlers.inbound[i]; if (inbound.title==theList.options[t].value) break; }\n theList.options[t].selected=(inbound.modified-store.getTiddler(theList.options[t].value).modified!=0); // changed tiddler\n count+=theList.options[t].selected?1:0;\n }\n clearMessage(); displayMessage(config.macros.importTiddlers.countMsg.format([count]));\n break;\n case 'importToggleFilter': // show/hide filter\n case 'importFilter': // apply filter\n alert("coming soon!");\n break;\n case 'importStart': // initiate the import processing\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.index=0;\n config.macros.importTiddlers.index=importTiddlers(0);\n importStopped();\n break;\n case 'importClose': // unload imported tiddlers or hide the import control panel\n // if imported tiddlers not loaded, close the import control panel\n if (!config.macros.importTiddlers.inbound) { thePanel.style.display='none'; break; }\n importReport(); // if an import was in progress, generate a report\n config.macros.importTiddlers.inbound=null; // clear the imported tiddler buffer\n refreshImportList(); // reset/resize the listbox\n break;\n case 'importSkip': // don't import the tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n theImported.status='skipped after asking'; // mark item as skipped\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index+1); // resume with NEXT item\n importStopped();\n break;\n case 'importRename': // change name of imported tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n theImported.status = 'renamed from '+theImported.title; // mark item as renamed\n theImported.set(theNewTitle.value,null,null,null,null); // change the tiddler title\n theItem.value = theNewTitle.value; // change the listbox item text\n theItem.text = theNewTitle.value; // change the listbox item text\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with THIS item\n importStopped();\n break;\n case 'importMerge': // join existing and imported tiddler content\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theItem.value);\n var theText = theExisting.text+'\sn----\sn^^merged from: [['+config.macros.importTiddlers.src+'#'+theItem.value+'|'+config.macros.importTiddlers.src+'#'+theItem.value+']]^^\sn^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\sn'+theImported.text;\n var theDate = new Date();\n var theTags = theExisting.getTags()+' '+theImported.getTags();\n theImported.set(null,theText,null,theDate,theTags);\n theImported.status = 'merged with '+theExisting.title; // mark item as merged\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");\n theImported.status += ' by '+theExisting.modifier;\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with this item\n importStopped();\n break;\n case 'importReplace': // substitute imported tiddler for existing tiddler\n var theItem = theList.options[config.macros.importTiddlers.index];\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==theItem.value) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theItem.value);\n theImported.status = 'replaces '+theExisting.title; // mark item for replace\n theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY hh:mm:ss");\n theImported.status += ' by '+theExisting.modifier;\n theAskPanel.style.display='none';\n config.macros.importTiddlers.index=importTiddlers(config.macros.importTiddlers.index); // resume with THIS item\n importStopped();\n break;\n case 'importListSmaller': // decrease current listbox size, minimum=5\n if (theList.options.length==1) break;\n theList.size-=(theList.size>5)?1:0;\n config.macros.importTiddlers.listsize=theList.size;\n break;\n case 'importListLarger': // increase current listbox size, maximum=number of items in list\n if (theList.options.length==1) break;\n theList.size+=(theList.size<theList.options.length)?1:0;\n config.macros.importTiddlers.listsize=theList.size;\n break;\n case 'importListMaximize': // toggle listbox size between current and maximum\n if (theList.options.length==1) break;\n theList.size=(theList.size==theList.options.length)?config.macros.importTiddlers.listsize:theList.options.length;\n break;\n }\n}\n//}}}\n\n// // re-entrant processing for handling import with interactive collision prompting\n//{{{\nfunction importTiddlers(startIndex)\n{\n if (!config.macros.importTiddlers.inbound) return -1;\n\n var theList = document.getElementById('importList');\n if (!theList) return;\n var t;\n // if starting new import, reset import status flags\n if (startIndex==0)\n for (var t=0;t<config.macros.importTiddlers.inbound.length;t++)\n config.macros.importTiddlers.inbound[t].status="";\n for (var i=startIndex; i<theList.options.length; i++)\n {\n // if list item is not selected or is a heading (i.e., has no value), skip it\n if ((!theList.options[i].selected) || ((t=theList.options[i].value)==""))\n continue;\n for (var j=0;j<config.macros.importTiddlers.inbound.length;j++)\n if (config.macros.importTiddlers.inbound[j].title==t) break;\n var theImported = config.macros.importTiddlers.inbound[j];\n var theExisting = store.getTiddler(theImported.title);\n // avoid redundant import for tiddlers that are listed multiple times (when 'by tags')\n if (theImported.status=="added")\n continue;\n // don't import the "ImportedTiddlers" history from the other document...\n if (theImported.title=='ImportedTiddlers')\n continue;\n // if tiddler exists and import not marked for replace or merge, stop importing\n if (theExisting && (theImported.status.substr(0,7)!="replace") && (theImported.status.substr(0,5)!="merge"))\n return i;\n // assemble tags (remote + existing + added)\n var newTags = "";\n if (config.macros.importTiddlers.importTags)\n newTags+=theImported.getTags() // import remote tags\n if (config.macros.importTiddlers.keepTags && theExisting)\n newTags+=" "+theExisting.getTags(); // keep existing tags\n if (config.macros.importTiddlers.addTags && config.macros.importTiddlers.newTags.trim().length)\n newTags+=" "+config.macros.importTiddlers.newTags; // add new tags\n theImported.set(null,null,null,null,newTags.trim());\n // set the status to 'added' (if not already set by the 'ask the user' UI)\n theImported.status=(theImported.status=="")?'added':theImported.status;\n // do the import!\n store.addTiddler(theImported);\n store.setDirty(true);\n }\n return(-1); // signals that we really finished the entire list\n}\n//}}}\n\n//{{{\nfunction importStopped()\n{\n var theList = document.getElementById('importList');\n var theNewTitle = document.getElementById('importNewTitle');\n if (!theList) return;\n if (config.macros.importTiddlers.index==-1)\n importReport(); // import finished... generate the report\n else\n {\n // DEBUG alert('import stopped at: '+config.macros.importTiddlers.index);\n // import collision... show the ask panel and set the title edit field\n document.getElementById('importAskPanel').style.display='block';\n theNewTitle.value=theList.options[config.macros.importTiddlers.index].value;\n }\n}\n//}}}\n
I added some notes about case insenstivity and a clear explanation of the process to update your upload button to work/%%/ with the new urls. Please read [[this post|New subdomain based url for your your site]] carefully if you want to use the new url.
<<forEachTiddler\n where\n 'tiddler.tags.contains("Announcements")'\n sortBy\n 'tiddler.created' descending\n write\n '"*[["+tiddler.created.formatString("YYYY-0MM-0DD")+" - " + tiddler.title + "|"+tiddler.title+"]]\sn"'\n>>
!!Announcing tiddlyspot.com!\n* ''http://tiddlyspot.com''\n\nCreate a TiddlyWiki at tiddlyspot.com, and you can:\n* ''//edit it online//'' at tiddlyspot.com, without saving locally or messing around with ftp\n* ''//save it offline for//'' editing on your local machine\n* ''//sync up anytime//'' with your tiddlyspot.com home, with a single click\n\n..and there's no login screen -- we never ask your name! \n\nWe're just getting started, so we want your feedback -- please email feedback@tiddlyspot.com with any comments.\n\nNote that if a tiddlyspot.com TiddlyWiki is not accessed for long time, we reserve the right to delete it. tiddlyspot.com is still experimental (but we think it's already very reliable) so you should keep a backup of your TiddlyWiki. Luckily tiddlyspot.com makes it easy to save locally!\n\nRegards,\n;Daniel & Simon\n
/***\nCosmetic fixes that probably should be included in a future TW...\n***/\n/*{{{*/\n.viewer .listTitle { list-style-type:none; margin-left:-2em; }\n.editorFooter .button { padding-top: 0px; padding-bottom:0px; }\n/*}}}*/\n/***\nImportant stuff. See TagglyTaggingStyles and HorizontalMainMenuStyles\n***/\n/*{{{*/\n[[TagglyTaggingStyles]]\n[[HorizontalMainMenuStyles]]\n/*}}}*/\n/***\nClint's fix for weird IE behaviours\n***/\n/*{{{*/\nbody {position:static;}\n.tagClear{margin-top:1em;clear:both;}\n/*}}}*/\n/***\nJust colours, fonts, tweaks etc. See SideBarWhiteAndGrey\n***/\n/*{{{*/\nbody {background:#eee; /* font-size:103%; */}\na{ color: #069; }\na:hover{ background: #069; color: #fff; }\n.popup { background: #178; border: 1px solid #069; }\n.headerForeground a { color: #6fc;}\n.headerShadow { left: 2px; top: 2px; }\n.title { padding:0px; margin:0px; }\n.siteSubtitle { padding:0px; margin:0px; padding-left:1.5em; }\n.subtitle { font-size:90%; color:#ccc; padding-left:0.25em; }\nh1,h2,h3,h4,h5 { color: #000; background: transparent; }\n.title {color:black; font-size:2em;}\n.shadow .title {color:#999; }\n.viewer pre { background-color:#f8f8ff; border-color:#ddf; }\n.viewer { padding-top:0px; }\n.editor textarea { font-family:monospace; }\n#sidebarOptions { border:1px #ccc solid; }\n.tiddler {\n border-bottom:1px solid #ccc; border-right:1px solid #ccc; padding-bottom:1em; margin-bottom:1em; \n background:#fff; padding-right:1.5em; }\n#messageArea { background-color:#bde; border-color:#8ab; border-width:4px; border-style:dotted; font-size:90%; }\n#messageArea .button { text-decoration:none; font-weight:bold; background:transparent; border:0px; }\n#messageArea .button:hover {background: #acd; }\n[[SideBarWhiteAndGrey]]\n\n#adsense {\n margin: 1em 15.7em 0em 1em; border:1px solid #ddd;\n background:#f8f8f8; text-align:center;margin-bottom:1em;overflow:hidden;padding:0.5em;} \n/*}}}*/\n/*{{{*/\n/* for testing clint's new formatter. eg {{red{asdfaf}}} */\n.red { color:white; background:red; display:block; padding:1em; } \n\n/* FF doesn't need this. but IE seems to want to make first one white */\n.txtMainTab .tabset { background:#eee; }\n.txtMoreTab .tabset { background:transparent; }\n\n/*}}}*/\n
[[Announcements]] [[Index]] <html><a href="http://tiddlyspot.com/" style="font-weight:bold;" class="tiddlyLink">tiddlyspot.com</a></html>
You can take your tiddlyspot site offline more easily now with a new one-click download link. New sites get the link in their AboutTiddlySpot tiddler. Existing sites can use it by adding this to a tiddler somewhere.\n\n{{{[[Download|http://tiddlyspot.com/?action=download&site=}}}//{{{yoursite}}}//{{{]]}}}\n\nReplace //yoursite// with the name your site. Try it out on this site here. [[Download|http://tiddlyspot.com/?action=download&site=announce]].\n\nThanks to [[BidiX|http://tiddlywiki.bidix.com/]] for providing the idea and the technical details to make this work.
You can now select any of these new flavours when you create your site. /%%/I thought it was time to roll this out since there is a lot of interest in using GTD (see [[here|http://tiddlyspot.com/blog/archives/general/download-squad-mentions-tiddlyspot-and-monkeygtd/]]). This will make it a lot easier to get started with Tiddlyspot and your favourite TiddlyWiki powered GTD system. The new flavours were part of the [["extras" panel|http://tiddlyspot.com/blog/archives/general/screenshot-of-the-extras-panel-that-you-wont-ever-see/]] that we scrapped.
* Introducing our beautiful new logo! Nice work Daniel!!/%%/ The site design needs some reworking now. We will get to that eventually.\n* Proxy now works with new subdomain urls, eg http://sitename.tiddlyspot.com/proxy/www.tiddlywiki.com/index.xml\n* You can now get the control panel with this shorter url, http://sitename.tiddlyspot.com/controlpanel\n* Added HaloScan to the list of proxyable sites, see the new FAQ at http://faq.tiddlyspot.com/#UsingTiddlySpot]]\n* There was a problem with control panel for new sites that was fixed last week some time. If you got an error message accessing your control panel last week then try again now.\n\nHere's the logo:\n[img[http://tiddlyspot.com/_ts/images/banner-logo.png]]\nYou can use it if you want to link to tiddlyspot. Eg,\n{{{\n<a href="http://tiddlyspot.com/"><img\nsrc="http://tiddlyspot.com/_ts/images/banner-logo.png"\nborder="0" alt="tiddlyspot"/></a>\n}}}\nWe might have some smaller ones coming soon.\n
[[BidiX|http://tiddlywiki.bidix.info]] has released a lovely new upload script written in ruby instead of php. New tiddlyspot.com sites now use this instead of store.php. If you want to update your existing site to use the new uploader then do the following:\n* Install the new version of UploadPlugin (3.3.2) from http://tiddlywiki.bidix.info/#UploadPlugin\n* Change store.php to store.cgi inside the {{{<<upload>>}}} macro in AboutTiddlySpot and SideBarOptions\nWe will continue to support the store.php uploads so it's not necessary to upgrade at this time, but in the future there maybe new functionality added that would require you to use index.cgi.\n\nNote also that new sites now have the following added to OptionsPanel:\n{{{\nUpload Password:\n<<option pasUploadPassword>>\n}}}\nThis is useful as it means you have the password field handy and can remove the AboutTiddlySpot tiddler without losing the upload password field. You can add this to your OptionsPanel tiddler also. Find it under More, Shadowed.\n
Thanks to some serious apache voodoo you can now access your site via a subdomain url. /%%/This is good because if you have multiple sites then your password cookie doesn't get mixed up. We are working on making this the default setup for all new sites, but have to test a couple of things first.\n\nThe new url is like this:\n{{{http://siteid.tiddlyspot.com/}}}.\n\n!Updates required for uploading to work via the new url\nHere's the catch though... For your uploads from your subdomain based url to work you have to do the following:\n* Go to you site via the new url\n* Edit your SideBarOptions tiddler. (Look for it under Shadowed under the More tab)\n* Replace this:<<br>>@@padding-left:2em;font-size:90%;{{{<<upload http://tiddlyspot.com/siteid/store.xxx index.html . . siteid>>}}}@@\n* with this:<<br>>@@padding-left:2em;font-size:90%;{{{<<upload http://siteid.tiddlyspot.com/store.xxx index.html . . siteid>>}}}@@<<br>>@@padding-left:1em;(where {{{siteid}}} is your siteid and {{{xxx}}} is either 'php' or 'cgi')@@\n* Repeat this for the AboutTiddlySpot tiddler also\n* Make sure you have entered your password correctly then click upload\n\n~~Note also that if you're an old-school user with store.php instead of store.cgi you can change to use store.cgi but only if you update your UploadPlugin to the latest version. (The older version of UploadPlugin is incompatible with store.cgi). If you don't know what that means just ignore it... :)~~\n\n!Read this if your site name has an upper case letter\nBecause DNS is case insensitive the new urls are case insensitive. This is a problem for a handful of users who have a site with a capital letter that clashes with another site that is has the site name in all lower case. For example:\n* If you site is called {{{BarneyRubble}}} and your current site url is {{{http://tiddlyspot.com/BarneyRubble/}}}\n* Your subdomain url is going to be the case insensitive {{{http://BarneyRubble.tiddlyspot.com/}}} which is the same as {{{http://barneyrubble.tiddlyspot.com/}}} because of the case insensitivity\n* The new url will work perfectly ''unless'' somebody else (or yourself) has created a site called "barneyrubble" (in lowercase)\n* If this is the case then you can't get to your site via the new url because the new url {{{http://barneyrubble.tiddlyspot.com/}}} goes to that other person's site.\n* There are 19 sites currently in that situation. If your site is one of them and you want to use the new subdomain url then [[email us|feedback@tiddlyspot.com]] and we will see if we can sort you out on a case by case basis.\n* Note that you can keep using your current url without any change.\n\n
/***\n|Name|NewHereCommand|\n|Source|http://simonbaird.com/mptw/#NewHereCommand|\n|Version|1.0|\n\nCode originally by ArphenLin. Small tweak by SimonBaird\nhttp://aiddlywiki.sourceforge.net/NewHere_demo.html#NewHereCommand\nTo use this you must edit your ViewTemplate and add newHere to the toolbar div, eg\n{{{<div class='toolbar' macro='toolbar ... newHere'></div>}}}\n***/\n\n//{{{\n\nconfig.commands.newHere = {\n text: 'new here',\n tooltip: 'Create a new tiddler tagged as this tiddler',\n handler: function(e,src,title) {\n if (!readOnly) {\n clearMessage();\n var t=document.getElementById('tiddler'+title);\n story.displayTiddler(t,config.macros.newTiddler.title,DEFAULT_EDIT_TEMPLATE);\n story.setTiddlerTag(config.macros.newTiddler.title, title, 0);\n story.focusTiddler(config.macros.newTiddler.title,"title");\n return false;\n }\n }\n};\n\n//}}}
We kind of miss the random site names but of course not everyone wants their site to called as "zingpod", "spodfop" or "gawfrink"! So now you can choose your own site name. This required some extra code to check if a site id is still available. If you've spent hours updating your "kishfrut" site and want to have it renamed to something a little nicer then email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with your id, password and desired id and I will rename it for you. Limited time offer!
This is the official announcements page for ''[[tiddlyspot.com|http://tiddlyspot.com/]]''.\n{{blog{\n<<forEachTiddler\n where\n 'tiddler.tags.contains("Announcements")'\n sortBy\n 'tiddler.created'\n descending\n write\n 'index>=6?"\sn!![["+tiddler.title+"]]@@color:#999;font-size:70%;" +\n tiddler.created.formatString(" - DD/MM/YY")+" - posted by "+tiddler.modifier+"@@\sn" +\n "{{excerpt{\sn" + \n (tiddler.text.match("/%%/") ?\n tiddler.text.substr(0,tiddler.text.indexOf("/%%/")) : \n tiddler.text.substr(0,100)) + \n " ...\sn[[read more...|"+tiddler.title+"]]\sn}}}":"";'\n>>\n}}}\n\n
Upload Password:\n<<option pasUploadPassword>>\n\nThese InterfaceOptions for customising TiddlyWiki are saved in your browser\n\nYour username for signing your edits. Write it as a WikiWord (eg JoeBloggs)\n\n<<option txtUserName>>\n<<option chkSaveBackups>> SaveBackups\n<<option chkAutoSave>> AutoSave\n<<option chkRegExpSearch>> RegExpSearch\n<<option chkCaseSensitiveSearch>> CaseSensitiveSearch\n<<option chkAnimate>> EnableAnimations\n\nSee AdvancedOptions
<!--{{{-->\n<div class='header' macro='gradient vert #04b #04b'>\n<div class='headerShadow'>\n<span class='siteTitle' style="font-weight:bold"><img align="middle" src="http://tiddlyspot.com/_ts/images/banner-logo.png"/></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div class='headerForeground'>\n<span class='siteTitle' style="font-weight:bold"><img align="middle" src="http://tiddlyspot.com/_ts/images/banner-logo.png"/></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div id='topMenu' refresh='content' tiddler='MainMenu'></div>\n</div>\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<!-- <div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div> -->\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->\n
Recently some tiddlyspot users have have reported that their site has been lost due to an unknown problem. The symptom is that after uploading the site ends up being just an empty file. We are working on figuring our why this might be happening and how we might do regular backups of tiddlyspot sites. But in the meantime, in case this ever happens to you please backup your site regularly by downloading it. And remember to always do the following:\n* Wait until you get the confirmation message "Main ~TiddlyWiki file uploaded to..." before\n** Closing your browser window or tab\n** Moving to another web page\n** Switching off your internet connection\n(Depending on the speed of your connection and the site of your ~TiddlyWiki it can take a long time for the upload to complete).\n
For a few hours on Friday afternoon (GMT+10) the creating of sites was broken. There were about 10 or 15 people who got an "Internal Server Error" instead of a new tiddlyspot site. If you were one of those people please accept our humble apologies and try again now. The site name you wanted is available again. Thanks very much to Jasmeet S who let us know about this problem and thanks Daniel for finding and fixing my screw-up so quickly. Apologies again for this lapse in quality control.
There is a known problem with IE and Norton Internet Security. If you use both of these then it might cause problems with your tiddlywiki file. This probably affects any TiddlyWiki, not just Tiddlyspot sites. To fix it you have to disable the Norton "block popups for this site" feature. More information is available at [[the FAQ|http://tiddlyspot.com/faq/#%5B%5BI%20always%20get%20a%20blank%20screen%20instead%20of%20my%20TiddlyWiki%20(even%20when%20I%20look%20at%20my%20offline%20copy)%5D%5D]]. Thanks to Dave P. for reporting this problem.
Tiddlyspot.com now has a proxy service thanks to BidiX's new proxy.cgi script available at http://tiddlywiki.bidix.info/#ProxyService. This allows you to use plugins that access other web sites (for example BidiX's RssExtensions (see http://tiddlywiki.bidix.info/#RSSFeeds to see what this can do) and ImportTiddlersPlugin directly from your tiddlyspot site. Visit http://tiddlywiki.bidix.info/#ProxyService for more information. At the moment the proxy service can be used with the following sites only.*\n* www.tiddlywiki.com\n* tiddlywiki.bidix.info\n* www.tiddlytools.com\n* tiddlywiki.abego-software.de\n* www.osmosoft.com\n* simonbaird.com\n* danielbaird.com\nIf you need some other sites then let us know at <<tiddler Feedback>>. \n\n!Update 22-Aug-06\n* Added www.haloscan.com, eg\nhttp://tiddlyspot.com/proxy/http://www.haloscan.com/members/rss.php?user=myusername\n\nThe proxy service is accessible at:\n{{{http://tiddlyspot.com/proxy/}}}//{{{the-url-you-want}}}//\n\nFor example:\nhttp://tiddlyspot.com/proxy/www.tiddlywiki.com/#HelloThere\nhttp://tiddlyspot.com/proxy/www.osmosoft.com/index.xml\n\n\n~~* The reason it's not open to any site is we aren't sure if we want to allow general rss reading via the tiddlyspot proxy. Our concern is that our hosting provider would bill us for all the extra bandwidth required when you read your favourite blogs and news sites in your Tiddlyspot TiddlyWiki. It doesn't matter so much now but if we had say a million sites then it might become significant.~~\n\n
/***\n| Name:|QuickOpenTagPlugin|\n| Purpose:|Makes tag links into a Taggly style open tag plus a normal style drop down menu|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#QuickOpenTagPlugin|\n| Requires:|TW 2.x|\n| Version|1.1 (7-Feb-06)|\n\n!History\n* Version 1.1 (07/02/2006)\n** Fix Firefox crashes\n** Updated by ~BidiX[at]~BidiX.info\n* Version 1.0 (?/01/2006)\n** First release\n\n***/\n//{{{\n\n//⊻ ⊽ ⋁ ▼ \n\nwindow.createTagButton_orig_mptw = createTagButton;\nwindow.createTagButton = function(place,tag,excludeTiddler) {\n var sp = createTiddlyElement(place,"span",null,"quickopentag");\n createTiddlyLink(sp,tag,true,"button");\n var theTag = createTiddlyButton(sp,config.macros.miniTag.dropdownchar,config.views.wikified.tag.tooltip.format([tag]),onClickTag);\n theTag.setAttribute("tag",tag);\n if(excludeTiddler)\n theTag.setAttribute("tiddler",excludeTiddler);\n return(theTag);\n};\n\nconfig.macros.miniTag = {handler:function(place,macroName,params,wikifier,paramString,tiddler) {\n var tagged = store.getTaggedTiddlers(tiddler.title);\n if (tagged.length > 0) {\n var theTag = createTiddlyButton(place,config.macros.miniTag.dropdownchar,config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);\n theTag.setAttribute("tag",tiddler.title);\n theTag.className = "miniTag";\n }\n}};\n\nconfig.macros.miniTag.dropdownchar = (document.all?"▼":"▾"); // the fat one is the only one that works in IE\n\nconfig.macros.allTags.handler = function(place,macroName,params)\n{\n var tags = store.getTags();\n var theDateList = createTiddlyElement(place,"ul",null,null,null);\n if(tags.length === 0)\n createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);\n for (var t=0; t<tags.length; t++)\n {\n var theListItem =createTiddlyElement(theDateList,"li",null,null,null);\n var theLink = createTiddlyLink(theListItem,tags[t][0],true);\n var theCount = " (" + tags[t][1] + ")";\n theLink.appendChild(document.createTextNode(theCount));\n\n var theDropDownBtn = createTiddlyButton(theListItem," "+config.macros.miniTag.dropdownchar,this.tooltip.format([tags[t][0]]),onClickTag);\n theDropDownBtn.setAttribute("tag",tags[t][0]);\n }\n};\n\n\nsetStylesheet(\n ".quickopentag { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }\sn"+\n ".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }\sn"+\n ".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}\sn"+\n "a.miniTag {font-size:150%;}\sn"+\n "",\n"QuickOpenTagStyles");\n\n//}}}\n\n/***\n<html>&#x22bb; &#x22bd; &#x22c1; &#x25bc; &#x25be;</html>\n***/\n
New sites created on tiddlyspot.com can now have an RSS feed.\n\nWe will add this feature to existing sites soon (we've already turned it on for this announcements site).\n\nIf you want to have RSS for your tiddlyspot.com site, turn on "~GenerateAnRssFeed" in the ~AdvancedOptions tiddler (click "options>>", "~AdvancedOptions", and tick the box). Next time you upload your ~TiddlyWiki to tiddlyspot, your RSS file will be uploaded too.
You can now upload an RSS file for your tiddlywiki. From the [[last announcement|RSS works (for new sites)]]:\n<<<\nIf you want to have RSS for your tiddlyspot.com site, turn on "GenerateAnRssFeed" in the AdvancedOptions tiddler (click "options>>", "AdvancedOptions", and tick the box). Next time you upload your TiddlyWiki to tiddlyspot, your RSS file will be uploaded too.\n<<<\nThe rss file will be at http://tiddlyspot.com/yoursite/index.xml. Note that if you created your site prior to 23 June you may need to edit your SiteUrl tiddler so that links in your RSS file will work properly. Find it in the Shadowed tab under the More tab. Set the contents of the SiteUrl tiddler to http://tiddlyspot.com/yoursite/ (instead of http://www.tiddlywiki.com/).
/***\n\n!Don't use this I have hacked it considerably. Fetch it from the original source.\n\n|''Name:''|RSSReaderPlugin|\n|''Description:''|This plugin provides a RSSReader for TiddlyWiki|\n|''Version:''|0.3.0|\n|''Date:''|Aug 24, 2006|\n|''Source:''|http://tiddlywiki.bidix.info/#RSSReaderPlugin|\n|''Documentation:''|http://tiddlywiki.bidix.info/#RSSReaderPluginDoc|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''Credit:''|BramChen for RssNewsMacro|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|\n|''~CoreVersion:''|2.0.0|\n|''Browser:''|Firefox 1.5; InternetExplorer 6.0; Safari|\n|''Include:''|none|\n|''Require:''|none|\n***/\n//{{{\nversion.extensions.RSSReaderPlugin = {\n major: 0, minor: 3, revision: 0,\n date: new Date("Aug 24, 2006"),\n author: "BidiX",\n credit: "BramChen for RssNewsMacro",\n source: "http://TiddlyWiki.bidix.info/#RSSReaderPlugin",\n documentation : "http://TiddlyWiki.bidix.info/#RSSReaderPluginDoc",\n author: 'BidiX (BidiX (at) bidix (dot) info',\n license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',\n coreVersion: '2.0.0',\n browser: 'Firefox 1.5; InternetExplorer 6.0; Safari' \n};\n\nconfig.macros.rssReader = {\n dateFormat: "DDD, DD MMM YYYY",\n itemStyle: "display: block;border: 1px solid black;padding: 5px; margin: 5px;", //useed '@@'+itemStyle+itemText+'@@'\n msg:{\n permissionDenied: "Permission to read preferences was denied.",\n noRSSFeed: "No RSS Feed at this address %0",\n urlNotAccessible: " Access to %0 is not allowed"\n },\n cache: [], // url => request\n desc: "noDesc",\n // feedURL: "",\n place:"",\n handler: function(place,macroName,params,wikifier,paramString,tiddler){\n var desc = params[0];\n var feedURL = params[1];\n // var toFilter = (params[2] ? params[2] : false);\n var toFilter = false;\n var filterString;\n if (params[2] != undefined) {\n toFilter = true;\n if (params[2].match(/\sw+/))\n filterString = params[2];\n else\n filterString = tiddler.title;\n\n // haloscan trims to 40 or so chars. simon\n // and replaces , with space. (wonder if other chars also?)\n filterString = filterString.replace(/[",\s/]/g,' ').substr(0,45); \n }\n\n\n var place = createTiddlyElement(place, "div", "RSSReader");\n wikify("^^<<rssFeedUpdate "+feedURL+" [[" + tiddler.title + "]]>>^^\sn",place);\n if (this.cache[feedURL]) {\n this.processResponse(this.cache[feedURL], feedURL, place, desc, toFilter, filterString);\n }\n else {\n this.asyncGet(feedURL, place, desc, toFilter, filterString);\n }\n },\n\n asyncGet: function (feedURL, place, desc, toFilter, filterString){\n var xmlhttp;\n try {xmlhttp=new XMLHttpRequest();}\n catch (e) {\n try {xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");}\n catch (e) {\n try {xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}\n catch (e) { displayMessage(e.description?e.description:e.toString());}\n }\n }\n if (!xmlhttp){\n return;\n }\n if (window.netscape){\n try {\n if (document.location.protocol.indexOf("http") == -1) {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n }\n catch (e) { displayMessage(e.description?e.description:e.toString()); }\n }\n xmlhttp.onreadystatechange=function (){\n if (xmlhttp.readyState==4) {\n if (xmlhttp.status==200 || xmlhttp.status===0) {\n config.macros.rssReader.processResponse(xmlhttp, feedURL, place, desc, toFilter, filterString);\n }\n else {\n displayMessage("Problem retrieving XML data:" + xmlhttp.statusText);\n }\n }\n };\n try {\n xmlhttp.open("GET",feedURL,true);\n if (config.browser.isIE) {\n xmlhttp.send();\n }\n else {\n xmlhttp.send(null);\n }\n }\n catch (e) {\n wikify(e.toString()+this.urlNotAccessible.format([feedURL]), place);\n }\n },\n processResponse: function(xmlhttp, feedURL, place, desc, toFilter, filterString){ \n//alert(xmlhttp.responseText);\n if (window.netscape){\n try {\n if (document.location.protocol.indexOf("http") == -1) {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n }\n catch (e) { displayMessage(e.description?e.description:e.toString()); }\n }\n if (xmlhttp.responseXML){\n this.cache[feedURL] = xmlhttp;\n this.genRssNews(xmlhttp.responseXML, place, feedURL, desc, toFilter, filterString);\n }\n else {\n var dom = (new DOMParser()).parseFromString(xmlhttp.responseText, "text/xml"); \n if (dom) {\n this.cache[feedURL] = xmlhttp;\n this.genRssNews(dom, place, feedURL, desc, toFilter, filterString);\n }\n else {\n wikify("<html>"+xmlhttp.responseText+"</html>", place);\n displayMessage(this.msg.noRSSFeed.format([feedURL]));\n }\n }\n },\n genRssNews: function(xml, place, feedURL, desc, toFilter, filterString){\n // Channel\n var chanelNode = xml.getElementsByTagName('channel').item(0);\n var chanelTitleElement = (chanelNode ? chanelNode.getElementsByTagName('title').item(0) : null);\n var chanelTitle = "";\n if ((chanelTitleElement) && (chanelTitleElement.firstChild)) chanelTitle = chanelTitleElement.firstChild.nodeValue;\n var chanelLinkElement = (chanelNode ? chanelNode.getElementsByTagName('link').item(0) : null);\n var chanelLink = "";\n if (chanelLinkElement) chanelLink = chanelLinkElement.firstChild.nodeValue;\n var titleTxt = "!![["+chanelTitle+"|"+chanelLink+"]]\sn";\n //var title = createTiddlyElement(place,"div",null,"ChanelTitle",null);\n //wikify(titleTxt,title);\n // ItemList\n var itemList = xml.getElementsByTagName('item');\n var article = createTiddlyElement(place,"ul",null,null,null);\n var lastDate;\n var re;\n if (toFilter) \n re = new RegExp(filterString.escapeRegExp());\n for (var i=0; i<itemList.length; i++){\n var titleElm = itemList[i].getElementsByTagName('title').item(0);\n var titleText = (titleElm ? titleElm.firstChild.nodeValue : '');\n//alert(filterString.escapeRegExp().replace(/ /g,'+')+" "+titleText.replace(/ /g,'+'));\n\n if (toFilter && ! titleText.match(re)) {\n continue;\n }\n var descText = '';\n var isWikitext = false;\n var descElem = itemList[i].getElementsByTagName('wikitext').item(0);\n if (descElem){\n try{\n isWikitext = true;\n descText = "\sn"+descElem.firstChild.nodeValue;}\n catch(e){}\n }\n else {\n descElem = itemList[i].getElementsByTagName('encoded').item(0);\n if (descElem){\n try{descText = descElem.firstChild.nodeValue;}\n catch(e){}\n descText = "<html>"+descText+"</html>";\n }\n else {\n descElem = itemList[i].getElementsByTagName('description').item(0);\n if (descElem){\n try{descText = descElem.firstChild.nodeValue;}\n catch(e){}\n descText = descText.replace(/<br \s/>/g,'\sn');\n if (desc == "asHtml")\n descText = "<html>"+descText+"</html>";\n }\n }\n }\n var linkElm = itemList[i].getElementsByTagName("link").item(0);\n var linkURL = linkElm.firstChild.nodeValue;\n var pubElm = itemList[i].getElementsByTagName('pubDate').item(0);\n var pubDate;\n if (!pubElm) {\n pubElm = itemList[i].getElementsByTagName('date').item(0); // for del.icio.us\n if (pubElm) {\n pubDate = pubElm.firstChild.nodeValue;\n pubDate = this.formatDateString(this.dateFormat, pubDate);\n }\n else {\n pubDate = '0';\n }\n }\n else {\n pubDate = (pubElm ? pubElm.firstChild.nodeValue : 0);\n pubDate = this.formatString(this.dateFormat, pubDate);\n }\n titleText = titleText.replace(/\s[|\s]/g,'');\n\n // I just want the Post by ... for haloscan purposes. simon.\n titleText = titleText.substr(titleText.indexOf("Post by ")+"Post by ".length) + ":"; \n\n //var rssText = '** '+'[[' + titleText + '|' + linkURL + ']]' + '\sn' ;\n var rssText = "''"+'[[' + titleText + '|' + linkURL + ']]' + "''\sn" ;\n if ((desc != "noDesc") && descText){\n if (version.extensions.nestedSliders){\n rssText = rssText.replace(/\sn/g,' ');\n descText = '+++[...]\sn'\n +(isWikitext ? '\sn<<rssFeedImportTiddler '+ feedURL + ' [['+titleText+']]>>':'')\n +'@@'+this.itemStyle+descText+'\sn@@\sn'\n +'===';\n }\n rssText = rssText + descText + '\sn\sn';\n }\n var story;\n if ((lastDate != pubDate) && ( pubDate != '0')) {\n story = createTiddlyElement(article,"li",null,"RSSItem",pubDate);\n lastDate = pubDate;\n }\n else {\n lastDate = pubDate;\n }\n story = createTiddlyElement(article,"div",null,"RSSItem",null);\n wikify(rssText,story);\n }\n },\n formatString: function(template, theDate){\n var dateString = new Date(theDate);\n template = template.replace(/hh|mm|ss/g,'');\n return dateString.formatString(template);\n },\n formatDateString: function(template, theDate){\n var dateString = new Date(theDate.substr(0,4), theDate.substr(5,2) - 1, theDate.substr(8,2)\n /*, theDate.substr(11,2), theDate.substr(14,2), theDate.substr(17,2)*/\n );\n return dateString.formatString(template);\n }\n \n};\n//}}}\n\n//{{{\nconfig.macros.rssFeedUpdate = {\n label: "Update",\n prompt: "Clear the cache and redisplay this RssFeed",\n handler: function(place,macroName,params) {\n var feedURL = params[0];\n var tiddlerTitle = params[1];\n createTiddlyButton(place, this.label, this.prompt, \n function () {\n if (config.macros.rssReader.cache[feedURL]) {\n config.macros.rssReader.cache[feedURL] = null; \n //story.refreshTiddler(tiddlerTitle,null, true);\n }\n story.refreshTiddler(tiddlerTitle,null, true);\n return false;});\n }\n};\n//}}}\n\n//{{{\nconfig.macros.rssFeedImportTiddler = {\n label: "Import",\n prompt: "Import this tiddler in this TiddlyWiki",\n askReplaceMsg: "Tiddler already exists, replace it ?",\n handler: function(place,macroName,params) {\n var feedUrl = params[0];\n var tiddlerTitle = params[1];\n createTiddlyButton(place, this.label, this.prompt, \n function () {\n if (feedUrl && config.macros.rssReader.cache[feedUrl]) {\n var tiddler = config.macros.rssFeedImportTiddler.parseRssNews(config.macros.rssReader.cache[feedUrl].responseXML, tiddlerTitle);\n if (tiddler && (! store.getTiddler(tiddlerTitle) || confirm(config.macros.rssFeedImportTiddler.askReplaceMsg))) {\n store.addTiddler(tiddler);\n store.notify(tiddler.title, true);\n store.setDirty(true);\n }\n }\n return false;});\n },\n \n // parse a RssFeed for retrieving a Tiddler with title\n parseRssNews: function(xml, title) {\n // ItemList\n if (document.location.protocol.indexOf("http") == -1) {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n\n var itemList = xml.getElementsByTagName('item');\n for (var i=0; i<itemList.length; i++){\n\n var titleElm = itemList[i].getElementsByTagName('title').item(0);\n var titleText = titleElm.firstChild.nodeValue;\n if (titleText == title) {\n // <tiddlywiki:title>\n // titleText\n titleText = titleText.htmlDecode();\n // <tiddlywiki:wikitext>\n var elem = itemList[i].getElementsByTagName('wikitext').item(0);\n var text = elem ? elem.firstChild.nodeValue.htmlDecode() : "";\n // <tiddlywiki:modifier>\n elem = itemList[i].getElementsByTagName('modifier').item(0);\n var modifier = elem ? elem.firstChild.nodeValue : "";\n // <tiddlywiki:modified>\n elem = itemList[i].getElementsByTagName('modified').item(0);\n var modified = elem ? Date.convertFromYYYYMMDDHHMM(elem.firstChild.nodeValue) : "";\n // <tiddlywiki:created>\n elem = itemList[i].getElementsByTagName('created').item(0);\n var created = elem ? Date.convertFromYYYYMMDDHHMM(elem.firstChild.nodeValue) : "";\n // <tiddlywiki:links>\n // Links ?\n // <tiddlywiki:tags>\n elem = itemList[i].getElementsByTagName('tags').item(0);\n var tags = elem ? elem.firstChild.nodeValue.htmlDecode() : "";\n var tiddler = new Tiddler();\n tiddler.assign(titleText,text,modifier,modified,tags,created);\n return tiddler;\n }\n }\n // not found \n alert("Tiddler \s[[" + title +"]] notFound.");\n return null;\n }\n\n};\n\n//}}}\n
/***\n| Name:|RenameTagsPlugin|\n| Purpose:|Allows you to easily rename tags|\n| Creator:|SimonBaird|\n| Source:|http://simonbaird.com/mptw/#RenameTagsPlugin|\n| Version:|1.0.1 (5-Mar-06)|\n\n!Description\nIf you rename a tiddler/tag that is tagging other tiddlers this plugin will ask you if you want to rename the tag in each tiddler where it is used. This is essential if you use tags and ever want to rename them. To use it, open the tag you want to rename as a tiddler (it's the last option in the tag popup menu), edit it, rename it and click done. You will asked if you want to rename the tag. Click OK to rename the tag in the tiddlers that use it. Click Cancel to not rename the tag.\n\n!Example\nTry renaming [[Plugins]] or [[CSS]] on this site.\n\n!History\n* 1.0.1 (5-Mar-06) - Added feature to allow renaming of tags without side-effect of creating a tiddler\n* 1.0.0 (5-Mar-06) - First working version\n\n!Code\n***/\n//{{{\n\nversion.extensions.RenameTagsPlugin = {\n major: 1, minor: 0, revision: 0,\n date: new Date(2006,3,5),\n source: "http://simonbaird.com/mptw/#RenameTagsPlugin"\n};\n\nconfig.macros.RenameTagsPlugin = {};\nconfig.macros.RenameTagsPlugin.prompt = "Rename the tag '%0' to '%1' in %2 tidder%3?";\n\n// these are very useful, perhaps they should be in the core\nif (!store.addTag) {\n store.addTag = function(title,tag) {\n var t=this.getTiddler(title); if (!t || !t.tags) return;\n t.tags.push(tag);\n };\n};\n\nif (!store.removeTag) {\n store.removeTag = function(title,tag) {\n var t=this.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)!=null) t.tags.splice(t.tags.find(tag),1);\n };\n};\n\nstore.saveTiddler_orig_tagrename = store.saveTiddler;\nstore.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags) {\n if (title != newTitle && this.getTaggedTiddlers(title).length > 0) {\n // then we are renaming a tag\n var tagged = this.getTaggedTiddlers(title);\n if (confirm(config.macros.RenameTagsPlugin.prompt.format([title,newTitle,tagged.length,tagged.length>1?"s":""]))) {\n for (var i=0;i<tagged.length;i++) {\n store.removeTag(tagged[i].title,title);\n store.addTag(tagged[i].title,newTitle);\n // if tiddler is visible refresh it to show updated tag\n story.refreshTiddler(tagged[i].title,false,true);\n }\n }\n if (!this.tiddlerExists(title) && newBody == "") {\n // dont create unwanted tiddler\n return null;\n }\n }\n return this.saveTiddler_orig_tagrename(title,newTitle,newBody,modifier,modified,tags);\n}\n\n//}}}\n\n
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal 'DD MMM YYYY'>><<saveChanges>><<upload http://announce.tiddlyspot.com/store.php index.html . . announce>><<slider chkSliderOptionsPanel OptionsPanel 'options »' 'Change TiddlyWiki advanced options'>><<slider chkSliderTimeline SideBarTabs 'tabs »' 'Show timeline'>>
/***\nThis CSS by DaveBirss.\n***/\n/*{{{*/\n\n.tabSelected {\n background: #fff;\n}\n\n.tabUnselected {\n background: #eee;\n}\n\n#sidebar {\n color: #000;\n}\n\n#sidebarOptions {\n background: #fff;\n}\n\n#sidebarOptions .button {\n color: #999;\n}\n\n#sidebarOptions .button:hover {\n color: #000;\n background: #fff;\n border-color:white;\n}\n\n#sidebarOptions .button:active {\n color: #000;\n background: #fff;\n}\n\n#sidebarOptions .sliderPanel {\n background: transparent;\n}\n\n#sidebarOptions .sliderPanel A {\n color: #999;\n}\n\n#sidebarOptions .sliderPanel A:hover {\n color: #000;\n background: #fff;\n}\n\n#sidebarOptions .sliderPanel A:active {\n color: #000;\n background: #fff;\n}\n\n.sidebarSubHeading {\n color: #000;\n}\n\n#sidebarTabs {`\n background: #fff\n}\n\n#sidebarTabs .tabSelected {\n color: #000;\n background: #fff;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: none;\n}\n\n#sidebarTabs .tabUnselected {\n color: #999;\n background: #eee;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: none;\n}\n\n#sidebarTabs .tabContents {\n background: #fff;\n}\n\n\n#sidebarTabs .txtMoreTab .tabSelected {\n background: #fff;\n}\n\n#sidebarTabs .txtMoreTab .tabUnselected {\n background: #eee;\n}\n\n#sidebarTabs .txtMoreTab .tabContents {\n background: #fff;\n}\n\n#sidebarTabs .tabContents .tiddlyLink {\n color: #999;\n}\n\n#sidebarTabs .tabContents .tiddlyLink:hover {\n background: #fff;\n color: #000;\n}\n\n#sidebarTabs .tabContents {\n color: #000;\n}\n\n#sidebarTabs .button {\n color: #666;\n}\n\n#sidebarTabs .tabContents .button:hover {\n color: #000;\n background: #fff;\n}\n\n/*}}}*/
We still don't know what's causing this problem and have not been able to repeat it but we have taken these steps:\n* Added some sanity checks in the upload script so it won't not blindly save an empty file.\n* Switched on backups so that we can easily recover your file if something goes wrong.\nOnce again it's still a good idea to keep your own local backup by downloading your site regularly. And remember if you have any problems please let us know at [[support@tiddlyspot.com|mailto:support@tiddlyspot.com]].
Check it out in your control panel, or go directly to:/%%/\n{{{http://yoursite.tiddlyspot.com/controlpanel?page=stats}}}\nMore details on the blog at [[this url|http://tiddlyspot.com/blog/archives/general/stats-page-is-back/]].
We just discovered that the cute little stats page only works for the old style urls :(/%%/. (These ones {{{http://tiddlyspot.com/yoursite/}}}). It doesn't work at all for the new urls (like this ({{{http://yoursite.tiddlyspot.com/}}}). So I guess the cute little stats page is going to have to be retired until we can figure out another way to do stats.
~TiddlyWiki 2.1 has arrived. If you want to upgrade your current site to ~TiddlyWiki 2.1.x, we've written up some instructions here:\nhttp://tiddlywikiguides.org/index.php?title=Upgrading_your_TiddlyWiki_to_2.1.x\n\nNote that if you're using ~MonkeyGTD or D3, we recommend that you don't upgrade yet.
//{{{\n[[MPTWStyleSheet]]\n\n* {\n font-family:'Trebuchet MS' sans-serif;\n}\n\ntt, pre, code {\n font-family: 'Courier New' monospace; font-size:80%;\n}\n.headerForeground {\n color:#fff;\n font-size:110%;\n padding:0;\n margin: 0;\n padding-top:2.3em;\n padding-left:2em;\n font-weight:bold;\n}\n\n.headerShadow {\n color:#04b;\n font-size:110%;\n padding-top:2em;\n padding-left:2em;\n}\n\n#topMenu {\n background: #db4;\n font-size:110%;\n}\n\n.viewer { font-size:130%; }\ntd.tagglyTagging { font-size:130%;}\n\na{ color: #04b; }\na:hover{ background: #04b; color: #fff; }\n\n#topMenu .tiddlyLink, #topMenu .button { color:#841; }\n#topMenu .button:hover, #topMenu .tiddlyLink:hover { background:#ffc; }\n\n.popup { background: #841; border: 1px solid #db4; }\n\n.blog h2 {\n margin:0;\n padding:0;\n \n}\n.blog .excerpt {\n margin:0;\n padding: 0;\n margin-left:1em;\n padding-left:1em;\n font-size:90%;\n border-left:1px solid #ddd;\n}\n\n#contentWrapper pre {\n font-family: 'Courier New', Courier, monospace;\n font-size: 70%;\n}\n\n/* for haloscan testing */\n.comments {\n padding-top:1em;\n}\n.RSSItem {\n border-bottom:1px solid #ddd;\n padding-top:2em;\n}\n\n//}}}\n
/***\n''Name:'' TWUpdate\n''Author:'' Tom Otvos\n''Version:'' 0.2\n<<twupdate>>\n***/\n//{{{\n\nversion.extensions.twupdate = {major: 0, minor: 2, revision: 0, date: new Date(2006,3,13,0,0,0,0), source: ""};\n\nconfig.macros.twupdate = { \n label: "update",\n sourceUrl: "http://www.tiddlywiki.com/empty.html", \n lingo: {\n prompt: "Update this TiddlyWiki from TiddlyWiki.com", \n warning: "Are you sure you want to update this document with the latest version of TiddlyWiki?\sn\snIf you want to continue, your document will first be saved with a backup.",\n success: "Update was successful. Click on 'OK' to reload the document",\n errNoHttp: "Unable to allocate an HTTP request object for the update",\n progressLoading: "Getting update from TiddlyWiki.com...",\n progressLoadSuccess: "File successfully loaded",\n progressLoadFailure: "File was not loaded successfully (%0)",\n progressMerging: "Merging with existing document..."\n }\n}\n\nconfig.macros.twupdate.handler = function(place)\n{\n if(!readOnly)\n createTiddlyButton(place, this.label, this.prompt, this.onClick, null, null, null);\n}\n\nconfig.macros.twupdate.onClick = function(e)\n{\n if (!confirm(config.macros.twupdate.lingo.warning)) return;\n\n try {\n // force a save with backup\n var saveBackups = config.options.chkSaveBackups;\n config.options.chkSaveBackups = true;\n saveChanges();\n config.options.chkSaveBackups = saveBackups;\n \n var ajax = new AjaxHelper();\n displayMessage(config.macros.twupdate.lingo.progressLoading);\n ajax.getText(config.macros.twupdate.sourceUrl, config.macros.twupdate.performUpdate); \n }\n catch (e) {\n alert(e);\n }\n\n return false;\n}\n\nconfig.macros.twupdate.performUpdate = function(emptyHtml, status, statusText)\n{\n // note that this is begin called from a callback from an event handler, so\n // "this" is most definitely not defined!\n \n if (status == 200)\n displayMessage(config.macros.twupdate.lingo.progressLoadSuccess);\n else {\n displayMessage(config.macros.twupdate.lingo.progressLoadFailure.format([statusText]));\n return;\n }\n displayMessage(config.macros.twupdate.lingo.progressMerging);\n \n // the bulk of this is cribbed from saveChanges()...\n var originalPath = document.location.toString();\n // Check we were loaded from a file URL\n if (originalPath.substr(0,5) != "file:") {\n alert(config.messages.notFileUrlError);\n if (store.tiddlerExists(config.messages.saveInstructions))\n displayTiddler(null,config.messages.saveInstructions);\n return;\n }\n var localPath = getLocalPath(originalPath);\n\n // Locate the storeArea div's\n var posOpeningDiv = emptyHtml.indexOf(startSaveArea);\n var posClosingDiv = emptyHtml.lastIndexOf(endSaveArea);\n if ((posOpeningDiv == -1) || (posClosingDiv == -1)) {\n alert(config.messages.invalidFileError.format(['empty.html']));\n return;\n }\n\n // Save new file\n var revised = emptyHtml.substr(0,posOpeningDiv + startSaveArea.length) + \n convertUnicodeToUTF8(allTiddlersAsHtml()) + "\sn\st\st" +\n emptyHtml.substr(posClosingDiv);\n var newSiteTitle = convertUnicodeToUTF8((wikifyPlain("SiteTitle") + " - " + wikifyPlain("SiteSubtitle")).htmlEncode());\n revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");\n revised = revised.replaceChunk("<!--PRE-HEAD-START--"+">","<!--PRE-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPreHead","") + "\sn");\n revised = revised.replaceChunk("<!--POST-HEAD-START--"+">","<!--POST-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPostHead","") + "\sn");\n revised = revised.replaceChunk("<!--PRE-BODY-START--"+">","<!--PRE-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPreBody","") + "\sn");\n revised = revised.replaceChunk("<!--POST-BODY-START--"+">","<!--POST-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPostBody","") + "\sn");\n var save = saveFile(localPath, revised);\n if (save) {\n displayMessage(config.messages.mainSaved, "file://" + localPath);\n store.setDirty(false);\n alert(config.macros.twupdate.lingo.success);\n document.location.reload();\n }\n else\n alert(config.messages.mainFailed);\n}\n\nfunction AjaxHelper()\n{\n this.http = null;\n \n try\n {\n this.http = new XMLHttpRequest()\n }\n \n catch(e)\n {\n // if we don't get an internal object, try allocating it using ActiveX, with successive\n // fallbacks to earlier MSXML versions as necessary\n try\n {\n this.http = new ActiveXObject("Msxml2.XMLHTTP.4.0")\n } \n catch(e) \n {\n try\n {\n this.http = new ActiveXObject("MSXML2.XMLHTTP")\n } \n catch(e) \n {\n try\n {\n this.http = new ActiveXObject("Microsoft.XMLHTTP")\n } \n catch(e) \n {\n this.http = null\n }\n }\n }\n }\n \n if (!this.http) throw 'Unable to allocate an HTTP request object';\n}\n\nAjaxHelper.prototype.getText = function(url, callback, async, force)\n{\n if (!this.http) return;\n if (async == undefined) async = true;\n if (force == undefined) force = false;\n // ??? right now, we are not handling "forced" requests\n this._request("GET", url, callback, async, true, false);\n}\n\nAjaxHelper.prototype.getXML = function(url, callback, async, force)\n{\n if (!this.http) return;\n if (async == undefined) async = true;\n if (force == undefined) force = false;\n // ??? right now, we are not handling "forced" requests\n this._request("GET", url, callback, async, true, true);\n}\n\nAjaxHelper.prototype.getHead = function(url, callback, async, force)\n{\n if (!this.http) return;\n if (async == undefined) async = true;\n if (force == undefined) force = false;\n // ??? right now, we are not handling "forced" requests\n this._request("HEAD", url, callback, async, false, false);\n}\n\nAjaxHelper.prototype.abort = function()\n{\n if (this.http) this.http.abort();\n}\n\nAjaxHelper.prototype.setRequestHeader = function(name, value)\n{\n if (this.http) this.http.setRequestHeader(name, value);\n}\n\nAjaxHelper.prototype._request = function(method, url, callback, async, hasResponse, hasResponseXML)\n{\n if (!this.http) return;\n \n // get reference to request object so we can use it in closure\n var xmlHttp = this.http, helper = this;\n xmlHttp.onreadystatechange = function()\n {\n if (!async) return;\n if (xmlHttp.readyState == 4)\n callback((hasResponse ? (hasResponseXML ? xmlHttp.responseXML : xmlHttp.responseText) : null), xmlHttp.status, xmlHttp.statusText, helper._parsedResponseHeaders());\n }\n \n try {\n // need some cross-domain privileges for Firefox\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n } \n catch (e) \n {\n }\n \n xmlHttp.open(method, url, async);\n xmlHttp.send(null);\n if (!async) callback((hasResponse ? (hasResponseXML ? xmlHttp.responseXML : xmlHttp.responseText) : null), xmlHttp.status, xmlHttp.statusText, this._parsedResponseHeaders());\n }\n \n catch (e)\n {\n alert(e);\n }\n}\n\nAjaxHelper.prototype._parsedResponseHeaders = function()\n{\n if (this.http) {\n var headersArray = new Array();\n var headers = this.http.getAllResponseHeaders().split("\sn");\n for (var i = 0; i < headers.length; i++) {\n var h = headers[i].trim();\n if (h.length == 0) continue;\n // value can have ':' so do not use split here!\n var sep = h.indexOf(':');\n headersArray[h.substring(0, sep).trim()] = h.substr(sep + 1).trim();\n }\n return headersArray;\n }\n else\n return null;\n}\n\n//}}}\n
/***\n|Name|TagglyListPlugin|\n|Created by|SimonBaird|\n|Location|http://simonbaird.com/mptw/#TagglyListPlugin|\n|Version|1.1.2 25-Apr-06|\n|Requires|See TagglyTagging|\n\n!History\n* 1.1.2 (25-Apr-2006) embedded TagglyTaggingStyles. No longer need separated tiddler for styles.\n* 1.1.1 (6-Mar-2006) fixed bug with refreshAllVisible closing tiddlers being edited. Thanks Luke Blanshard.\n\n***/\n\n/***\n!Setup and config\n***/\n//{{{\n\nversion.extensions.TagglyListPlugin = {\n major: 1, minor: 1, revision: 2,\n date: new Date(2006,4,25),\n source: "http://simonbaird.com/mptw/#TagglyListPlugin"\n};\n\nconfig.macros.tagglyList = {};\nconfig.macros.tagglyListByTag = {};\nconfig.macros.tagglyListControl = {};\nconfig.macros.tagglyListWithSort = {};\nconfig.macros.hideSomeTags = {};\n\n// change this to your preference\nconfig.macros.tagglyListWithSort.maxCols = 6;\n\nconfig.macros.tagglyList.label = "Tagged as %0:";\n\n// the default sort options. set these to your preference\nconfig.macros.tagglyListWithSort.defaults = {\n sortBy:"title", // title|created|modified\n sortOrder: "asc", // asc|desc\n hideState: "show", // show|hide\n groupState: "nogroup", // nogroup|group\n numCols: 1\n};\n\n// these tags will be ignored by the grouped view\nconfig.macros.tagglyListByTag.excludeTheseTags = [\n "systemConfig",\n "TiddlerTemplates"\n];\n\nconfig.macros.tagglyListControl.tags = {\n title:"sortByTitle", \n modified: "sortByModified", \n created: "sortByCreated",\n asc:"sortAsc", \n desc:"sortDesc",\n hide:"hideTagged", \n show:"showTagged",\n nogroup:"noGroupByTag",\n group:"groupByTag",\n cols1:"list1Cols",\n cols2:"list2Cols",\n cols3:"list3Cols",\n cols4:"list4Cols",\n cols5:"list5Cols",\n cols6:"list6Cols",\n cols7:"list7Cols",\n cols8:"list8Cols",\n cols9:"list9Cols" \n}\n\n// note: should match config.macros.tagglyListControl.tags\nconfig.macros.hideSomeTags.tagsToHide = [\n "sortByTitle",\n "sortByCreated",\n "sortByModified",\n "sortDesc",\n "sortAsc",\n "hideTagged",\n "showTagged",\n "noGroupByTag",\n "groupByTag",\n "list1Cols",\n "list2Cols",\n "list3Cols",\n "list4Cols",\n "list5Cols",\n "list6Cols",\n "list7Cols",\n "list8Cols",\n "list9Cols"\n];\n\n\n//}}}\n/***\n\n!Utils\n***/\n//{{{\n// from Eric\nfunction isTagged(title,tag) {\n var t=store.getTiddler(title); if (!t) return false;\n return (t.tags.find(tag)!=null);\n}\n\n// from Eric\nfunction toggleTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)==null) t.tags.push(tag);\n else t.tags.splice(t.tags.find(tag),1);\n}\n\nfunction addTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n t.tags.push(tag);\n}\n\nfunction removeTag(title,tag) {\n var t=store.getTiddler(title); if (!t || !t.tags) return;\n if (t.tags.find(tag)!=null) t.tags.splice(t.tags.find(tag),1);\n}\n\n// from Udo\nArray.prototype.indexOf = function(item) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] == item) {\n return i;\n }\n }\n return -1;\n};\nArray.prototype.contains = function(item) {\n return (this.indexOf(item) >= 0);\n}\n//}}}\n/***\n\n!tagglyList\ndisplays a list of tagged tiddlers. \nparameters are sortField and sortOrder\n***/\n//{{{\n\n// not used at the moment...\nfunction sortedListOfOtherTags(tiddler,thisTag) {\n var list = tiddler.tags.concat(); // so we are working on a clone..\n for (var i=0;i<config.macros.hideSomeTags.tagsToHide.length;i++) {\n if (list.find(config.macros.hideSomeTags.tagsToHide[i]) != null)\n list.splice(list.find(config.macros.hideSomeTags.tagsToHide[i]),1); // remove hidden ones\n }\n for (var i=0;i<config.macros.tagglyListByTag.excludeTheseTags.length;i++) {\n if (list.find(config.macros.tagglyListByTag.excludeTheseTags[i]) != null)\n list.splice(list.find(config.macros.tagglyListByTag.excludeTheseTags[i]),1); // remove excluded ones\n }\n list.splice(list.find(thisTag),1); // remove thisTag\n return '[[' + list.sort().join("]] [[") + ']]';\n}\n\nfunction sortHelper(a,b) {\n if (a == b) return 0;\n else if (a < b) return -1;\n else return +1;\n}\n\nconfig.macros.tagglyListByTag.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n\n var sortBy = params[0] ? params[0] : "title"; \n var sortOrder = params[1] ? params[1] : "asc";\n\n var result = store.getTaggedTiddlers(tiddler.title,sortBy);\n\n if (sortOrder == "desc")\n result = result.reverse();\n\n var leftOvers = []\n for (var i=0;i<result.length;i++) {\n leftOvers.push(result[i].title);\n }\n\n var allTagsHolder = {};\n for (var i=0;i<result.length;i++) {\n for (var j=0;j<result[i].tags.length;j++) {\n\n if ( \n result[i].tags[j] != tiddler.title // not this tiddler\n && config.macros.hideSomeTags.tagsToHide.find(result[i].tags[j]) == null // not a hidden one\n && config.macros.tagglyListByTag.excludeTheseTags.find(result[i].tags[j]) == null // not excluded\n ) {\n if (!allTagsHolder[result[i].tags[j]])\n allTagsHolder[result[i].tags[j]] = "";\n allTagsHolder[result[i].tags[j]] += "**[["+result[i].title+"]]\sn";\n\n if (leftOvers.find(result[i].title) != null)\n leftOvers.splice(leftOvers.find(result[i].title),1); // remove from leftovers. at the end it will contain the leftovers...\n }\n }\n }\n\n\n var allTags = [];\n for (var t in allTagsHolder)\n allTags.push(t);\n\n allTags.sort(function(a,b) {\n var tidA = store.getTiddler(a);\n var tidB = store.getTiddler(b);\n if (sortBy == "title") return sortHelper(a,b);\n else if (!tidA && !tidB) return 0;\n else if (!tidA) return -1;\n else if (!tidB) return +1;\n else return sortHelper(tidA[sortBy],tidB[sortBy]);\n });\n\n var markup = "";\n\n if (sortOrder == "desc") {\n allTags.reverse();\n }\n else {\n // leftovers first...\n for (var i=0;i<leftOvers.length;i++)\n markup += "*[["+leftOvers[i]+"]]\sn";\n } \n\n for (var i=0;i<allTags.length;i++)\n markup += "*[["+allTags[i]+"]]\sn" + allTagsHolder[allTags[i]];\n\n if (sortOrder == "desc") {\n // leftovers last...\n for (var i=0;i<leftOvers.length;i++)\n markup += "*[["+leftOvers[i]+"]]\sn";\n }\n\n wikify(markup,place);\n}\n\nconfig.macros.tagglyList.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n var sortBy = params[0] ? params[0] : "title"; \n var sortOrder = params[1] ? params[1] : "asc";\n var numCols = params[2] ? params[2] : 1;\n\n var result = store.getTaggedTiddlers(tiddler.title,sortBy);\n if (sortOrder == "desc")\n result = result.reverse();\n\n var listSize = result.length;\n var colSize = listSize/numCols;\n var remainder = listSize % numCols;\n\n var upperColsize;\n var lowerColsize;\n if (colSize != Math.floor(colSize)) {\n // it's not an exact fit so..\n lowerColsize = Math.floor(colSize);\n upperColsize = Math.floor(colSize) + 1;\n }\n else {\n lowerColsize = colSize;\n upperColsize = colSize;\n }\n\n var markup = "";\n var c=0;\n\n var newTaggedTable = createTiddlyElement(place,"table");\n var newTaggedBody = createTiddlyElement(newTaggedTable,"tbody");\n var newTaggedTr = createTiddlyElement(newTaggedBody,"tr");\n\n for (var j=0;j<numCols;j++) {\n var foo = "";\n var thisSize;\n\n if (j<remainder)\n thisSize = upperColsize;\n else\n thisSize = lowerColsize;\n\n for (var i=0;i<thisSize;i++) \n foo += ( "*[[" + result[c++].title + "]]\sn"); // was using splitList.shift() but didn't work in IE;\n\n var newTd = createTiddlyElement(newTaggedTr,"td",null,"tagglyTagging");\n wikify(foo,newTd);\n\n }\n\n};\n\n/* snip for later.....\n //var groupBy = params[3] ? params[3] : "t.title.substr(0,1)";\n //var groupBy = params[3] ? params[3] : "sortedListOfOtherTags(t,tiddler.title)";\n //var groupBy = params[3] ? params[3] : "t.modified";\n var groupBy = null; // for now. groupBy here is working but disabled for now.\n\n var prevGroup = "";\n var thisGroup = "";\n\n if (groupBy) {\n result.sort(function(a,b) {\n var t = a; var aSortVal = eval(groupBy); var aSortVal2 = eval("t".sortBy);\n var t = b; var bSortVal = eval(groupBy); var bSortVal2 = eval("t".sortBy);\n var t = b; var bSortVal2 = eval(groupBy);\n return (aSortVal == bSortVal ?\n (aSortVal2 == bSortVal2 ? 0 : (aSortVal2 < bSortVal2 ? -1 : +1)) // yuck\n : (aSortVal < bSortVal ? -1 : +1));\n });\n }\n\n if (groupBy) {\n thisGroup = eval(groupBy);\n if (thisGroup != prevGroup)\n markup += "*[["+thisGroup+']]\sn';\n markup += "**[["+t.title+']]\sn';\n prevGroup = thisGroup;\n }\n\n\n\n*/\n\n\n//}}}\n\n/***\n\n!tagglyListControl\nUse to make the sort control buttons\n***/\n//{{{\n\nfunction getSortBy(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.sortBy;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["title"])) return "title";\n else if (tiddler.tags.contains(usetags["modified"])) return "modified";\n else if (tiddler.tags.contains(usetags["created"])) return "created";\n else return defaultVal;\n}\n\nfunction getSortOrder(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.sortOrder;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["asc"])) return "asc";\n else if (tiddler.tags.contains(usetags["desc"])) return "desc";\n else return defaultVal;\n}\n\nfunction getHideState(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.hideState;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["hide"])) return "hide";\n else if (tiddler.tags.contains(usetags["show"])) return "show";\n else return defaultVal;\n}\n\nfunction getGroupState(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.groupState;\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n if (tiddler.tags.contains(usetags["group"])) return "group";\n else if (tiddler.tags.contains(usetags["nogroup"])) return "nogroup";\n else return defaultVal;\n}\n\nfunction getNumCols(title) {\n var tiddler = store.getTiddler(title);\n var defaultVal = config.macros.tagglyListWithSort.defaults.numCols; // an int\n if (!tiddler) return defaultVal;\n var usetags = config.macros.tagglyListControl.tags;\n for (var i=1;i<=config.macros.tagglyListWithSort.maxCols;i++)\n if (tiddler.tags.contains(usetags["cols"+i])) return i;\n return defaultVal;\n}\n\n\nfunction getSortLabel(title,which) {\n // TODO. the strings here should be definable in config\n var by = getSortBy(title);\n var order = getSortOrder(title);\n var hide = getHideState(title);\n var group = getGroupState(title);\n if (which == "hide") return (hide == "show" ? "−" : "+"); // 0x25b8;\n else if (which == "group") return (group == "group" ? "normal" : "grouped");\n else if (which == "cols") return "cols±"; // &plusmn;\n else if (by == which) return which + (order == "asc" ? "↓" : "↑"); // &uarr; &darr;\n else return which;\n}\n\nfunction handleSortClick(title,which) {\n var currentSortBy = getSortBy(title);\n var currentSortOrder = getSortOrder(title);\n var currentHideState = getHideState(title);\n var currentGroupState = getGroupState(title);\n var currentNumCols = getNumCols(title);\n\n var tags = config.macros.tagglyListControl.tags;\n\n // if it doesn't exist, lets create it..\n if (!store.getTiddler(title))\n store.saveTiddler(title,title,"",config.options.txtUserName,new Date(),null);\n\n if (which == "hide") {\n // toggle hide state\n var newHideState = (currentHideState == "hide" ? "show" : "hide");\n removeTag(title,tags[currentHideState]);\n if (newHideState != config.macros.tagglyListWithSort.defaults.hideState)\n toggleTag(title,tags[newHideState]);\n }\n else if (which == "group") {\n // toggle hide state\n var newGroupState = (currentGroupState == "group" ? "nogroup" : "group");\n removeTag(title,tags[currentGroupState]);\n if (newGroupState != config.macros.tagglyListWithSort.defaults.groupState)\n toggleTag(title,tags[newGroupState]);\n }\n else if (which == "cols") {\n // toggle num cols\n var newNumCols = currentNumCols + 1; // confusing. currentNumCols is an int\n if (newNumCols > config.macros.tagglyListWithSort.maxCols || newNumCols > store.getTaggedTiddlers(title).length)\n newNumCols = 1;\n removeTag(title,tags["cols"+currentNumCols]);\n if (("cols"+newNumCols) != config.macros.tagglyListWithSort.defaults.groupState)\n toggleTag(title,tags["cols"+newNumCols]);\n }\n else if (currentSortBy == which) {\n // toggle sort order\n var newSortOrder = (currentSortOrder == "asc" ? "desc" : "asc");\n removeTag(title,tags[currentSortOrder]);\n if (newSortOrder != config.macros.tagglyListWithSort.defaults.sortOrder)\n toggleTag(title,tags[newSortOrder]);\n }\n else {\n // change sortBy only\n removeTag(title,tags["title"]);\n removeTag(title,tags["created"]);\n removeTag(title,tags["modified"]);\n\n if (which != config.macros.tagglyListWithSort.defaults.sortBy)\n toggleTag(title,tags[which]);\n }\n\n store.setDirty(true); // save is required now.\n story.refreshTiddler(title,false,true); // force=true\n}\n\nconfig.macros.tagglyListControl.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n var onclick = function(e) {\n if (!e) var e = window.event;\n handleSortClick(tiddler.title,params[0]);\n e.cancelBubble = true;\n if (e.stopPropagation) e.stopPropagation();\n return false;\n };\n createTiddlyButton(place,getSortLabel(tiddler.title,params[0]),"Click to change sort options",onclick,params[0]=="hide"?"hidebutton":"button");\n}\n//}}}\n/***\n\n!tagglyListWithSort\nput it all together..\n***/\n//{{{\nconfig.macros.tagglyListWithSort.handler = function (place,macroName,params,wikifier,paramString,tiddler) {\n if (tiddler && store.getTaggedTiddlers(tiddler.title).length > 0)\n // todo make this readable\n wikify(\n "<<tagglyListControl hide>>"+\n (getHideState(tiddler.title) != "hide" ? \n '<html><span class="tagglyLabel">'+config.macros.tagglyList.label.format([tiddler.title])+' </span></html>'+\n "<<tagglyListControl title>><<tagglyListControl modified>><<tagglyListControl created>><<tagglyListControl group>>"+(getGroupState(tiddler.title)=="group"?"":"<<tagglyListControl cols>>")+"\sn" + \n "<<tagglyList" + (getGroupState(tiddler.title)=="group"?"ByTag ":" ") + getSortBy(tiddler.title)+" "+getSortOrder(tiddler.title)+" "+getNumCols(tiddler.title)+">>" // hacky\n // + \sn----\sn" +\n //"<<tagglyList "+getSortBy(tiddler.title)+" "+getSortOrder(tiddler.title)+">>"\n : ""),\n place,null,tiddler);\n}\n\nconfig.macros.tagglyTagging = { handler: config.macros.tagglyListWithSort.handler };\n\n\n//}}}\n/***\n\n!hideSomeTags\nSo we don't see the sort tags.\n(note, they are still there when you edit. Will that be too annoying?\n***/\n//{{{\n\n// based on tags.handler\nconfig.macros.hideSomeTags.handler = function(place,macroName,params,wikifier,paramString,tiddler) {\n var theList = createTiddlyElement(place,"ul");\n if(params[0] && store.tiddlerExists[params[0]])\n tiddler = store.getTiddler(params[0]);\n var lingo = config.views.wikified.tag;\n var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;\n createTiddlyElement(theList,"li",null,"listTitle",prompt.format([tiddler.title]));\n for(var t=0; t<tiddler.tags.length; t++)\n if (!this.tagsToHide.contains(tiddler.tags[t])) // this is the only difference from tags.handler...\n createTagButton(createTiddlyElement(theList,"li"),tiddler.tags[t],tiddler.title);\n\n}\n\n//}}}\n/***\n\n!Refresh everything when we save a tiddler. So the tagged lists never get stale. Is this too slow???\n***/\n//{{{\n\nfunction refreshAllVisible() {\n story.forEachTiddler(function(title,element) {\n if (element.getAttribute("dirty") != "true") \n story.refreshTiddler(title,false,true);\n });\n}\n\nstory.saveTiddler_orig_mptw = story.saveTiddler;\nstory.saveTiddler = function(title,minorUpdate) {\n var result = this.saveTiddler_orig_mptw(title,minorUpdate);\n refreshAllVisible();\n return result;\n}\n\nstore.removeTiddler_orig_mptw = store.removeTiddler;\nstore.removeTiddler = function(title) {\n this.removeTiddler_orig_mptw(title);\n refreshAllVisible();\n}\n\nconfig.shadowTiddlers.TagglyTaggingStyles = "/***\snTo use, add {{{[[TagglyTaggingStyles]]}}} to your StyleSheet tiddler, or you can just paste the CSS in directly. See also ViewTemplate, EditTemplate and TagglyTagging.\sn***/\sn/*{{{*/\sn.tagglyTagged li.listTitle { display:none;}\sn.tagglyTagged li { display: inline; font-size:90%; }\sn.tagglyTagged ul { margin:0px; padding:0px; }\sn.tagglyTagging { padding-top:0.5em; }\sn.tagglyTagging li.listTitle { display:none;}\sn.tagglyTagging ul { margin-top:0px; padding-top:0.5em; padding-left:2em; margin-bottom:0px; padding-bottom:0px; }\sn\sn/* .tagglyTagging .tghide { display:inline; } */\sn\sn.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\sn.tagglyTagging table { margin:0px; padding:0px; }\sn\sn\sn.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\sn.tagglyTagging .button, .tagglyTagging .hidebutton { color:#aaa; font-size:90%; border:0px; padding-left:0.3em;padding-right:0.3em;}\sn.tagglyTagging .button:hover, .hidebutton:hover { background:#eee; color:#888; }\sn.selected .tagglyTagging .button { display:inline; }\sn\sn.tagglyTagging .hidebutton { color:white; } /* has to be there so it takes up space. tweak if you're not using a white tiddler bg */\sn.selected .tagglyTagging .hidebutton { color:#aaa }\sn\sn.tagglyLabel { color:#aaa; font-size:90%; }\sn\sn.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\sn.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\sn.tagglyTagging ul ul li {margin-left:0.5em; }\sn\sn.editLabel { font-size:90%; padding-top:0.5em; }\sn/*}}}*/\sn";\n\nrefreshStyles("TagglyTaggingStyles");\n\n\n//}}}\n\n// // <html>&#x25b8;&#x25be;&minus;&plusmn;</html>
/***\nTo use, add {{{[[TagglyTaggingStyles]]}}} to your StyleSheet tiddler, or you can just paste the CSS in directly. See also ViewTemplate, EditTemplate and TagglyTagging.\n***/\n/*{{{*/\n.tagglyTagged li.listTitle { display:none;}\n.tagglyTagged li { display: inline; font-size:90%; }\n.tagglyTagged ul { margin:0px; padding:0px; }\n.tagglyTagging { padding-top:0.5em; }\n.tagglyTagging li.listTitle { display:none;}\n.tagglyTagging ul { margin-top:0px; padding-top:0.5em; padding-left:2em; margin-bottom:0px; padding-bottom:0px; }\n\n/* .tagglyTagging .tghide { display:inline; } */\n\n.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }\n.tagglyTagging table { margin:0px; padding:0px; }\n\n\n.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }\n.tagglyTagging .button, .tagglyTagging .hidebutton { color:#aaa; font-size:90%; border:0px; padding-left:0.3em;padding-right:0.3em;}\n.tagglyTagging .button:hover, .hidebutton:hover { background:#eee; color:#888; }\n.selected .tagglyTagging .button { display:inline; }\n\n.tagglyTagging .hidebutton { color:white; } /* has to be there so it takes up space */\n.selected .tagglyTagging .hidebutton { color:#aaa }\n\n.tagglyLabel { color:#aaa; font-size:90%; }\n\n.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }\n.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}\n.tagglyTagging ul ul li {margin-left:0.5em; }\n\n.editLabel { font-size:90%; padding-top:0.5em; }\n/*}}}*/\n
Point your rss reader over to the blog at http://tiddlyspot.blogspot.com/ for future announcements. /%%/We will preserve this site though for historical purposes. :)
Take a look here: http://tiddlyspot.com/blog/\nThe first article is a nice one by Daniel on TiddlyWiki's low barrier of entry, and the motivation behind setting up Tiddlyspot.
To counter [[this problem|Stats page not working right]] we are now using a tracker image on each site to collect stats./%%/ This shouldn't cause any problems but please [[let us know|mailto:support@tiddlyspot.com]] if you come across any strangeness.
New tiddlyspot sites now use the new subdomain URL for everything. That also means new sites can't include capital letters./%%/\n\nNew sites also now get a "download" button in the right column, and we've replaced the old ~AboutTiddlySpot tiddler with something shorter and clearer (which also uses our preferred capitalisation of 'none': we prefer to write tiddlyspot, rather than ~TiddlySpot).\n\nThe demo sites have been updated, so if you want a quick look at the new layout check those out (on the home page, click the "@@color:#666;(?)@@" next to each of the flavours).
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 27/6/2006 11:49:15 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 27/6/2006 18:46:2 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 27/6/2006 18:46:27 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 28/6/2006 12:39:46 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 28/6/2006 12:40:4 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 28/6/2006 12:41:56 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . | Ok |\n| 28/6/2006 12:42:50 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 29/6/2006 17:34:19 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . | Ok |\n| 29/6/2006 17:34:58 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 1/7/2006 15:17:45 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . | Ok |\n| 1/7/2006 15:24:4 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 7/7/2006 14:41:56 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 7/7/2006 15:51:59 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 8/7/2006 14:40:31 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . | Ok |\n| 8/7/2006 15:18:26 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 8/7/2006 15:38:4 | Simon | [[/|http://tiddlyspot.com/announce/#%5B%5BProblem%20Affecting%20Site%20Creations%5D%5D]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 14/7/2006 10:10:25 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 14/7/2006 10:18:21 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 14/7/2006 10:25:58 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 14/7/2006 10:56:57 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 14/7/2006 11:0:8 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 19/7/2006 12:0:6 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 19/7/2006 12:0:18 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 19/7/2006 12:3:12 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 19/7/2006 12:13:35 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 21/7/2006 9:56:35 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 14/8/2006 12:12:43 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . | Ok |\n| 14/8/2006 12:13:12 | Simon | [[/|http://tiddlyspot.com/announce/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 15/8/2006 16:47:18 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://tiddlyspot.com/announce/store.php]] | . | index.html | . |\n| 15/8/2006 17:9:19 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.cgi|http://announce.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/8/2006 17:9:43 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.cgi|http://announce.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/8/2006 17:9:58 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.cgi|http://announce.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/8/2006 17:10:37 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 15/8/2006 17:12:23 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.cgi|http://announce.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/8/2006 17:14:35 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 15/8/2006 17:23:47 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 16/8/2006 0:11:24 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 17/8/2006 11:53:25 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 17/8/2006 11:54:40 | Daniel Baird | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 17/8/2006 11:55:59 | Daniel Baird | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 17/8/2006 11:56:43 | Daniel | [[/|http://announce.tiddlyspot.com/#%5B%5BUpdates%20for%20new%20sites%2C%20including%20subdomains%5D%5D]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 17/8/2006 17:51:30 | Daniel | [[/|http://announce.tiddlyspot.com/#%5B%5BYou%20can%20now%20password%20protect%20your%20site%5D%5D]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 18/8/2006 12:5:41 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 18/8/2006 12:8:29 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 18/8/2006 12:8:53 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 18/8/2006 14:36:12 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 18/8/2006 14:42:14 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 18/8/2006 14:43:50 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 18/8/2006 16:4:16 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 22/8/2006 10:42:9 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 22/8/2006 22:24:22 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 22/8/2006 22:25:15 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 22/8/2006 22:30:33 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 22/8/2006 23:7:31 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 10:27:0 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/8/2006 10:29:31 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 10:31:20 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 10:34:27 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/8/2006 10:36:51 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 10:41:38 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 10:45:55 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 10:55:20 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:6:32 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:11:15 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:15:20 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:16:5 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:21:8 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:21:50 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:22:30 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:22:30 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:23:45 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 23/8/2006 11:24:31 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 23/8/2006 11:27:17 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:22:20 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 25/8/2006 8:23:46 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:27:7 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:29:2 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:30:43 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 25/8/2006 8:31:33 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:33:4 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:37:14 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:38:48 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:42:57 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:48:55 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 8:51:28 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 9:18:16 | YourName | [[announce.html|file:///D:/Documents%20and%20Settings/User/Desktop/announce.html]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 25/8/2006 9:24:47 | YourName | [[announce.html|file:///D:/Documents%20and%20Settings/User/Desktop/announce.html]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 9:41:32 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 9:46:28 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 9:53:57 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 11:51:30 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 25/8/2006 11:59:13 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 6/9/2006 10:38:42 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 6/9/2006 10:44:19 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 14/9/2006 10:51:23 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 14/9/2006 10:51:40 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 14/9/2006 10:54:33 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 14/9/2006 10:57:28 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 5/10/2006 12:55:53 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 5/10/2006 12:56:27 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 5/10/2006 12:58:3 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 8/10/2006 23:8:54 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 8/10/2006 23:14:51 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 8/10/2006 23:17:7 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 8/10/2006 23:18:9 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 9/10/2006 10:21:41 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 9/10/2006 11:6:4 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 9/10/2006 13:33:9 | Daniel | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 19/10/2006 18:4:31 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 19/10/2006 18:7:6 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 19/10/2006 18:7:27 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 1/11/2006 18:43:53 | YourName | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 1/11/2006 18:45:42 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 1/12/2006 15:24:29 | Simon | [[/|http://announce.tiddlyspot.com/#%5B%5BTracker%20image%20inserted%20for%20stats%5D%5D%20%5B%5BStats%20page%20not%20working%20right%5D%5D]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 1/12/2006 15:25:27 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |\n| 14/2/2007 9:48:59 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . | Ok |\n| 14/2/2007 9:50:46 | Simon | [[/|http://announce.tiddlyspot.com/]] | [[store.php|http://announce.tiddlyspot.com/store.php]] | . | index.html | . |
/***\n<<tiddler UploadPluginDoc>>\n!Code\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 3, revision: 1, \n date: new Date(2006,3,30),\n type: 'macro',\n source: 'http://tiddlywiki.bidix.info/#UploadPlugin',\n docs: 'http://tiddlywiki.bidix.info/#UploadPluginDoc'\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\nconfig.lib.file.basename = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 2, date: new Date(2006,3,11),\n type: 'tweak',\n source: 'http://tiddlywiki.bidix.info/#PasswordTweak'\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n var size = 15;\n if (params[1])\n size = params[1];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.size = size;\n c.value = config.options[opt];\n place.appendChild(c);\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.size = size;\n c.value = config.options[opt];\n place.appendChild(c);\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\n};\n\nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\n var label;\n if (document.location.toString().substr(0,4) == "http")\n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.dirname(storeUrl)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n displayMessage(config.macros.upload.messages.aboutToUpload.format([this.dirname(storeUrl)]), this.dirname(storeUrl));\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n if (uploadDir) {\n rssPath = uploadDir + "/" + config.macros.upload.basename(rssPath);\n } else {\n rssPath = config.macros.upload.basename(rssPath);\n }\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [config.macros.upload.dirname(storeUrl)+"/"+rssPath]), config.macros.upload.dirname(storeUrl)+"/"+rssPath);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original = this.download(storeUrl, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n revised = revised.replace(new RegExp("<title>[^<]*</title>", "im"),"<title>"+ newSiteTitle +"</title>");\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [config.macros.upload.dirname(storeUrl)+"/"+toFilename]), config.macros.upload.dirname(storeUrl)+"/"+toFilename);\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');}\n }\n catch (e) { }\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "\sr\sn";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data;name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir\n + ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data;name=\s"userfile\s";filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //request.open("POST", storeUrl, true, username, password);\n request.open("POST", storeUrl, true);\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\nconfig.macros.upload.download = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n //request.open("GET", document.location.toString(), true, username, password);\n request.open("GET", document.location.toString(), true);\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]));\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nconfig.shadowTiddlers.UploadPluginDoc = "[[Full Documentation|http://tiddlywiki.bidix.info/l#UploadPluginDoc ]]\sn"; \n\n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n//}}}\n////===
Fixes a couple of minor issues. Newly created sites get this automatically. Existing sites can upgrade from here: http://tiddlywiki.bidix.info/#UploadPlugin\n\n(In the future we hope to have an easier to update your UploadPlugin).
<!--{{{-->\n<div class="toolbar" macro="toolbar -closeTiddler closeOthers +editTiddler permalink references jump newHere"></div>\n<div class="tagglyTagged" macro="hideSomeTags"></div>\n<div>\n <span class="title" macro="view title"></span>\n <span class="title" style="font-size:120%;color:#999;" macro="showWhen tiddler.tags.contains('Announcements')">\n <span macro='view created date [[ - DD MMM YYYY]]'></span>\n - posted by <span macro='view modifier'></span>\n </span>\n <span class="miniTag" macro="miniTag"></span>\n</div>\n<div class='subtitle'>Updated <span macro='view modified date [[DD MMM, YYYY]]'></span></div>\n<div class="viewer" macro="view text wikified"></div>\n<div class="viewer" macro="showWhen tiddler.tags.contains('Announcements')"><span macro="tiddler BackToIndex"></span></div>\n<div class="tagglyTagging" macro="tagglyListWithSort"></div>\n<div class="viewer" style="padding-top:1em;font-size:98%;" macro="showWhen tiddler.tags.contains('Announcements')">\n <h1>Comments</h1>\n <div style="margin-left:1em;">\n <span macro="haloscan comments"></span>\n <!--<span macro="haloscan trackbacks"></span>-->\n </div>\n <div style="margin-left:1em;" class="comments" macro="rssReader asText http://announce.tiddlyspot.com/proxy/www.haloscan.com/members/rss.php?user=glosoli ' '"></div>\n</div>\n<!--}}}-->\n
This was probably our most requested feature. Now you can change your password when you need to by visiting your control panel. /%%/Please let us know at [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] if you have any problems.\n\nThe control panel url (in case you don't already have it):\n{{{http://yoursitename.tiddlyspot.com/controlpanel}}}\nor\n{{{http://tiddlyspot.com/yoursitename/controlpanel}}}\nfor older sites.\n\nAlso there is a new download url. (The old one will keep working)\n{{{http://yoursitename.tiddlyspot.com/download}}}\nor\n{{{http://tiddlyspot.com/yoursitename/download}}}\nfor older sites.\n
You can do this and a couple of other things at the new Tiddlyspot Control Panel. The url for this is:\n\n=={{{http://tiddlyspot.com/}}}//{{{YourSiteName}}}//{{{/controlpanel.cgi}}}==\nadded 17 Aug 06: new url is {{{http://}}}//{{{yoursitename}}}//{{{.tiddlyspot.com/controlpanel.cgi}}}\n\nAlso, I realised no-one knows about the prettier url for downloading yet. It's:\n\n{{{http://tiddlyspot.com/download/}}}//{{{YourSiteName}}}//\n\nFeedback and suggestions are welcome. Comment on the [[blog post|http://tiddlyspot.com/blog/archives/general/working-control-panel/]] or email feedback@tiddlyspot.com.\n\n