Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
/***
|''Name''|SimpleSearchPlugin|
|''Description''|displays search results as a simple list of matching tiddlers|
|''Authors''|FND|
|''Version''|0.4.1|
|''Status''|stable|
|''Source''|http://devpad.tiddlyspot.com/#SimpleSearchPlugin|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/plugins/SimpleSearchPlugin.js|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''Keywords''|search|
!Code
***/
//{{{
if(!version.extensions.SimpleSearchPlugin) { //# ensure that the plugin is only installed once
version.extensions.SimpleSearchPlugin = { installed: true };
if(!config.extensions) { config.extensions = {}; }
config.extensions.SimpleSearchPlugin = {
heading: "Search Results",
containerId: "searchResults",
btnCloseLabel: "close",
btnCloseTooltip: "dismiss search results",
btnCloseId: "search_close",
btnOpenLabel: "open all",
btnOpenTooltip: "open all search results",
btnOpenId: "search_open",
displayResults: function(matches, query) {
story.refreshAllTiddlers(true); // update highlighting within story tiddlers
var el = document.getElementById(this.containerId);
query = '"""' + query + '"""'; // prevent WikiLinks
if(el) {
removeChildren(el);
} else { //# fallback: use displayArea as parent
var container = document.getElementById("displayArea");
el = document.createElement("div");
el.id = this.containerId;
el = container.insertBefore(el, container.firstChild);
}
var msg = "!" + this.heading + "\n";
if(matches.length > 0) {
msg += "''" + config.macros.search.successMsg.format([matches.length.toString(), query]) + ":''\n";
this.results = [];
for(var i = 0 ; i < matches.length; i++) {
this.results.push(matches[i].title);
msg += "* [[" + matches[i].title + "]]\n";
}
} else {
msg += "''" + config.macros.search.failureMsg.format([query]) + "''"; // XXX: do not use bold here!?
}
createTiddlyButton(el, this.btnCloseLabel, this.btnCloseTooltip, config.extensions.SimpleSearchPlugin.closeResults, "button", this.btnCloseId);
if(matches.length > 0) { // XXX: redundant!?
createTiddlyButton(el, this.btnOpenLabel, this.btnOpenTooltip, config.extensions.SimpleSearchPlugin.openAll, "button", this.btnOpenId);
}
wikify(msg, el);
},
closeResults: function() {
var el = document.getElementById(config.extensions.SimpleSearchPlugin.containerId);
removeNode(el);
config.extensions.SimpleSearchPlugin.results = null;
highlightHack = null;
},
openAll: function(ev) {
story.displayTiddlers(null, config.extensions.SimpleSearchPlugin.results);
return false;
}
};
// override Story.search()
Story.prototype.search = function(text, useCaseSensitive, useRegExp) {
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(), useCaseSensitive ? "mg" : "img");
var matches = store.search(highlightHack, null, "excludeSearch");
var q = useRegExp ? "/" : "'";
config.extensions.SimpleSearchPlugin.displayResults(matches, q + text + q);
};
// override TiddlyWiki.search() to sort by relevance
TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {
var candidates = this.reverseLookup("tags", excludeTag, !!match);
var primary = [];
var secondary = [];
var tertiary = [];
for(var t = 0; t < candidates.length; t++) {
if(candidates[t].title.search(searchRegExp) != -1) {
primary.push(candidates[t]);
} else if(candidates[t].tags.join(" ").search(searchRegExp) != -1) {
secondary.push(candidates[t]);
} else if(candidates[t].text.search(searchRegExp) != -1) {
tertiary.push(candidates[t]);
}
}
var results = primary.concat(secondary).concat(tertiary);
if(sortField) {
results.sort(function(a, b) {
return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
});
}
return results;
};
} //# end of "install only once"
//}}}
Macros
This page is still incomplete. You can help by contributing to its expansion.
Please improve the article, or discuss the issue on the talk page.
Macros provide commands to perform a variety of advanced functions in the place where they are called (usually within a tiddler).
A macro is normally called with the following syntax:
<<macroName [parameters]>>
In contrast to plugins, a macro's code is only executed when the respective tiddler containing the macro call is rendered.
Contents
[show]
Parameters
Generally, there are four ways to use macro parameters:
no quotes: <<foo bar baz>>
single quotes: <<foo 'bar' 'baz'>>
double quotes: <<foo "bar" "baz">>
double brackets: <<foo [[bar]] [[baz]]>>
Empty parameters (e.g. to adopt default value if the parameter is optional) are inserted by enclosing an empty string ('', "" or [[]]).
There's also fifth way, using curly brackets ({{...}}) - those contents are evaluated, so they're only used if the parameter value has to be calculated in some way.
Named Parameters
This section is still incomplete. You can help by contributing to its expansion.
Please improve the article, or discuss the issue on the talk page.
<<macro label:value>>
Evaluated Parameters
Parameters enclosed in {{ ... }} are processed as JavaScript code.
See Also
[[Category:Macros]]
[[Core Macros]]
[[Plugins]]
The backstage is an element every space has. It is an area where you can manage the space. It is where you can Include other spaces, add new members and perform various activities related to your content (tiddlers).
You can also manage your user account, such as create new spaces.
A number of TiddlyWiki [[macros]] define [[access keys|http://en.wikipedia.org/wiki/Access_key]], whose invocation is browser-specific:
|!PC|!Mac |!Function|
|SHIFT+ALT+F| CTRL+F|[[Search]]|
|SHIFT+ALT+J| CTRL+J|[[NewJournal]]|
|SHIFT+ALT+N| CTRL+N|[[NewTiddler]]|
|SHIFT+ALT+S| CTRL+S|[[SaveChanges]]|
{{{
For Firefox versions prior to 2.0 the default modifier is ALT only rather than SHIFT+ALT.
}}}
{{{
As of Opera 7.0 on the PC and Mac, press and release SHIFT+ESC and then press the shortcut letter without any modifier.
}}}
''The remaining keyboard shortcuts do not require access-key modifiers, and should thus be identical on all platforms.''
!!Editing
|!Shortcut|!Action|
|~Ctrl-Enter|Accept changes|
|~Shift-Ctrl-Enter|Accept minor change (do not update timestamp)|
|Esc|Cancel (abandon changes)|
!!Searching
|!Shortcut |!Action|
|Esc|Clear the search term|
TiddlyWiki is a free browser-based, reusable, non-linear personal notebook.
This is the community wiki, providing documentation and a variety of resources for TiddlyWiki users and developers. Please visit the official TiddlyWiki site for project information, downloads etc.
TiddlyWiki.org is a community effort, so active participation and contributions are very welcome!
[[TiddlyWiki]] [[TiddlyWiki.org]] [[Policy]] [[Help]]
[[Information for Users]]
[[Basics]]
[[Introduction]]
[[TiddlyWiki Markup]]
[[Components]]
[[Configuration]]
[[Content Management]]
[[Troubleshooting]]
[[TiddlyWiki FAQ]]
[[Advanced Features]]
[[Customization]]
[[Macros]]
[[Plugin]]
[[Scripts]]
[[Server-Side Solutions]]
[[Client-Side Tools]]
[[Additional Resources]]
[[Beginner's Guides]]
[[Getting Started on TiddlyWiki.com]]
[[TiddlyWiki for the Rest of Us by Dave Gifford]]
[[TW Help by Morris Gray]]
[[more... ]]
[[Services]]
[[Community Support mailing list at Google Groups]]
[[Tiddlyspot (free TiddlyWiki hosting)]]
[[Adaptations]]
[[MPTW]]
[[TeamTasks]]
[[RippleRap]]
[[more... ]]
[[Information for Developers]]
[[Guides]]
[[Translation]]
[[Core Code]]
[[Writing Plugins]]
[[Writing Macros]]
[[Resources]]
[[Code Repository]]
[[Tickets (Bug Tracking)]]
[[Developers' mailing list]]
[[Nightly Builds]]
[[Developer Tools]]
[[Hot Issues]]
[[Translation]]
[[Core Code]]
[[Writing Plugins]]
[[Writing Macros]]
[[Resources]]
[[Code Repository]]
[[Tickets (Bug Tracking)]]
[[Developers' mailing list]]
[[Nightly Builds]]
[[Developer Tools]]
[[Hot Issues]]
!Introduction to TiddlyWiki
<html>
<iframe width="420" height="345" src="http://www.youtube.com/embed/ezNScBd7_h4" frameborder="0" allowfullscreen></iframe>
</html>
!!Inline Styles
Apply CSS properties inline:
{{{
@@color:#4bbbbb;Some random text@@
}}}
Displays as:
@@color:#4bbbbb;Some random text@@
!!CSS classes
CSS classes can be applied to text blocks or runs. This form creates an HTML {{{<span>}}}:
{{{
{{customClassName{Some random text}}}
}}}
Displays as:
{{customClassName{Some random text}}}
This form generates an HTML {{{<div>}}}:
{{{
{{customClassName{
Some random text
}}}
}}}
Displays as:
{{customClassName{
Some random text
}}}
/***
|''Name''|FancyMissingPlugin|
|''Version''|0.1.0|
|''Description''|Orders the output in the Missing tab by how missing|
|''Author''|Frederik Dohr|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
No explicit use require, just add the plugin and go to the Missing tab.
!Code
***/
//{{{
(function() {
// hijack getMissingLinks to sort by number of references
var getMissingLinks = TiddlyWiki.prototype.getMissingLinks;
TiddlyWiki.prototype.getMissingLinks = function(sortField) {
var results = getMissingLinks.apply(this, arguments);
var index = results.map(function(item, i) {
return {
title: results[i],
count: store.getReferringTiddlers(results[i]).length
};
});
return index.sort(function(a, b) {
return b.count - a.count;
}).map(function(item, i) {
return item.title;
});
};
})();
//}}}
* install hideWhen from http://mptw.tiddlyspot.com/#HideWhenPlugin
* in your ViewTemplate do something like this:
...
...
<div macro="showWhen readOnly">
<!- - cut-down toolbar for web users - ->
<div macro='toolbar closeTiddler permalink'></div>
</div>
<div macro="hideWhen readOnly">
<!- - regular toolbar for me - ->
<div macro='toolbar closeTiddler closeOthers +editTiddler deleteTiddler permalink references jump'></div>
</div>
...
The ''isTouched'' method of a [[Tiddler]] object is used to determine whether a tiddler has been edited/changed since it was last saved. It takes no parameters.
If it has it will return ''true'', otherwise it will return ''false''
{{{
tiddler.isTouched();
}}}
* Plugins are a TW core-supported feature that works "out of the box".
* Plugins are tiddlers that contain ONLY pure javascript code. Any wiki syntax it contains must be wrapped inside a javascript comment block.
* Plugins are tagged with "systemConfig", which tells TW to run them ONCE, when the document is first loaded into the browser.
* Plugins typically install macro definitions or other 'handler functions' that are then triggered later on as a result of other activities.
* Plugins are optional modules extending the functionality of TiddlyWiki.
* Plugins are usually written by third-party developers and released under an open-source license.
* Plugins are usually just a tiddler containing ~JavaScript code.
!Installation
[[Ideally|Plugin Installation]], plugin tiddlers should be [[imported|Importing]] from their original location into the TiddlyWiki document.
In order to be processed on startup, plugins need to be assigned the ''systemConfig'' [[Tags|tag]].
In general, plugins are processed in alpha-numeric order (by tiddler title), using case-sensitive ASCII sort order (i.e. A-Z precedes a-z).
! Dependency Handling
Plugins support the use of a ''Requires'' [[slice]] to determine load order.
If a plugin contains such a slice, its value is processed as a space-separated, bracketed list of plugin names (i.e. value of the respective ''Name'' slice), and any plugins listed there will be loaded first, regardless of the sort order of the titles.
Object detection can be used for [[strict dependency handling|Best Practices]].
!Example
If PluginA requires PluginB to be loaded first, it should contain the following directive:
{{{
|Requires|PluginB|
}}}
This will force an override of the normal load sequence and ensure that PluginB is loaded before PluginA is processed.
! See Also
* <<tag plugins>>
* [[Plugin Installation]]
* [[Plugin Repositories]]
* [[Plugin Questions]]
* [[Macros]]
* [[Best Practices]]
The slider macro allows embedding tiddlers within another tiddler, with the option to toggle the visibility of the [[transclusion|transcluded]] content:
{{{
<<slider cookie tiddler label tooltip>>
}}}
* {{{cookie}}}: variable to save the state of the slider (e.g. {{{chkFooSlider}}})
* {{{tiddler}}}: name of the tiddler to include in the slider
* {{{label}}}: title text of the slider
* {{{tooltip}}}: tooltip text of the slider
For example:
{{{
<<slider chkTestSlider [[OptionsPanel]] "Options" "Open advanced options">>
}}}
The resumeNotifications method of a [[TiddlyWiki class|TiddlyWiki]] object resumes issuing notifications after [[suspendNotifications|TiddlyWiki.prototype.suspendNotifications]] is called. If [[suspendNotifications|TiddlyWiki.prototype.suspendNotifications]] was called multiple times, this method must be called an equal number of times in order for notifications to occur. This method does not expect any parameters.
This tiddler contains the commands that produce the buttons contained in the slider above the timeline on the right.
In ~TiddlySpace they are displayed on the right hand side of the menu bar.
By default it is set to:
{{{
<<closeAll>><<permaview>><<newTiddler>>
}}}
You can edit it to include anything else you want.
<html><div align="center"><iframe src="http://webchat.freenode.net?channels=tiddlywiki&uio=MTE9MTAz8d" width="500" height="400"></iframe></div></html>
This tiddler determines the colour scheme used within the TiddlyWiki. When a new space is created the random color palette macro determines the default, however these can be overwritten directly in the ColorPalette tiddler.
{{{
Background: #e0e3f5
Foreground: #090d1e
PrimaryPale: #b9c2e8
PrimaryLight: #7485d2
PrimaryMid: #384fb1
PrimaryDark: #0c1126
SecondaryPale: #cbe8b9
SecondaryLight: #98d274
SecondaryMid: #67b138
SecondaryDark: #16260c
TertiaryPale: #e8bab9
TertiaryLight: #d27574
TertiaryMid: #b13a38
TertiaryDark: #260c0c
Error: #f88
ColorPaletteParameters: HSL([229|48], [0.5146822107288709],[0.1|0.8208696653333263])
}}}
|!Formatting|!Macros|!Shadow tiddlers|!Miscellaneous|
|<<tiddler WikiTextContent>>|<<tiddler MacrosContent>>|<<tiddler ShadowTiddlersContent>>|<<tiddler ReferenceContent>>|
{{{
[element = ]createTiddlyText(parent,text)
}}}
The global function ''createTiddlyText'' creates a DOM text node. This function takes two parameters:
; parent
: the DOM element where the text node will be placed.
; text
: the text content to be added to ''parent''.
The TiddlyWiki core code is stored and developed as a collection of individual files, which makes it more manageable.
A recipe file determines which code files, tiddlers and HTML components to put together - somewhat like a jigsaw puzzle.
[[Cook]] then reads the recipe file and generates a new TiddlyWiki document from it.
Recipes can reference one another, making it straightforward to create a multiple variants of TiddlyWiki at one time.
!!Example
TiddlyWiki's [[default recipe file|http://svn.tiddlywiki.org/Trunk/core/tiddlywiki.html.recipe]]:
{{{
template: html/tiddlywiki.template.html
recipe: tiddlers/split.recipe
recipe: js/split.recipe
copy: java/TiddlySaver.jar
}}}
!!External Resources
* [[Recipe Files|http://trac.tiddlywiki.org/wiki/RecipeFiles]]
!!See Also
* [[Cook]]
* [[Ginsu]]
* [[Chef]]
/***
|''Name''|RevisionsCommandPlugin|
|''Description''|provides access to tiddler revisions|
|''Author''|FND|
|''Contributors''|Martin Budden|
|''Version''|0.3.3|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/RevisionsCommandPlugin.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/plugins/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Keywords''|serverSide|
!Usage
Extend [[ToolbarCommands]] with {{{revisions}}}.
!Revision History
!!v0.1 (2009-07-23)
* initial release (renamed from experimental ServerCommandsPlugin)
!!v0.2 (2010-03-04)
* suppressed wikification in diff view
!!v0.3 (2010-04-07)
* restored wikification in diff view
* added link to side-by-side diff view
!To Do
* strip server.* fields from revision tiddlers
* resolve naming conflicts
* i18n, l10n
* code sanitizing
* documentation
!Code
***/
//{{{
(function($) {
jQuery.twStylesheet(".diff { white-space: pre, font-family: monospace }",
{ id: "diff" });
var cmd = config.commands.revisions = {
type: "popup",
hideShadow: true,
text: "revisions",
tooltip: "display tiddler revisions",
revTooltip: "", // TODO: populate dynamically?
loadLabel: "loading...",
loadTooltip: "loading revision list",
selectLabel: "select",
selectTooltip: "select revision for comparison",
selectedLabel: "selected",
compareLabel: "compare",
linkLabel: "side-by-side view",
revSuffix: " [rev. #%0]",
diffSuffix: " [diff: #%0 #%1]",
dateFormat: "YYYY-0MM-0DD 0hh:0mm",
listError: "revisions could not be retrieved",
handlePopup: function(popup, title) {
title = this.stripSuffix("rev", title);
title = this.stripSuffix("diff", title);
var tiddler = store.getTiddler(title);
var type = _getField("server.type", tiddler);
var adaptor = new config.adaptors[type]();
var limit = null; // TODO: customizable
var context = {
host: _getField("server.host", tiddler),
workspace: _getField("server.workspace", tiddler)
};
var loading = createTiddlyButton(popup, cmd.loadLabel, cmd.loadTooltip);
var params = { popup: popup, loading: loading, origin: title };
adaptor.getTiddlerRevisionList(title, limit, context, params, this.displayRevisions);
},
displayRevisions: function(context, userParams) {
removeNode(userParams.loading);
if(context.status) {
var callback = function(ev) {
var e = ev || window.event;
var revision = resolveTarget(e).getAttribute("revision");
context.adaptor.getTiddlerRevision(tiddler.title, revision, context,
userParams, cmd.displayTiddlerRevision);
};
var table = createTiddlyElement(userParams.popup, "table");
for(var i = 0; i < context.revisions.length; i++) {
var tiddler = context.revisions[i];
var row = createTiddlyElement(table, "tr");
var timestamp = tiddler.modified.formatString(cmd.dateFormat);
var revision = tiddler.fields["server.page.revision"];
var cell = createTiddlyElement(row, "td");
createTiddlyButton(cell, timestamp, cmd.revTooltip, callback, null,
null, null, { revision: revision });
cell = createTiddlyElement(row, "td", null, null, tiddler.modifier);
cell = createTiddlyElement(row, "td");
createTiddlyButton(cell, cmd.selectLabel, cmd.selectTooltip,
cmd.revisionSelected, null, null, null,
{ index:i, revision: revision, col: 2 });
cmd.context = context; // XXX: unsafe (singleton)!?
}
} else {
$("<li />").text(cmd.listError).appendTo(userParams.popup);
}
},
revisionSelected: function(ev) {
var e = ev || window.event;
e.cancelBubble = true;
if(e.stopPropagation) {
e.stopPropagation();
}
var n = resolveTarget(e);
var index = n.getAttribute("index");
var col = n.getAttribute("col");
while(!index || !col) {
n = n.parentNode;
index = n.getAttribute("index");
col = n.getAttribute("col");
}
cmd.revision = n.getAttribute("revision");
var table = n.parentNode.parentNode.parentNode;
var rows = table.childNodes;
for(var i = 0; i < rows.length; i++) {
var c = rows[i].childNodes[col].firstChild;
if(i == index) {
if(c.textContent) {
c.textContent = cmd.selectedLabel;
} else {
c.text = cmd.selectedLabel;
}
} else {
if(c.textContent) {
c.textContent = cmd.compareLabel;
} else {
c.text = cmd.compareLabel;
}
c.onclick = cmd.compareSelected;
}
}
},
compareSelected: function(ev) {
var e = ev || window.event;
var n = resolveTarget(e);
var context = cmd.context;
context.rev1 = n.getAttribute("revision");
context.rev2 = cmd.revision;
context.tiddler = context.revisions[n.getAttribute("index")];
context.format = "unified";
context.adaptor.getTiddlerDiff(context.tiddler.title, context,
context.userParams, cmd.displayTiddlerDiffs);
},
displayTiddlerDiffs: function(context, userParams) {
var tiddler = context.tiddler;
tiddler.title += cmd.diffSuffix.format([context.rev1, context.rev2]);
tiddler.text = "{{diff{\n" + context.diff + "\n}}}";
tiddler.tags = ["diff"];
tiddler.fields.doNotSave = "true"; // XXX: correct?
if(!store.getTiddler(tiddler.title)) {
store.addTiddler(tiddler);
}
var src = story.getTiddler(userParams.origin);
var tiddlerEl = story.displayTiddler(src, tiddler);
var uri = context.uri.replace("format=unified", "format=horizontal");
var link = $('<a target="_blank" />').attr("href", uri).text(cmd.linkLabel);
$(".viewer", tiddlerEl).prepend(link);
},
displayTiddlerRevision: function(context, userParams) {
var tiddler = context.tiddler;
tiddler.title += cmd.revSuffix.format([tiddler.fields["server.page.revision"]]);
tiddler.fields.doNotSave = "true"; // XXX: correct?
if(!store.getTiddler(tiddler.title)) {
store.addTiddler(tiddler);
}
var src = story.getTiddler(userParams.origin);
story.displayTiddler(src, tiddler);
},
stripSuffix: function(type, title) {
var str = cmd[type + "Suffix"];
var i = str.indexOf("%0");
i = title.indexOf(str.substr(0, i));
if(i != -1) {
title = title.substr(0, i);
}
return title;
}
};
var _getField = function(name, tiddler) {
return tiddler.fields[name] || config.defaultCustomFields[name];
};
})(jQuery);
//}}}
FAQ about using the [[HideWhenPlugin|The HideWhenPlugin]] from [[MonkeyPirateTiddlyWiki|http://mptw.tiddlyspot.com/#HideWhenPlugin]].
!!Using ~HideWhen to do conditional toolbars based on user name
Replace the normal toolbar comand in the ViewTemplate tiddler with the following:
<div class='toolbar' macro="showWhen config.options.txtUserName == '~BartSimpson' ">
<span macro='toolbar editTiddler closeOthers closeTiddler'></span>
</div>
<div class='toolbar' macro="showWhen config.options.txtUserName != '~BartSimpson' ">
<span macro='toolbar closeOthers closeTiddler'></span>
</div>
!!Using ~HideWhen to do conditional fields based on tags
Let suppose you have a some tiddlers tagged with "friend" and you'd like to use some custom field to maintain some information about them, say their favourite food.
In ViewTemplate:
<div macro="showWhen tiddler.tags.contains('friend')">
Favourite food: <span macro="view favouritefood"></span>
</div>
In EditTemplate:
<div macro="showWhen tiddler.tags.contains('friend')">
Favourite food: <span macro="edit favouritefood"></span>
</div>
Now you can view and edit your friends' favourite food.
If you wish to have the same field show for your business contacts as well as your friends then you would do it like this:
In EditTemplate:
<div macro="showWhen tiddler.tags.containsAny(['friend','contact'])">
Favourite food: <span macro="edit favouritefood"></span>
</div>
In ViewTemplate:
<div macro="showWhen tiddler.tags.containsAny(['friend','contact'])">
Favourite food: <span macro="view favouritefood"></span>
</div>
Note that custom fields must be lower case. See http://trac.tiddlywiki.org/ticket/356 for details.
!!Making editable custom fields appear on a new tiddler
Create a customized newTiddler button:
<<newTiddler label:'Add Training' tag:'Training' title:'New Training'>>
Place the following in the EditTemplate:
<div macro="showWhen tiddler.tags.contains('Training') || tiddler.title == 'New Training'">
[[TrainingTemplateEdit]]
</div>
Create a TrainingTemplateEdit tiddler to put all of your desired custom fields in.
Placing each collection of custom fields in a separate tiddler helps cut down on the confusion of having multiple different things going on in your ViewTemplate & EditTemplate, as well as making it easier to safe guard against accidentally deleting or over writing one of them and losing everything.
|Style|Formatting|h
|''bold''|{{{''bold''}}} - two single-quotes, not a double-quote|
|//italics//|{{{//italics//}}}|
|''//bold italics//''|{{{''//bold italics//''}}}|
|__underline__|{{{__underline__}}}|
|--strikethrough--|{{{--Strikethrough--}}}|
|super^^script^^|{{{super^^script^^}}}|
|sub~~script~~|{{{sub~~script~~}}}|
|@@Highlight@@|{{{@@Highlight@@}}}|
|{{{plain text}}}|{{{ {{{PlainText No ''Formatting''}}} }}}|
|/%this text will be invisible%/hidden text|{{{/%this text will be invisible%/}}}|
Quote: Eric
The current TiddlyWiki username value is stored internally in javascript as config.options.txtUserName.
To display/modify the value using an edit field embedded in tiddler content, you can use the core's built-in {{{<<option>>}}} macro, like this:
{{{
<<option txtUserName>>
}}}
However, to display the value directly as inline tiddler content (e.g. as part of the SiteTitle or SiteSubtitle), using [[WikifyPlugin|http://www.TiddlyTools.com/#WikifyPlugin]] you can write:
{{{
<<wikify "%0" {{config.options.txtUserName}}>>
}}}
or use the [[InlineJavascriptPlugin|http://www.tiddlytools.com/#InlineJavascriptPlugin]] to write:
{{{
<script>return config.options.txtUserName</script>
}}}
!!Simpler Alternative
Quote: Kriss
An alternative option could be to:
1) create a tiddler named '~ShowValue' and containing only the text '$1'.
2) in the ''title''-tiddler, you enter:
{{{
<<tiddler ShowValue with:{{config.options.txtUserName}}>>
}}}
By changing the value after 'with:' you can now call this ''~ShowValue''-tiddler for any kind of value or expression.
To link to a tiddler named 'Meeting with Alice', you'd type <nowiki>[[Meeting with Alice]]</nowiki>
/***
|''Name''|BinaryTiddlersPlugin|
|''Description''|renders base64-encoded binary tiddlers as images or links|
|''Author''|FND|
|''Version''|0.3.2|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/BinaryTiddlersPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
!Code
***/
//{{{
(function($) {
var ctfield = "server.content-type";
var plugin = config.extensions.BinaryTiddlersPlugin = {
isWikiText: function(tiddler) {
var ctype = tiddler.fields[ctfield];
if(ctype) {
return !this.isBinary(tiddler) && !this.isTextual(ctype);
} else {
return true;
}
},
// NB: pseudo-binaries are considered non-binary here
isBinary: function(tiddler) {
var ctype = tiddler.fields[ctfield];
return ctype ? !this.isTextual(ctype) : false;
},
isTextual: function(ctype) {
return ctype.indexOf("text/") == 0
|| this.endsWith(ctype, "+xml")
|| ctype == 'application/json'
|| ctype == 'application/javascript';
},
endsWith: function(str, suffix) {
return str.length >= suffix.length &&
str.substr(str.length - suffix.length) == suffix;
},
isLink: function(tiddler) {
return this.isBinary(tiddler) && tiddler.text.indexOf("<html>") != -1
}
};
// Disable edit for linked tiddlers (for now)
// This will be changed to a GET then PUT
config.commands.editTiddler.isEnabled = function(tiddler) {
var existingTest = config.commands.editTiddler.isEnabled;
if (existingTest) {
return existingTest && !plugin.isLink(tiddler);
} else {
return !plugin.isLink(tiddler);
}
};
// hijack text viewer to add special handling for binary tiddlers
var _view = config.macros.view.views.wikified;
config.macros.view.views.wikified = function(value, place, params, wikifier,
paramString, tiddler) {
var ctype = tiddler.fields["server.content-type"];
if(params[0] == "text" && ctype && !tiddler.tags.contains("systemConfig") && !plugin.isLink(tiddler)) {
var el;
if(plugin.isBinary(tiddler)) {
var uri = "data:%0;base64,%1".format([ctype, tiddler.text]); // TODO: fallback for legacy browsers
if(ctype.indexOf("image/") == 0) {
el = $("<img />").attr("alt", tiddler.title).attr("src", uri);
} else {
el = $("<a />").attr("href", uri).text(tiddler.title);
}
} else {
el = $("<pre />").text(tiddler.text);
}
el.appendTo(place);
} else {
_view.apply(this, arguments);
}
};
// hijack edit macro to disable editing of binary tiddlers' body
var _editHandler = config.macros.edit.handler;
config.macros.edit.handler = function(place, macroName, params, wikifier,
paramString, tiddler) {
if(params[0] == "text" && plugin.isBinary(tiddler)) {
return false;
} else {
_editHandler.apply(this, arguments);
}
};
// hijack autoLinkWikiWords to ignore binary tiddlers
var _autoLink = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function() {
return plugin.isWikiText(this) ? _autoLink.apply(this, arguments) : false;
};
})(jQuery);
//}}}
The TabMoreOrphans tiddler contains a command that lists all the tiddlers that are not linked to from any other tidder.
{{{
<<list orphans>>
}}}
In TiddlyWiki this list appears as default in the {{{Orphans}}} tab on the right-hand menu.
[[Unit tests|http://en.wikipedia.org/wiki/Unit_testing]] increase confidence in the quality and reliability of source code.
From release 2.5, The TiddlyWiki core uses the [[QUnit|http://docs.jquery.com/QUnit]] framework (gradually transitioning from [[JSSpec|http://jania.pe.kr/aw/moin.cgi/JSSpec]]).
The [[test suite|http://trac.tiddlywiki.org/browser/Trunk/core/test/recipes/tests.html.recipe]] [[Dev:Recipe|recipe]] provides a simple way to get started.
Individual tests are located in the [[tests directory|http://trac.tiddlywiki.org/browser/Trunk/core/test/tests/]].
These tests can also be see in action in the @test space
This tiddler contains a list of the tiddlers that appear in the MainMenu. In the default TiddlySpace theme the MainMenu appears in the horizontal bar at the top of the page and in the default TiddlyWiki theme the MainMenu is on the left.
Unless you're delighted with the default scheme you can make some quick changes by generating a new random color palette, hit this button to cycle through some alternatives.
<<RandomColorPaletteButton saturation_pale:0.67 saturation_light:0.53
saturation_mid:0.43 saturation_dark:0.06 pale:0.99 light:0.85 mid:0.5 dark:0.31>>
<html><hr><html>
[[Basic|Basic Formatting]]
[[CSS|CSS Formatting]]
[[Code|Code Formatting]]
[[HTML Entities|HTML Entities Formatting]]
[[HTML|HTML Formatting]]
[[Headings|Headings Formatting]]
[[Horizontal Rules|Horizontal Rule Formatting]]
[[Images|Image Formatting]]
[[Line Breaks|Line Break Formatting]]
[[Links|Link Formatting]]
[[Lists|List Formatting]]
[[Quotations|Quotations Formatting]]
[[Suppressing|Suppressing Formatting]]
[[Tables|Tables Formatting]]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="14pt"
height="14pt"
viewBox="918 510 14 14"
id="svg3070">
<metadata
id="metadata3089">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3072">
<radialGradient
cx="0"
cy="0"
r="1"
id="Gradient"
gradientUnits="userSpaceOnUse">
<stop
id="stop3075"
style="stop-color:#ffffff;stop-opacity:1"
offset="0" />
<stop
id="stop3077"
style="stop-color:#2b2b2b;stop-opacity:1"
offset="1" />
</radialGradient>
<radialGradient
id="Obj_Gradient"
xlink:href="#Gradient"
gradientTransform="matrix(11.473944,0,0,11.473944,922.3752,513.7837)" />
</defs>
<g
id="g3080"
style="fill:none;stroke:none">
<g
id="g3082">
<path
d="m 929.6952,512.9018 c -2.5384,-2.53843 -6.654,-2.53843 -9.1924,0 -2.5384,2.5384 -2.5384,6.654 0,9.19238 2.5384,2.53839 6.654,2.53839 9.1924,0 2.5384,-2.53838 2.5384,-6.65398 0,-9.19238 m -4.5962,2.8407 2.07733,-2.07734 1.75547,1.75549 -2.0773,2.07735 2.0773,2.07732 -1.75547,1.75548 -2.07733,-2.07732 -2.07733,2.07732 -1.75547,-1.75548 2.0773,-2.07732 -2.0773,-2.07735 1.75547,-1.75549 z"
id="path3084"
style="fill:url(#Obj_Gradient)" />
<path
d="m 927.61447,515.38354 a 4.51205,4.2590378 0 1 1 -9.0241,0 4.51205,4.2590378 0 1 1 9.0241,0 z"
transform="matrix(1.0218069,0,0,1.0462046,-18.063694,-21.648443)"
id="path2394"
style="fill:#000000;fill-opacity:0;fill-rule:evenodd;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
</g>
</svg>
You can with Martin's new plugin support for diffrent markups. See:
http://www.martinswiki.com/#MediaWikiFormatterPlugin for MediaWiki markup
and http://www.martinswiki.com for other markup.
See also [[google groups discussion|http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/a8b1e3cc62ae9268/53149b6d2b5c3427?lnk=gst&q=MediaWiki&rnum=1]]
Sections in a tiddler refer to all that which is enclosed in headings. Beware that sections do __not__ entail subsections when being access programatically. Also note that a tiddlers end marks the end of the last section.
For example, assume a tiddler containing the following...
{{{
!Heading1
Some introductory text.
!!Heading2
Some more details.
}}}
Here, section {{{Heading1}}} refers to all content that the section Heading1 contains. If you transclude its content vie the tiddler macro via {{{<<tiddler Sections##Heading1>>}}} you get the following result:
<<<
<<tiddler Sections##Heading1>>
<<<
Likewise {{{<<tiddler Sections##Heading2>>}}} renders as:
<<<
Some more details.
<<<
Using the following you get a new tiddler button:
{{{
<<newTiddler>>
}}}
Displays as:
<<newTiddler>>
Certain attributes can also be attached, such as a label, default text, tags and fields:
{{{
<<newTiddler label:WikiWord text:"text" tag:tag tag:tag accessKey:key focus:field>>
}}}
Displays as:
<<newTiddler label:WikiWord text:"text" tag:tag tag:tag accessKey:key focus:field>>
[[Osmosoft|http://osmosoft.com]] is the open source innovation arm of [[BT|http://www.bt.com]].
We help promote [[Open Source]] within [[BT]], ensuring obligations when consuming and contributing to [[Open Source]] projects are well understood.
We drive innovation, leading several popular projects including [[TiddlyWiki]], [[TiddlyWeb]] and of course [[TiddlySpace]].
Evaluated macro parameters are parameters that can be passed to a macro which contain javascript. For example {{{<<tiddler {{ document.location.href }}>>}}} will display a tiddler (if it exists) with the same name as what is in your browser address bar. {{{document.location.href}}} is a javascript variable that is evaluated with the results passed to the macro.
It is ''not'' possible to use these in TiddlySpace for security reasons however they can be used in TiddlyWiki.
<!DOCTYPE html>
<html manifest="/bags/common/tiddlers/takenote_manifest.appcache">
<head>
<title>takenote</title>
<link type="text/css" rel="stylesheet" href="/bags/common/tiddlers/notabene.css" />
<link type="text/css" rel="stylesheet" href="/bags/common/tiddlers/jquery-ui.custom.css">
<link rel="apple-touch-icon" href="/bags/common/tiddlers/touchicon_takenote.png"/>
<link rel="apple-touch-icon-precomposed" href="/bags/common/tiddlers/touchicon_takenote.png"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=0,initial-scale=1.0">
</head>
<body>
<ul id="backstage">
<!-- no not add a newline between li elements or you will get a margin with inline blocks -->
<li><a href="/dashboard">dashboard</a></li><li><a href="/takenote">takenote</a></li>
<li><a class='connectionStatus'></a></li>
</ul>
<div class="takenotedashboard">
<div class='messageArea' style="display: none;"></div>
<div class="header">
<div class='siteicon'></div>
</div>
<div class="toolpanel viewer">
<div class='section searchSection requiresConnection'>
<h2>All Notes</h2>
<input class="findnote" type="search" placeholder="type search term" />
<ul>
<li>Access all notes in this space from <a href="/tiddlers?select=tag:!excludeLists">/tiddlers</a></li>
</ul>
</div>
<div class="section incompleteSection">
<h2>New Notes</h2>
<ul id="createNotes"></ul>
<h2>Recently Started Notes</h2>
<ul id="incomplete"></ul>
<a class='syncButton' title="save all notes in the list to the web">sync these notes</a>
</div>
<div class="section recentSection">
<h2>Recently Created Notes</h2>
<ul id="recentnotes"></ul>
</div>
</div>
<div class='footer'>
<span class='version'>v. 0.7.5</span>
</div>
</div>
<noscript>
Takenote requires javascript to work correctly. Sorry!
</noscript>
<script src="/bags/common/tiddlers/backstage.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/bookmark_bubble.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/jquery-ui.custom.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/tiddlyspace/tiddlers/chrjs" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/chrjs-store.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/jquery-json.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/notabene.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
dashboard($(".takenotedashboard")[0], {
host: "/"
});
</script>
</body>
</html>
[[Jeremy|http://jermolene.tiddlyspace.com]] is the original creator of TiddlyWiki and works at [[BT|http://www.btplc.com/]] where he is Head of Open Source Innovation, leading [[Osmosoft]].
The ''formatString'' method has been added to the Date object. You can use it to format a date however you please. It takes one parameter that is a ''template'' for how you want the date to be formatted.
Below is a table of all the components you can use in your template to get the desired date format.
|Template Part|Result Type|h
|hh12|Current hour using 12 hour clock|
|0hh|Current hour using 24 hour clock|
|hh|Current hour|
|mmm|Three character month representation|
|0mm|Current minute|
|mm|Current minute|
|0ss|Current second|
|ss|Current second|
|AM or PM|Returns whether it is am or pm (uppercase)|
|am or pm|Returns whether it is am or pm (lowercase)|
|wYYYY|4 digit year|
|wYY|2 digit year|
|YYYY|4 digit year|
|YY|2 digit year|
|MMM|Full month title|
|0MM|Month number prefixed with 0 (if req)|
|MM|Month number|
|0WW|Week number prefixed with 0 (if req)|
|WW|Week number|
|DDD|Full day name|
|ddd|3 char day name|
|~0DD|Day number prefixed with 0 (if req)|
|DDth|Day number with correct suffix (th, rd, st)|
|DD|Day number|
These can be combined to create your own date templates to use in your tiddlywiki. For example to display a date like, 27th January 2011 you'd need a template like:
//{{{
var template = "DDth MMM YYYY";
date.formatString(template);
//}}}
Or to display a date and time like, 27th Jan 18:54:23
//{{{
var template = "DDth mmm hh:mm:ss";
date.formatString(template);
//}}}
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
body {
font-family: sans-serif;
}
header,
footer {
color: #FFF;
background-color: #000;
}
header,
header h1,
footer,
footer p {
width: 100%;
}
header,
footer {
display: table;
}
header h1,
footer p {
display: table-cell;
vertical-align: middle;
padding-left: 5px;
padding-right: 5px;
}
nav {
background-color: #EEE;
}
nav,
nav li a {
color: #000;
}
nav li a {
display: block;
padding: 5px;
text-decoration: none;
cursor: pointer;
}
nav li a:link,
nav li a:visited,
nav li a:hover {
}
nav li a:active {
outline: none;
}
nav li a:focus {
outline-offset: -1px; /* hack to prevent Firefox from widening the element (despite the spec!) */
}
footer .username {
display: block;
float: right;
font-style: italic;
}
.pane article {
height: 100%;
background-color: #FFF;
}
.column {
width: 20%;
height: 100%;
overflow: auto; /* XXX: should be on UL/OL, but full-height is tricky then */
float: left;
border-right: 1px solid #AAA;
}
.column h3 {
display: none;
}
.column input {
display: block;
width: 95%; /* XXX: 100% would be more desirable, but leads to excessive width */
margin: 2px auto;
}
.column ul,
.column ol {
border-top: 1px solid #CCC;
list-style-type: none;
}
.column:first-child ul {
border-top: none;
}
.column li {
border-bottom: 1px solid #CCC;
background-color: #F8F8F8;
}
.column li a {
padding-left: 22px;
background-repeat: no-repeat;
background-position: 2px center;
}
.column.index li a,
.column.recipes li a,
.column.bags li a {
background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEDAP346fDUdNmMNP///yH5BAEAAAMALAAAAAAQABAAAAI2nI+py40BYwC0AiMslfCOGWlVgG1cKJShCKRDpnFtuQHn/Nr2ObkwH/HtgDiI4IhMCkiOZrMAADs=);
}
.column.tiddlers li a,
.column.revisions li a {
background-image: url(data:image/gif;base64,R0lGODlhEAAQAJECAMzMzPz8/P///wAAACH5BAEAAAIALAAAAAAQABAAAAIvFI4JIW0BYzysLYmpxfzsoFwQ8HES+YDhhYrm+K1s+YLxCqe1ncq5+2rtfjKFoAAAOw==);
}
.button {
border: 1px solid #CCC;
padding: 2px 5px;
text-decoration: none;
color: #1C94C4;
background-color: #F6F6F6;
cursor: pointer;
}
.button:focus {
outline: none;
}
.selected {
font-weight: bold;
color: #FFF;
background-color: #3D8CFF;
}
.disabled {
color: #AAA;
cursor: auto;
}
.info,
.error {
color: #000;
cursor: pointer;
}
.info {
background-color: #FCEFA1;
}
.active {
background-color: #FFFEEE;
}
.error {
background-color: #F88 !important;
}
.pane .button {
display: block;
float: right;
margin-bottom: 10px;
border-top-width: 0;
}
.pane #btnFullscreen {
border-left-width: 0;
border-right-width: 0;
}
Takes two parameters root (a dom element) and changeList (a list of tiddler names that have changed). WARNING: If changeList is not provided then all tiddlers will be refreshed. This could trigger lots of unnecessary refreshes.
Loops through all elements which are a child of the given root parameter.
If an element has a [[refresh attribute set|dom element refresh attribute]], it will run the related refresh handler.
//{{{
config.macros.references = {
handler: function(place, m, p, w, pa, tiddler) {
if(!tiddler) return;
else invokeMacro(place, "list", "filter \"[linksTo[%0]]\" emptyMessage:'No references'".format(tiddler.title), null, tiddler);
}
};
//}}}
Allows you to convert a string in YYYYMMDDHHMM form into a date object.
The HtmlJavascript is a special tiddler that allows you to add javascript files to the html [[serialization]] of a space.
The tiddler is a new line separated list of javascript files
e.g.
{{{
http://foo.tiddlyspace.com/tiddlername.js
tiddlername
/bags/glossary_public/tiddlers/tiddlername
}}}
Atom is a [[standard for syndication|http://en.wikipedia.org/wiki/Atom_(standard)]] that can be used in TiddlySpace to keep track of recent changes to collections of tiddlers. Any URL which returns several tiddlers can be retrieved as an atom feed and tracked in an aggregator such as [[NetNewsWire|http://netnewswireapp.com/]] and [[Google Reader|http://www.google.com/reader]].
Some examples:
''Tiddlers recently modified by @cdent'':
{{{
http://tiddlyspace.com/search.atom?q=modified:cdent
}}}
''All the tiddlers in the glossary space'':
{{{
http://glossary.tiddlyspace.com/tiddlers.atom
}}}
//Note the common user of the ''.atom'' extentsion.//
highlightHack is defined in main.js
{{{
var highlightHack = null; // Embarrassing hack department...
}}}
It is used to highlight text
[[Story.js|Story]] and Macros.js (the view macro) make use of this
{{{
story.forEachTiddler(function(t, tiddler, e) {
console.log("This: " + t);
console.log(tiddler);
console.log(e);
});
}}}
This macro displays the current date and time.
!Usage
{{{
<<today [dateFormat]>>
}}}
(cf. Date Formats) also: try the date format in quotes if the regular format doesn't work for you
The tab macro lets you create tab interfaces such as the one used for the timeline in the sidebar.
You use it as follows:
{{{
<<tabs theCookieName
nameOfFirstTab "HoverValueOfFirstTab" TiddlerToShowInTab(or content)
nameOfSecondTab "HoverValueOfSecondTab" TiddlerToShowInTab(or content)
...
>>
}}}
''theCookieName'' is used to store the name of the tab you currently have open. It does this so that when you return the tiddler will still be displaying the last tab you had selected.
Example use of the tab macro:
{{{
<<tabs txtFavourite
tags "First tab" "tags macro"
tag "Second tab" "tag macro"
>>
}}}
At it's most basic this macro lists all the tags used in you tiddlywiki as dropdown lists of all the tiddlers which have that tag
For example
{{{
<<allTags>>
}}}
Displays as:
<<allTags>>
The optional init() function of a tiddlywiki macro is automatically invoked by the TW core during the [[startup process]], but ''after'' all the plugins have been loaded.
{{{
config.macros.MacroName={
init: function() {
...
// your init code
...
},
handler: function(place, macroName, params, wikifier, paramString, tiddler){
}
}
}}}
<!--{{{-->
<div class='toolbar'
macro='toolbar [[ToolbarCommands::ViewToolbar]] icons:yes height:16 width:16 more:popup'>
</div>
<div class='heading'>
<span class='spaceSiteIcon'
macro='tiddlerOrigin label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
</span>
<span class="titleBar">
<div class='title' macro='view title text'></div>
<span class="subtitle" macro='viewRevisions page:5'>
last modified on
<span macro="view modified date"></span>
</span>
</span>
<div class='tagClear'></div>
</div>
<div class='content'>
<div class='viewer' macro='view text wikified'></div>
<div class='info_source' macro='originalSource'></div>
</div>
<div class='tagInfo'>
<div class='tidTags' macro='tags'></div>
<div class='tagging' macro='tagging'></div>
<hr/><div macro="view title replyLink"></div>
<span class='followPlaceHolder' macro='followTiddlers'></span>
<span
macro='view modifier SiteIcon label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
</span>
<div class='references' macro='serializerLinks'></div>
</div>
<!--}}}-->
Attempting to refresh the page changes will cause a browser warning:
<<<
There are unsaved changes in TiddlyWiki. If you continue you will lose those changes
<<<
This may be due to the automatic saving not being able to reach the server because the [[user|User]] has been offline, or is experiencing a bad network connection, or is faced with an [[Edit Conflict]]. Pressing <<saveChanges>> will cause any unsaved changes to be pushed to the server.
.
The notification mechanism is provided by the TiddlyWiki store object
to enable interested parties to register callback functions to be
invoked when tiddlers are modified. Callbacks can be registered to be
called for modifications to particular named tiddlers, or to be called
for modifications to any tiddler.
To register new callback functions one should make use of the [[addNotification method|TiddlyWiki.prototype.addNotification]]
Out of the box, the notification table looks like this (see Refresh.js
in the TiddlyWiki source repository):
{{{
config.notifyTiddlers = [
{name: "StyleSheetLayout", notify: refreshStyles},
{name: "StyleSheetColors", notify: refreshStyles},
{name: "StyleSheet", notify: refreshStyles},
{name: "StyleSheetPrint", notify: refreshStyles},
{name: "PageTemplate", notify: refreshPageTemplate},
{name: "SiteTitle", notify: refreshPageTitle},
{name: "SiteSubtitle", notify: refreshPageTitle},
{name: "ColorPalette", notify: refreshColorPalette},
{name: null, notify: refreshDisplay}
];
}}}
Note that these notification handlers are called while TiddlyWiki is
starting up and the store is being loaded from the HTML payload in the
document. Quite a lot of care is taken in the core to make sure that
this doesn't trigger double initialisation (where the main() function
explicitly initialises something that is also re-initialised inside a
notification handler).
The notification table is a global variable. It would be more correct
for each instance of the TiddlyWiki store object to have it's own
notification handler table.
One of the problems with the naivety of the notification mechanism is
that it can be quite noisy; if a piece of code is modifying a bunch of
tiddlers the torrent of notifications triggered can slow things down.
To resolve this, the TiddlyWiki object provides methods to temporarily
[[suspendNotifications()|TiddlyWiki.prototype.suspendNotifications]] and [[resumeNotifications()|TiddlyWiki.prototype.resumeNotifications]]. The core uses this
to improve the performance of the importTiddlers macro by suppressing
notifications as individual tiddlers are imported and issuing a
blanket notification at the end of the import.
Ginsu splits the tiddlers in a TiddlyWiki HTML out into separate files ready for checking in to Subversion.
cf. [[Trac|http://trac.tiddlywiki.org/wiki/Ginsu]]
!!External Resources
* [[Ginsu|http://trac.tiddlywiki.org/wiki/Ginsu]]
!!See Also
* [[Cook|Cook]]
* [[Recipes|Recipe]]
* [[Chef|Dev:Chef]]
[[Welcome]] <<randomTiddler>> [[About the old and the new wikis]]
A [[space|Space]] may have one or more members who together form a [[Small Trusted Group]] collectively owning the space.
[[TiddlyTools|http://www.tiddlytools.com]] is a treasure trove of high quality, well maintained TiddlyWiki plugins created by [[Eric Shulman]] of ELSDesign.
'' Getting an empty TiddlyWiki file from tiddlywiki.com ''
* Right click on http://www.tiddlywiki.com/empty.html
* Choose "Save link as..." or "Save target as..."
* Save the file to your desktop or somewhere else
* Go to the file you just saved and double click it
'' Getting a previous version of TiddlyWiki ''
* Visit http://www.tiddlywiki.com/archive/
'' Getting a hosted TiddlyWiki on Tiddlyspot ''
* Go to http://tiddlyspot.com
* Enter a site id and password
* Click create
* Your TiddlyWiki is now useable online
* To download:
** Click the download link
** Save the file on your desktop or somewhere
** Double click it to open it
'' Downloading a TiddlyWiki hosted somewhere else ''
* As with an empty TiddlyWiki file, but with the specific url
* Or install [http://tiddlywiki.bidix.info/#download.php download.php] on your server to be able to create a download link as in a Tiddlyspot's TiddlyWiki.
[[Category:FAQ]]
[[Category:Getting Started]]
* It is not possible to import from TiddlyWiki's on servers which are not [[CORS|http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing]] enabled. Popular sites such as [[TiddlyTools|http://tiddlytools.com]] are currently not CORS enabled. Fortunately this is fixable - webmasters can enable their sites to be CORS enabled by following the instructions [[here|http://enable-cors.org]] and if a website is not CORS enabled you can e-mail the owner to tell them the problem
* Some browsers will only allow you to import from TiddlyWikis in the same directory as your TiddlyWiki. If you use Chrome you can enable this by modifying the Chrome shortcut to include the following parameter
{{{
--allow-file-access-from-files
}}}
* Note some browsers, notably Opera do not support import / upgrade in any form.
Runs various <<tag refresh>> functions
It refreshes the PageTemplate, the display and the default stylesheets StyleSheetLayout, StyleSheetColors, StyleSheetPrint and the active stylesheet (usually StyleSheet but defined in the javascript variable config.refresherData.styleSheet)
!Wiki Markup
Sometimes text can inadvertently match TiddlyWiki formatting instructions - particularly program code, or text pasted from elsewhere.
This can be resolved by using one of the following options:
[cf. http://oldwiki.tiddlywiki.org/wiki/Escaping]
!Code Comments
Individual tiddler passages can be "commented out" to prevent them from being processed and/or displayed by TiddlyWiki:
[cf. http://oldwiki.tiddlywiki.org/wiki/Escaping / http://oldwiki.tiddlywiki.org/wiki/Dev:Comments]
A [[User]] who is a [[Member]] of a [[Space]] may add another [[User]] as a [[Member]] of the [[Space]]. Caution is advised adding another [[Member]] to a [[Home Space]] as the result is they are peers; both are [[Members|Member]] enjoying the same privileges, including being able to [[edit|Edit Tiddler]], [[publish|Publish Tiddler]], [[delete|Delete Tiddler]] and [[Remove Member|remove any member]] including the [[Owner]]. For this reason a [[Space]] may be thought of as a [[Small Trusted Group]].
Lately I found the version number changed from 2.6.2 to 2.6.3
But trying to upgrade the 2.6.2 version by backstage/upgrade does not work, it ends in displaying "Error with the new core code". And this error ist displayed not only when I try to upgrade from 2.6.2 to 2.6.3 but even when I try to "upgrade" a fresh and empty version 2.6.3 tiddlywiki. Might it be that there are (wrong?) Firefox configuration settings which prevent it from upgrading tiddlywiki? What am I doing wrong?
See also: [[Error with the new core code]]
The TiddlyWiki Address Book (twab) is a system for keeping your Address Book within your TiddlyWiki.
It supports the addition of contacts via a simple macro that can be placed in any Tiddler.
It also supports the import and export of your contacts to and from major webmail providers such as Google, Yahoo, and Hotmail as well as Microsoft Outlook. Twab is customizable and comes fully documented.
!!!Link:
http://www.tiddly-twab.com
Several [[macros]] take a date format string as an optional argument.
This string can be a combination of ordinary text and special placeholders that are substituted by parts of the date:
| Code | Output|h
|DDD|day of week in full (e.g. "Monday")|
|ddd|day of week in short (e.g. "Mon")|
|DD|day of month, without leading zero|
|0DD|day of month, with leading zero if necessary|
|~DDth|day of month with suffix|
|WW|~ISO-8601 week number of year, without leading zero|
|0WW|~ISO-8601 week number, with leading zero if necessary|
|MMM|month in full (e.g. "July")|
|mmm|short month (e.g. "Jul")|
|MM|month number, without leading zero|
|0MM|month number, with leading zero if necessary|
|YYYY|four-digit year number|
|YY|two-digit year|
|wYYYY|four-digit year number with respect to week number|
|wYY|two-digit year with respect to week number|
|hh|hours, 24-hour format, without leading zero|
|0hh|hours, 24-hour format, with leading zero if necessary|
|hh12|hours, 12-hour format, without leading zero|
|0hh12|hours, 12-hour format, with leading zero if necessary|
|mm|minutes, without leading zero|
|0mm|minutes, with leading zero if necessary|
|ss|seconds, without leading zero|
|0ss|seconds, with leading zero if necessary|
|am or pm|lowercase AM/PM indicator|
|AM or PM|uppercase AM/PM indicator|
The ''getContainer'' method of the [[Story]] class returns the DOM element that contains all the displayed tiddlers.
It takes no parameters
It can be used like this:
{{{
story.getContainer();
}}}
By default this will return the {{{<div id="tiddlerDisplay">}}} element.
* ''[[TiddlySnip|http://tiddlysnip.com]]'' a firefox extension that allows you to use TiddlyWiki as a scrapbook!
* ''[[Tiddle|http://tiddle.sourceforge.net]]'' a desktop application which provides an indexed quick-search view into a TiddlyWiki file.
A TiddlySpace [[space|Space]] comprises of two collections of [[tiddlers|Tiddler]]: a [[Public]] [[bag|Bag]] and a [[Private]] [[bag|Bag]]. Tiddlers in the Public bag are visible anyone who has access to the TiddlySpace server, in the case of http://tiddlyspace.com that is anyone on the Web. Only a [[member|Member]] of the [[space|Space]] may alter a public tiddler, though this is default [[Access Control]] may be changed by a member of a space using the TiddlyWeb [[HTTP API]].
Using the following creates a save changes button
{{{
<<saveChanges>>
}}}
Displays as:
<<saveChanges>>
The button label can also be changed and a tooltip added:
{{{
<<saveChanges [label] [tip]>>
}}}
Displays as:
<<saveChanges [label] [tip]>>
''Double Brackets in Links Are Not Rendered Properly''
* [[replace|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/90af118e1dc2fb1c]] the double brackets with their encoded equivalents, %5B and %5D respectively (see [[Firefox|Firefox#Permalinks]]).
All you need to run TiddlyWiki is your web browser. Though it must be a reasonably recent browser that supports javascript. Firefox is reported to have the best support, but IE (6 or better), Opera, and Safari are also supported.
If you want to [[Editing and Saving over HTTP|publish your TiddlyWiki]] then you'll need a web host (or a hosting service like the free http://www.tiddlyspot.com).
[[Category:FAQ]]
[[Category:Basics]]
CF:
I'm using TiddlyWiki 2.0.11, and it seems like my wiki options ("options >>" on the right sidebar) aren't being saved between browser sessions. If I make changes to the options, I see them reflected immediately, but when I close my web browser and then edit the page
again later, everything's lost. How do I fix this?
Saq:
Do you have cookies enabled? the TW options are saved in cookies.
CF:
Thanks! I had assumed the options were saved in the TiddlyWiki page itself and set up Firefox to clear cookies when I closed the browser.
See also [[How do I change my default options?]]
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
See http://trac.tiddlywiki.org/wiki/Translations for a current list of translations, and information on how to do new translations.
See http://trac.tiddlywiki.org/browser/Trunk/association/locales/core to view the source code of existing translations.
See http://translations.tiddlyspace.com/ to view and get information on how to include translations on TiddlySpace.
Image hosting sites offer a handful of pre-set sizes (eg thumbnail, small, large). If none suit, here's one method for resizing images within TiddlyWiki.
If using a URL, wrap it in HTML tags and insert '''style="width: 70px; "''' or '''style="height: 146px; "''' (altering the px to desired size) before '''/></html>''' like this:
<nowiki>
<html><img src="url of image" style="width: 70px; "/></html>
</nowiki>
If using HTML code from a hosting site, insert '''style="width: 70px; "''' before /></a></html> like this:
<nowiki>
<html><a href="link" style="width: 70px;" /></a></html>
</nowiki>
You can also use [[ImageSizePlugin|http://www.tiddlytools.com#ImageSizePlugin]] from [[TiddlyTools]] to resize images without using HTML.
/***
|''Name''|TiddlySpaceRevisionView|
|''Description''|Show tiddler revisions in a stack of cards view|
|''Author''|BenGillies|
|''Version''|0.2.0|
|''Status''|beta|
|''Source''|http://github.com/TiddlySpace/tiddlyspace|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Requires''|TiddlyWebAdaptor|
!Usage
The viewRevisions macro can be attached to any element, which should be passed
in as a parameter.
For example:
<<viewRevisions page:10 link:"<<view modified date>>">>
would show the revisions "stack of cards" view, 10 at a time, when the modified
date is clicked.
!Code
***/
//{{{
(function($) {
var me = config.macros.viewRevisions = {
revisionTemplate: "RevisionTemplate",
revSuffix: " [rev. #%0]", // text to append to each tiddler title
defaultPageSize: 5, // default number of revisions to show
defaultLinkText: "View Revisions", // when there's nothing else to use
offsetTop: 30, // in px
offsetLeft: 10, // in px
shiftDownDelay: 50, // in ms
visibleSlideAmount: 20, // amount of revisions to show on left hand edge after sliding
zIndex: 100, // default z-index
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
params = paramString.parseParams(null, null, true)[0];
var tiddlerElem = story.findContainingTiddler(place);
var revButton;
var pageSize = parseInt(params.page[0], 10) || me.defaultPageSize;
var linkObj = params.link ? params.link[0] || me.defaultLinkText : false;
if(linkObj) {
revButton = $('<span class="button openRevisions" />')
.appendTo(place);
wikify(linkObj, revButton[0], null, tiddler);
} else {
revButton = place;
}
$(revButton).click(function() {
if (!$(tiddlerElem).hasClass("revisions")) {
me.showRevisions(tiddlerElem, tiddler, pageSize);
} else {
me.closeRevisions(tiddlerElem);
}
});
},
// initialisation for revision view
showRevisions: function(tiddlerElem, tiddler, pageSize) {
var context = {
host: tiddler.fields["server.host"],
workspace: tiddler.fields["server.workspace"]
};
$(tiddlerElem).addClass("revisions").attr("revName", tiddler.title);
// ensure toolbar commands deactivate RevisionsView
$("a", ".toolbar", tiddlerElem).each(function(index, btn) {
var _onclick = btn.onclick;
btn.onclick = function(e) {
me.closeRevisions(tiddlerElem);
_onclick.apply(this, arguments);
};
});
// ensure default action deactivates RevisionsView
var _ondblclick = tiddlerElem.ondblclick;
tiddlerElem.ondblclick = function(e) {
me.closeRevisions(tiddlerElem);
_ondblclick.apply(this, arguments);
};
var type = tiddler.fields["server.type"];
var adaptor = new config.adaptors[type]();
var userParams = {
tiddlerElem: tiddlerElem,
pageSize: pageSize,
title: tiddler.title
};
me.createCloak(tiddlerElem);
adaptor.getTiddlerRevisionList(tiddler.title, null, context, userParams,
function(context, userParams) {
// strip the current revision
context.revisions.shift();
me.expandStack(context, userParams);
});
},
// fetch the actual revision and put it in the tiddler div
showRevision: function(place, revision, callback) {
var context = {
host: revision.fields["server.host"],
workspace: revision.fields["server.workspace"]
};
var userParams = {
revElem: place
};
var type = revision.fields["server.type"];
var adaptor = new config.adaptors[type]();
var revNo = revision.fields["server.page.revision"];
adaptor.getTiddlerRevision(revision.title, revNo, context, userParams,
function(context, userParams) {
var tiddler = context.tiddler;
tiddler.title += me.revSuffix
.format([$(place).attr("revision")]);
tiddler.fields.doNotSave = true;
if (store.getTiddler(tiddler.title)) {
store.deleteTiddler(tiddler.title);
}
store.addTiddler(tiddler);
//now, populate the existing div
var revElem = userParams.revElem;
$(revElem).attr("id", story.tiddlerId(tiddler.title));
$(revElem).attr("refresh", "tiddler");
var getTemplate = function() {
var themeName = config.options.txtTheme;
if (themeName) {
return store.getTiddlerSlice(themeName,
me.revisionTemplate) || me.revisionTemplate ||
"ViewTemplate";
} else {
return (store.getTiddler(me.revisionTemplate)) ?
me.revisionTemplate : "ViewTemplate";
}
};
var template = getTemplate();
story.refreshTiddler(tiddler.title, template, true);
callback(tiddler);
});
},
createCloak: function(promoteElem) {
var el = $(promoteElem);
// cache styles for resetting later
el.data({
top: el.css("top"),
left: el.css("left"),
zIndex: el.css("z-index")
});
$('<div class="revisionCloak" />').css("z-index", me.zIndex)
.click(function() {
me.closeRevisions(promoteElem);
})
.appendTo(document.body);
el.css("z-index", me.zIndex + 1);
},
// clean up, removing all evidence of revision view
closeRevisions: function(promoteElem) {
var el = $(promoteElem);
// revert the original tiddler back to its previous state
el.removeAttr("revName").removeClass("revisions").css({
top: el.data("top"),
left: el.data("left"),
zIndex: el.data("zIndex")
});
// remove any revisions still in the store
var revisions = $(".revisions");
revisions.each(function(index, revision) {
var revAttributes = revision.attributes;
if ((revAttributes.revname) &&
(revAttributes.revision)) {
var revName = revAttributes.revname.value;
var revNo = revAttributes.revision.value;
var title = revName + me.revSuffix.format([revNo]);
if (store.getTiddler(title)) {
store.deleteTiddler(title);
}
}
});
// delete the previous revisions
revisions.remove();
// remove the cloak
$(".revisionCloak").remove();
},
// calback from getting list of revisions
expandStack: function(context, userParams) {
var pageSize = userParams.pageSize;
var from = userParams.from || 0;
var tiddlerElem = userParams.tiddlerElem;
userParams.defaultHeight = $(tiddlerElem).height();
userParams.defaultWidth = $(tiddlerElem).width();
if (from < context.revisions.length) {
me.displayNextRevision(tiddlerElem, userParams, context, from,
from + pageSize - 1);
}
},
// place the next div above and behind the previous one
displayNextRevision: function(tiddlerElem, userParams, context, from, to) {
var revision = context.revisions[from];
var callback = function() {
var revText = revBtn.getRevisionText(tiddlerElem, revision);
tiddlerElem = me.createRevisionObject(tiddlerElem, context,
userParams, revText);
$(tiddlerElem)
.attr("revision", (context.revisions.length - from));
if ((from < to) && ((from + 1) < context.revisions.length)){
me.displayNextRevision(tiddlerElem, userParams, context,
from + 1, to);
} else if ((context.revisions.length - 1) > to) {
me.showMoreButton(tiddlerElem, context, userParams, to + 1);
}
}
me.shiftVisibleDown(userParams.title, callback);
},
createRevisionObject: function(tiddlerElem, context, userParams, text) {
var newPosition = me.calculatePosition(tiddlerElem, context);
return $('<div class="revisions tiddler" />')
.css({
position: "absolute",
top: newPosition.top,
left: newPosition.left,
"z-index": me.zIndex + 1,
height: userParams.defaultHeight,
width: userParams.defaultWidth
})
.attr("revName", userParams.title)
.append(text)
.insertBefore(tiddlerElem);
},
// move the already present revisions down by 1 to fit the next one in
shiftVisibleDown: function(title, callback) {
var revisions = $("[revName='%0'].revisions".format([title]));
var revisionCount = revisions.length;
$(revisions).animate({top: "+=" + me.offsetTop},
me.shiftDownDelay, function() {
revisionCount -= 1;
if ((callback) && (!revisionCount)) {
callback();
}
});
},
// where we put the new revision
calculatePosition: function(elem, context) {
var offset = $(elem).offset();
var currentPosition = $(elem).position();
var newPosition = {
top: currentPosition.top - me.offsetTop
};
if ((context.restrictLeft) ||
((offset.left - me.offsetLeft) <
$("#contentWrapper").offset().left)) {
newPosition.left = $(elem).position().left;
context.restrictLeft = true;
} else {
newPosition.left = currentPosition.left - me.offsetLeft;
}
return newPosition;
},
// equivalent of displayNextRevision, but for the more button
showMoreButton: function(tiddlerElem, context, userParams, moreIndex) {
userParams.from = moreIndex + 1;
me.shiftVisibleDown(userParams.title, function() {
var btn = me.createRevisionObject(tiddlerElem, context, userParams,
"");
var more = createTiddlyButton(btn[0], "more...", "show more revisions",
function() {
if ($(".viewRevision").length) {
return;
}
userParams.tiddlerElem = btn[0];
$(btn).text("")
.append(revBtn
.getRevisionText(btn[0], context.revisions[moreIndex]))
.attr("revision", context.revisions.length - moreIndex);
me.expandStack(context, userParams);
});
$(more).css("float", "right");
});
},
stripRevFromTitle: function(revisionTitle) {
return revisionTitle.split(/ ?\[rev\. #[0-9]+\]$/)[0];
},
onClickRevision: function(revElem, revision, callback) {
// don't do anything if we are still loading
if ($(".revisions").hasClass("loading")) {
return null;
}
var origTitle = me.stripRevFromTitle(revision.title);
if ($(revElem).hasClass("viewRevision")) {
$(".revisions").addClass("loading");
me.slideIn(revElem, revision, origTitle, function() {
store.deleteTiddler(revision.title);
revision.title = origTitle;
$(revElem).text("").append(revBtn.getRevisionText(revElem,
revision))
.removeAttr("tags").removeAttr("tiddler")
.removeAttr("refresh").removeAttr("template")
.removeAttr("id");
$(".revisions").removeClass("loading");
if (callback) {
callback();
}
});
$(revElem).removeAttr("prevPos").removeClass("viewRevision");
} else {
var viewRevision = function() {
var prevPos = $(revElem).position().left;
$(revElem).addClass("viewRevision").attr("prevPos", prevPos);
$(".revisions").addClass("loading");
me.showRevision(revElem, revision, function(rev) {
me.slideOut(revElem, rev, origTitle, function() {
$(".revisions").removeClass("loading");
});
});
};
// make sure another revision isn't already out
if ($(".viewRevision").length) {
var newRevElem = $(".viewRevision")[0];
var newRevision = store.getTiddler($(newRevElem)
.attr("tiddler"));
me.onClickRevision(newRevElem, newRevision, viewRevision);
} else {
viewRevision();
}
}
},
slideOut: function(revElem, revision, title, callback) {
var leftMostPos = $("[revName='%0'].revisions".format([title]))
.offset().left;
var width = $(revElem).width();
var originalLeftPos = $(story.getTiddler(title))
.position().left;
var slideAmount = leftMostPos + width - me.visibleSlideAmount;
$("[revName='%0'].revisions:not(.viewRevision)".format([title]))
.animate({left: "-=" + slideAmount}, 1000);
$(revElem)
.attr("baseHeight", $(revElem).css("height"))
.css("height", "auto")
.animate({left: originalLeftPos}, 1000, callback);
},
slideIn: function(revElem, revision, title, callback) {
var slideAmount = $(revElem).offset().left -
$(story.getTiddler(title)).offset().left;
var origRevPos = $(revElem).attr("prevPos");
$("[revName='%0'].revisions:not(.viewRevision)".format([title]))
.animate({left: "+=" + slideAmount}, 1000);
$(revElem).animate({left: origRevPos}, 1000, function() {
$(revElem)
.css("height", $(revElem).attr("baseHeight"))
.removeAttr("baseHeight");
callback();
});
}
};
var revBtn;
config.macros.slideRevision = revBtn = {
btnText: "created by %0 at %1 on %2",
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var btn = revBtn.getRevisionText(place, tiddler);
$(place).append(btn);
},
getRevisionText: function(place, revision) {
var text = revBtn.btnText.format([revision.modifier,
revision.modified.formatString("0hh:0mm"),
revision.modified.formatString("0DD MMM YYYY")]);
var btn = $('<a href="javascript:;" class="button revButton" />')
.text(text)
.click(function() {
var revElem = story.findContainingTiddler(this);
me.onClickRevision(revElem, revision);
});
return btn;
}
};
})(jQuery);
//}}}
The ''getTiddlers'' method of a [[TiddlyWiki class|TiddlyWiki Class]] object returns an array of every tiddler in the TiddlyWiki, sorted by a field. Its only parameter, the name of the field to sort on, is optional. This can be any property of the [[Tiddler]] class. If the TiddlyWiki is empty, an empty array is returned.
{{{
var tiddlers = store.getTiddlers();
}}}
I get this error when trying to update. I am using mGSD 3.1.3 beta on top of the core code. I am not sure what core code version I am at now. Maybe the update checks that?
<hr>
I get this same error.
<hr>
Same here - trying to upgrade core code from mGSD 3.1.7 beta
<hr>
Me too
Type the text for 'New Tiddler'
TiddlyWiki Resources
Contents
[show]
Official
tiddlywiki.com is the primary TiddlyWiki web site.
wiki.tiddlywiki.org is this documentation wiki.
trac.tiddlywiki.org Trac site for submitting/viewing bug reports and seeing the core development progress.
Getting Started on TiddlyWiki.com
Books
TiddlyWiki維基寫作-知識管理最佳工具 ("TiddlyWiki - An excellent tool for knowledge management."; Traditional Chinese)
Guides and Tutorials
TW Help a TiddlyWiki help file for beginners maintained by Morris Gray
TiddlyWiki for the rest of us by Dave G (Also available in Spanish)
Intro: TiddlyWiki is a very versatile program, but has an initial learning curve to it. Much of the documentation is written by and for people immersed day after day in computer code, so, um, how do I put this delicately, it is not always written in helpful everyday language. Not being a computer genius myself, I found the TiddlyWiki learning curve daunting, but well worth it. For those of you like me, newcomers to TiddlyWiki who don't know "Tiddly Squat", I would like you to discover this great program without having to commit as much time and energy to it as I did. Enjoy!
Tiddler Toddler A guide for absolute beginners by Julie Starr, an absolute beginner
TiddlyWikiTutorial a tutorial in the form of a TiddlyWiki
TiddlyWiki Basics by Denise Olson
Writing Macros and Core Code Overview now contain what had been at The Macrocodex a guide to writing TiddlyWiki macros by Gimcrack'd. (That link now produces 301.)
Tid-Help a primer for tiddlywiki by Jim Ventola
TiddlyWiki Getting Started Guide by Daniel Baird
A Getting Started Guide in development that might still be the first in a series of standalone guides to TiddlyWiki. See the latest sample for a preview.
TiddlyWiki quick reference card by Dmitri Popov (CheatSheet PDF) (Broken)
TiddlyWiki Format Reference One page reference for TiddlyWiki markup (without resorting to view tiddler source)
Start here: The making of a presentation manager part 1 to part 3 - A step by step HowTo get this: a-pm presentation manager by Mario Pietsch
Other Useful Sites
TiddlySpot (free TiddlyWiki hosting)
TiddlySnip a firefox extension that allows you to use TiddlyWiki as a scrapbook! (this wouldn't work in Firefox 3.5.12 because of an invalid security certificate)
TiddlyThemes a gallery of themes for TiddlyWiki
Community Support
Users' mailing list at Google Groups (Newcomers welcome!)
Developers' mailing list at Google Groups
IRC chat (#tiddlywiki on Freenode)
Facebook Groups
Benefactors
UnaMesa
Osmosoft
More
Some of these might be past their use-by date.
Tid-Help 2 a screencast also by Jim Ventola
TiddlyWikiTutorial by Blog Jones
Intro: Welcome to TiddlyWikiTutorial, an introduction to one of the most efficient ways of communicating information ever devised.
Getting Started Guide by Russ Lipton 404
Contents About Getting Started, What Is TiddlyWiki? What You Can Do With TiddlyWiki, Getting Around TiddlyWiki...
TiddlyWikiFAQ by Simon Baird. Has some stuff that should be migrated over here.
Some useful reference stuff by Julian Knight (Jules) including lists of built-in macros, formatting rules and useful JavaScript methods for developers.
TiddlyWikiTips by Jim Barr
A screencast by Leon Kilat. Unfortunately he choose an old version of GTD-TiddlyWiki. (Full screen version here).
An old but good introduction to/description of TiddlyWiki from euicho.com
Some older stuff at zrenard.com.
TiddlyWikiPlugin on delicious a list of plugins maintained by BidiX
Guida a TiddlyWiki an italian TiddlyWiki tutorial
Searches
Search for code at GitHub.
Search for code at SourceForge.
Search for shareable adaptations and user creations at LimeBits.
Search for anything "TiddlyWiki" at Delicious.
[[StyleSheetTiddlySpace]]
/*{{{*/
.info_source
{
margin-left: 56px;
}
.viewer .tagcloudTag
{
border:none;
background:#ddf;
line-height:1.2em;
}
.viewer .tagcloudTag:hover{
background:#ccf;
}
.twtable td
{
vertical-align:top;
}
.inlineList li {
margin-right: 10px;
display: inline-block;
}
/*}}}*/
/***
See [[How do I right-justify some text in a tiddler?]]
***/
/*{{{*/
.justifyright {
text-align: right;
}
.justifyfull {
text-align: justify;
}
/*}}}*/
{{{
[element = ]createTiddlyText(parent,text)
}}}
The global function ''createTiddlyText'' creates a DOM text node. This function takes two parameters:
; parent
: the DOM element where the text node will be placed.
; text
: the text content to be added to ''parent''.
The {{{<<list>>}}} macro creates a list of tiddlers of a given type. It takes the following parameters:
{{{
<<list {type} [template:<templateTiddlerName>] [emptyMessage:"<message for when the list is empty>"]>>
}}}
The template tiddlers allows you to customise the text that is displayed about each tiddler. If it is not provided, then the default of "{{{<<view title link>>}}}" is used, which just includes the title of the tiddler as a link. You could add the author to each entry in the list by setting the template to a tiddler with the text "{{{<<view title link>> by <<view modified link>>}}}".
The empty message parameter allows you to specify text to be displayed if the list of tiddlers is empty.
The following types are supported:
!all
To list all tiddlers
{{{
<<list all>>
}}}
!filter
List tiddlers that match a certain [[filter|filters syntax]]. The following example lists all plugins.
{{{
<<list filter [tag[systemConfig]]>>
}}}
!Missing
To list tiddlers that have links to them but are not defined:
{{{
<<list missing>>
}}}
!Orphans
To list tiddlers that are not linked to from any other tiddlers:
{{{
<<list orphans>>
}}}
!Shadowed
To list tiddlers shadowed with default contents:
{{{
<<list shadowed>>
}}}
!Touched
Show tiddlers that have been modified locally:
{{{
<<list touched>>
}}}
'' Slow Rendering ''
In TiddlyWikis with a large amount of tiddlers, the listings in [[SideBarTabs]] (e.g. [[Timeline]]) might require a long time to be generated, thus inhibiting the overall performance.
cf. [[Tips for speeding up performance on large TiddlyWikis|http://www.giffmex.org/twfortherestofus.html#%5B%5BTips%20for%20speeding%20up%20performance%20on%20large%20TiddlyWikis%5D%5D]]
Quote:[[Dave|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/2558268245a93d7a/cec021c6f5b42271?#cec021c6f5b42271]]
I recommend disabling animations even on medium-sized tiddlywikis. Animations slow it down. Also, if your file gets big you will want to open the shadowed tiddler tab rather than the tab listing all tidders A-Z or by date. Or hide the tabbed menus altogether if you don't need them showing. With each new tiddler, the image of the two tabbed lists I mentioned (all and by date) has to be refreshed and can take a while. You can remove the tabbed lists from the page layout by removing their code from PageTemplate. Nevertheless, I have a couple TiddlyWikis with 1,000s of tiddlers that each have form fields, and I am not noting any other performance
issues yet.
'' Plugin Load Times ''
[[Eric|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/38c0b23e4e007c2b/263409bf4f852efd?#263409bf4f852efd]]
The plugin 'load timer' information is available in the shadow tiddler, [[PluginManager]], which is also accessible from the
backstage>plugins menu, or by embedding the <nowiki><<plugins>></nowiki> macro into any tiddler content.
[[Martin|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/38c0b23e4e007c2b/53af6dface09556f?#53af6dface09556f]]
You can also see the total time taken to load the plugins:
1) go to the tweak dropdown in backstage
2) click the "Show unknown options" checkbox
3) click the "chkDisplayInstrumentation" checkbox, it's about the 8th one down
this will let you see what proportion of the total load time is spent loading the plugins
'' Maximum File Size ''
Ken: This seems to be the constant question: How big can it get?
As far as I am aware there is no limit to how big of a file you can download and open. I pumped up a TW to around 3 megs just to see what it could do and didn't have any problems. It took a while to get the file, but I got it.
If you are running lots of plugins then Firefox will give you the "A script is making this page run slow. Do you want to continue?" message, but it will load.
[[Daniel|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/2558268245a93d7a/7dcfe21a4e0d5bd3?#7dcfe21a4e0d5bd3]]
The problems reported by people with large TiddlyWikis are usually performance based, and it seems that the solution (once you've disabled animations..) is to remove macros that loop through every tiddler, like the tabs in the sidebar. So it's not so much the size
that's the problem in a direct sense, but the fact that many TW macros assume that looping through every tiddler isn't very slow.
Markus: Mine is online and loading of about 1.7 MB might be quite annoying for people with low bandwidth. I'm desperately seeking for a solution !
''Book Comparison ''
[[Alice in Wonderland|http://www.gutenberg.org/etext/11]], a book of approximately 200 pages, translates to a mere 160 kB in plain-text format.
'' See Also ''
* [[Tips for speeding up performance on large TiddlyWikis|http://www.giffmex.org/twfortherestofus.html#%5B%5BTips%20for%20speeding%20up%20performance%20on%20large%20TiddlyWikis%5D%5D]]
* [[I keep getting "A script is making this page run slow" in Firefox]]
This script allows you to insert the current time.
<script label="what time is it?">
return "<br>"+new Date().toString();
</script>
http://groups.google.com/group/tiddlywiki/browse_thread/thread/f440f280a8098592/58fc107fd0fe86ed?hl=en&lnk=gst&q=aliasplugin#
<!doctype html>
<html>
<head>
<title>TiddlyApp Share</title>
<link rel="stylesheet" href="/bags/common/tiddlers/profile.css" type="text/css"/>
<script src="/bags/common/tiddlers/jquery.js" type="text/javascript"></script>
<script src="/bags/tiddlyspace/tiddlers/chrjs" type="text/javascript"></script>
<script src="/bags/common/tiddlers/chrjs-store.js" type="text/javascript"></script>
<script src="/bags/common/tiddlers/chrjs.users" type="text/javascript"></script>
<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
<script>
// The templates of the links to display on the page
var links = [
{
title: "Tiddlers",
info: "Show a list of all the tiddlers in this space that a visitor currently has access to.",
href: "{host}/tiddlers"
}, {
title: "Public Tiddlers",
info: "Show a list of all the public tiddlers in this space in alphabetical order.",
href: "{host}/bags/{subdomain}_public/tiddlers?select=tag:!excludeLists;sort=title"
}, {
title: "Atom Feed",
info: "Get the Atom feed of the most recently changed tiddlers.",
href: "{host}/tiddlers.atom?select=tag:!excludeLists;sort=-modified;limit=20"
}, {
title: "Specific Tiddler",
info: "Show a specific tiddler in your space (GettingStarted in this example) as HTML, JSON or just plain text.",
href: ["{host}/GettingStarted", "{host}/GettingStarted.json", "{host}/GettingStarted.txt"],
more: "http://tiddlyweb.peermore.com/wiki/"
}, {
title: "Search for text",
info: "Search tiddlers for some text contained inside a tiddler.",
href: "{host}/search?q={subdomain}"
}, {
title: "List tiddlers with a tag",
info: "Display all the tiddlers that have the tag specified (here the tag is systemConfig).",
href: "{host}/tiddlers?select=tag:systemConfig"
}
];
$(function() {
var subdomain = document.location.host.split(".")[0];
// Filter curly braces to display information
for (var i in links) {
var href = links[i].href;
if (typeof href === "string")
href = [href];
for (var j in href) {
href[j] = href[j].replace("{host}", (document.protocol || "http:") + "//" + document.location.host);
href[j] = href[j].replace("{subdomain}", subdomain);
}
links[i].href = href;
}
// Display links to user
var insertInto = $('#share_links');
for (var i in links) {
var linkBody = $('<div class="share_link"></div>');
var linkDisplay = $('<div class="link_display"></div>');
for (var j in links[i].href) {
var a = $('<a class="link_href" target="_blank"/>');
a.html(links[i].href[j]);
a.attr('href', links[i].href[j]);
linkDisplay.append(a);
linkDisplay.append("<br/>");
}
var linkTitle = $('<b class="link_title"/>');
linkTitle.html(links[i].title);
var linkInfo = $('<div class="link_info"/>');
linkInfo.html(links[i].info);
linkBody.append(linkTitle);
linkBody.append('<br/>');
linkBody.append(linkInfo);
linkBody.append(linkDisplay);
if (links[i].more) {
var linkMore = $('<a class="link_more">Learn more</a>');
linkMore.attr('href', links[i].more);
linkBody.append(linkMore);
}
insertInto.append(linkBody);
}
});
</script>
<style type="text/css">
.link_display {
display: block;
background: #f2f2f2;
border: 1px solid #aaa;
padding: 10px;
margin-top: 4px;
word-wrap: break-word;
}
.link_more {
display: block;
text-align: right;
}
.share_link {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="container">
<div id="header">
<h1>Share Space</h1>
</div>
<div class="main section">
<p>Here are a number of methods that you can use to share this Space and its content in different ways.</p>
<span id="share_links"></span>
</div>
</div>
</body>
</html>
'' Problem ''
When you type a bunch of spaces into your TiddlyWiki, they look ok until you save and reload. Then any run of multiple spaces have been replaced with an single space. This also affects tab characters so it's especially nasty for plugins and code snippets. All your indenting gets trashed.
'' Solution ''
This only happens in Microsoft Internet Explorer. When IE stores tiddlers it replaces a set of spaces with a single space. There is no simple solution apart from switching to a different browser, such as Mozilla Firefox.
Also I believe the problem is fixed in 2.2 (currently in beta).
'' Guess Again ''
It happens in Firefox 2, TiddlyWiki 2.4.0.
And In FireFox 3. Hopefully there's a better solution than using &nbsp;
'''temporary note'''
Using [[preformatted blocks|TiddlyWiki Markup#Preformatted]] should solve this issue.
However, even without those, it seems to work fine with TiddlyWiki v2.4.1 and both Firefox 3 and IE7 on Windows Vista.
-- [[User:FND|FND]] 07:00, 28 August 2008 (UTC)
----
I just upgraded to 2.4.1 and spaces are not preserved for me. I run TiddlyWiki in Firefox 3 on Vista
-- 16:33, 18 December 2008 (UTC)
There are a number of plugins offering significant improvements over the built-in search functionality:
* [[SimpleSearchPlugin|http://devpad.tiddlyspot.com/#SimpleSearchPlugin]]
* [[SearchPlusPlugin|http://tw.lewcid.org/svn/plugins/SearchPlusPlugin/SearchPlusPlugin.js]] (requires [[PreferenceSaverLib|http://tw.lewcid.org/svn/plugins/PreferenceSaverLib/PreferenceSaverLib.js ]])
* [[SearchOptionsPlugin|http://www.tiddlytools.com/#SearchOptionsPlugin]]
** [[TwHelpSearchPlugin|http://twhelp.tiddlyspot.com/#TwHelpSearchPlugin]] defines an alternative format for the SearchResults tiddler generated by SearchOptionsPlugin)
* [[YourSearchPlugin|http://tiddlywiki.abego-software.de/#YourSearchPlugin]] (also available as a [[bookmarklet|http://xdexavier.googlepages.com/yoursearch.html ]])
The [[MatchTagsPlugin|http://www.tiddlytools.com/#MatchTagsPlugin ]] and [[GotoPlugin|http://www.TiddlyTools.com/#GotoPlugin]] might also be noteworthy in this context.
In addition, [[Tiddle|http://tiddle.sourceforge.net]] provides a desktop application for indexing TiddlyWiki documents.
! Be Bold!
Contributions to the wiki are always welcome. If you ever come across information that you think is useful to a larger audience, feel free to add it to the wiki.
Don't worry if you're not sure about details like page title or categorization - this is a wiki, so chances are others will take care of those issues as they find them.
! Editing Guidelines
Anyone who is a member of TiddlySpace has the power to edit in this space.
! Page Names
Page names should generally be concise (e.g. "Customization" or "Customizing" instead of "How to customize TiddlyWiki.").
!! Capitalization in Titles
# Always capitalize the first and the last word.
# Capitalize all nouns, pronouns, adjectives, verbs, adverbs, and subordinate conjunctions ("as", "because", "although").
# Lowercase all articles, coordinate conjunctions ("and", "or", "nor"), and prepositions regardless of length, when they are other than the first or last word.<br>Capitalize prepositions of five characters or more ("after", "among", "between").
# Lowercase the "to" in an infinitive.
source: [http://www.writersblock.ca/tips/monthtip/tipmar98.htm Writer's Block]
! See Also
* [[Quality]]
* <<tag help>>
The ''isDirty'' method of a [[TiddlyWiki class|TiddlyWiki]] object returns whether there are unsaved changes to it. This method expects no parameters.
Use:
{{{
store.isDirty();
}}}
See also: [[Story.setDirty]]
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="450 366 38 57"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<g>
<path d="M 452.1094 421.2422 L 450 421.2422 L 450 423 L 487.9688 423 L 487.9688 421.2422 L 485.8595 421.2422
L 485.8595 377.29688 L 487.9688 377.29688 L 487.9688 375.53906 L 485.8595 375.53906
C 485.8595 375.53906 481.12463 371.59341 473.02023 370.52802 C 472.6824 368.9689 471.72098 366.75 468.9844 366.75
C 466.24783 366.75 465.28638 368.9689 464.94864 370.52802
C 456.84418 371.59341 452.1094 375.53906 452.1094 375.53906 L 450 375.53906 L 450 377.29688 L 452.1094 377.29688
Z M 467.12247 370.32086 L 467.12247 370.32086 C 467.3805 369.42395 467.90762 368.50781 468.9844 368.50781
C 470.0612 368.50781 470.5883 369.42395 470.84634 370.32086
C 470.24136 370.2848 469.62054 370.26562 468.9844 370.26562
C 468.34827 370.26562 467.72748 370.2848 467.12247 370.32086 Z M 454.21875 420.92804 L 454.21875 420.92804
C 455.46762 420.42087 456.32816 419.35281 456.32816 418.11716 L 456.32816 377.29688 L 458.4375 377.29688
L 458.4375 421.2422 L 454.21875 421.2422 Z M 460.5469 420.92804 L 460.5469 420.92804
C 461.79578 420.42087 462.65625 419.35281 462.65625 418.11716 L 462.65625 377.29688 L 464.76566 377.29688
L 464.76566 421.2422 L 460.5469 421.2422 Z M 466.87503 420.92804 L 466.87503 420.92804
C 468.1239 420.42087 468.9844 419.35281 468.9844 418.11716 L 468.9844 377.29688 L 471.09378 377.29688
L 471.09378 421.2422 L 466.87503 421.2422 Z M 473.2032 420.92804 L 473.2032 420.92804
C 474.45203 420.42087 475.31256 419.35281 475.31256 418.11716 L 475.31256 377.29688 L 477.4219 377.29688
L 477.4219 421.2422 L 473.2032 421.2422 Z M 479.5313 420.92804 L 479.5313 420.92804
C 480.78018 420.42087 481.64066 419.35281 481.64066 418.11716 L 481.64066 377.29688 L 483.75006 377.29688
L 483.75006 421.2422 L 479.5313 421.2422 Z" fill="black" class="glyph"/>
</g>
</g>
</svg>
/***
|''Name''|TiddlyWebConfig|
|''Description''|configuration settings for TiddlyWebWiki|
|''Author''|FND|
|''Version''|1.3.2|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/TiddlyWebConfig.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Requires''|TiddlyWebAdaptor ServerSideSavingPlugin|
|''Keywords''|serverSide TiddlyWeb|
!Code
***/
//{{{
(function($) {
if(!config.extensions.ServerSideSavingPlugin) {
throw "Missing dependency: ServerSideSavingPlugin";
}
if(!config.adaptors.tiddlyweb) {
throw "Missing dependency: TiddlyWebAdaptor";
}
if(window.location.protocol != "file:") {
config.options.chkAutoSave = true;
}
var adaptor = tiddler.getAdaptor();
var recipe = tiddler.fields["server.recipe"];
var workspace = recipe ? "recipes/" + recipe : "bags/common";
var plugin = config.extensions.tiddlyweb = {
host: tiddler.fields["server.host"].replace(/\/$/, ""),
username: null,
status: {},
getStatus: null, // assigned later
getUserInfo: function(callback) {
this.getStatus(function(status) {
callback({
name: plugin.username,
anon: plugin.username ? plugin.username == "GUEST" : true
});
});
},
hasPermission: function(type, tiddler) {
var perms = tiddler.fields["server.permissions"];
if(perms) {
return perms.split(", ").contains(type);
} else {
return true;
}
}
};
config.defaultCustomFields = {
"server.type": tiddler.getServerType(),
"server.host": plugin.host,
"server.workspace": workspace
};
// modify toolbar commands
config.shadowTiddlers.ToolbarCommands = config.shadowTiddlers.ToolbarCommands.
replace("syncing ", "revisions syncing ");
config.commands.saveTiddler.isEnabled = function(tiddler) {
return plugin.hasPermission("write", tiddler) && !tiddler.isReadOnly();
};
config.commands.deleteTiddler.isEnabled = function(tiddler) {
return !readOnly && plugin.hasPermission("delete", tiddler);
};
// hijack option macro to disable username editing
var _optionMacro = config.macros.option.handler;
config.macros.option.handler = function(place, macroName, params, wikifier,
paramString) {
if(params[0] == "txtUserName") {
params[0] = "options." + params[0];
var self = this;
var args = arguments;
args[0] = $("<span />").appendTo(place)[0];
plugin.getUserInfo(function(user) {
config.macros.message.handler.apply(self, args);
});
} else {
_optionMacro.apply(this, arguments);
}
};
// hijack isReadOnly to take into account permissions and content type
var _isReadOnly = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
return _isReadOnly.apply(this, arguments) ||
!plugin.hasPermission("write", this);
};
var getStatus = function(callback) {
if(plugin.status.version) {
callback(plugin.status);
} else {
var self = getStatus;
if(self.pending) {
if(callback) {
self.queue.push(callback);
}
} else {
self.pending = true;
self.queue = callback ? [callback] : [];
var _callback = function(context, userParams) {
var status = context.serverStatus || {};
for(var key in status) {
if(key == "username") {
plugin.username = status[key];
config.macros.option.propagateOption("txtUserName",
"value", plugin.username, "input");
} else {
plugin.status[key] = status[key];
}
}
for(var i = 0; i < self.queue.length; i++) {
self.queue[i](plugin.status);
}
delete self.queue;
delete self.pending;
};
adaptor.getStatus({ host: plugin.host }, null, _callback);
}
}
};
(plugin.getStatus = getStatus)(); // XXX: hacky (arcane combo of assignment plus execution)
})(jQuery);
//}}}
Questions on how to use TiddlySpace, or TiddlyWiki may be sent to the [[TiddlyWiki List]].
Discussion on the development of TiddlySpace takes place on the [[TiddlyWeb List]]. The [[TiddlyWikiDev List]] is reserved for discussion of developing TiddlyWiki itself.
InterfaceOptions
SaveChanges
ToolbarButtons
SafeMode
KeyboardShortcuts
StartupParameters
SpecialTags
SpecialTiddlers
PermaView
HtmlEntities
[[Tags]]
IncrementalSearch
RegExpSearch
SaveEmptyTemplate
CustomStyleSheet
NestedStyleSheets
NestedTemplates
TiddlerSlicing
CustomMarkup
MobileDevices
.policy {
float: right;
margin: 10px;
border-collapse: collapse;
}
.policy,
.policy thead,
.policy th,
.policy td {
border: 1px solid #AAA;
padding: 2px 5px;
}
.policy caption,
.policy tr.special {
font-style: italic;
}
.policy caption {
text-align: left;
}
.policy thead,
.policy thead th {
border-color: #000;
}
.policy thead {
color: #FFF;
background-color: #000;
}
.policy th {
padding: 2px 10px;
}
.policy tr:nth-child(even) {
background-color: #EEE;
}
.policy input[type="checkbox"] {
display: block;
margin: 0 auto;
}
Edit the tiddler called SideBarOptions. (You can find it under the Shadowed tab under the More tab). Change the date format in the [[NewJournal macro|NewJournal (macro)]]. For example:
<nowiki> <<newJournal 'YYYY-MM-DD'>></nowiki>
See also [[DateFormats]]
The [[TiddlyWiki.prototype.getTiddlerText]] supports accessing sections in a tiddler.
If a tiddler has a heading ({{{!Heading}}}) in the markup of its text anything that follows that heading is returned.
For example given a tiddler with title "Title" which has the following text:
{{{
!Heading
foo
}}}
A call to
{{{
store.getTiddlerText|("Title##Heading")
}}}
will return "foo"
The ''getTiddlerText'' method of a [[TiddlyWiki|TiddlyWiki class]] object returns the source code of a tiddler. It takes two parameters:
* the title of the tiddler
* the string to return if the tiddler does not exist (by default, the null value — not an empty string)
For example, to get the text of this tiddler do the following
{{{
store.getTiddlerText('getTiddlerText');
// if it doesn't exist null will be returned
}}}
{{{
store.getTiddlerText('getTiddlerText', 'Nothing there');
// if it doesn't exist 'Nothing there' will be returned
}}}
If a tiddler is not defined by the author but a [[shadow tiddler|Shadow Tiddlers]] exists, its source code is returned instead. If the tiddler doesn't exist, then the second parameter passed is returned.
Also see [[Tiddler Heading Transclusion]]
/*
* jQuery Autocomplete plugin 1.1
*
* Copyright (c) 2009 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
*/
//{{{
(function($){$.fn.extend({autocomplete:function(urlOrData,options){var isUrl=typeof urlOrData=="string";options=$.extend({},$.Autocompleter.defaults,{url:isUrl?urlOrData:null,data:isUrl?null:urlOrData,delay:isUrl?$.Autocompleter.defaults.delay:10,max:options&&!options.scroll?10:150},options);options.highlight=options.highlight||function(value){return value;};options.formatMatch=options.formatMatch||options.formatItem;return this.each(function(){new $.Autocompleter(this,options);});},result:function(handler){return this.bind("result",handler);},search:function(handler){return this.trigger("search",[handler]);},flushCache:function(){return this.trigger("flushCache");},setOptions:function(options){return this.trigger("setOptions",[options]);},unautocomplete:function(){return this.trigger("unautocomplete");}});$.Autocompleter=function(input,options){var KEY={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var $input=$(input).attr("autocomplete","off").addClass(options.inputClass);var timeout;var previousValue="";var cache=$.Autocompleter.Cache(options);var hasFocus=0;var lastKeyPressCode;var config={mouseDownOnSelect:false};var select=$.Autocompleter.Select(options,input,selectCurrent,config);var blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){hasFocus=1;lastKeyPressCode=event.keyCode;switch(event.keyCode){case KEY.UP:event.preventDefault();if(select.visible()){select.prev();}else{onChange(0,true);}break;case KEY.DOWN:event.preventDefault();if(select.visible()){select.next();}else{onChange(0,true);}break;case KEY.PAGEUP:event.preventDefault();if(select.visible()){select.pageUp();}else{onChange(0,true);}break;case KEY.PAGEDOWN:event.preventDefault();if(select.visible()){select.pageDown();}else{onChange(0,true);}break;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){var fn=(arguments.length>1)?arguments[1]:null;function findValueCallback(q,data){var result;if(data&&data.length){for(var i=0;i<data.length;i++){if(data[i].result.toLowerCase()==q.toLowerCase()){result=data[i];break;}}}if(typeof fn=="function")fn(result);else $input.trigger("result",result&&[result.data,result.value]);}$.each(trimWords($input.val()),function(i,value){request(value,findValueCallback,findValueCallback);});}).bind("flushCache",function(){cache.flush();}).bind("setOptions",function(){$.extend(options,arguments[1]);if("data"in arguments[1])cache.populate();}).bind("unautocomplete",function(){select.unbind();$input.unbind();$(input.form).unbind(".autocomplete");});function selectCurrent(){var selected=select.selected();if(!selected)return false;var v=selected.result;previousValue=v;if(options.multiple){var words=trimWords($input.val());if(words.length>1){var seperator=options.multipleSeparator.length;var cursorAt=$(input).selection().start;var wordAt,progress=0;$.each(words,function(i,word){progress+=word.length;if(cursorAt<=progress){wordAt=i;return false;}progress+=seperator;});words[wordAt]=v;v=words.join(options.multipleSeparator);}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result",[selected.data,selected.value]);return true;}function onChange(crap,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();return;}var currentValue=$input.val();if(!skipPrevCheck&¤tValue==previousValue)return;previousValue=currentValue;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=currentValue.toLowerCase();request(currentValue,receiveData,hideResultsNow);}else{stopLoading();select.hide();}};function trimWords(value){if(!value)return[""];if(!options.multiple)return[$.trim(value)];return $.map(value.split(options.multipleSeparator),function(word){return $.trim(value).length?$.trim(word):null;});}function lastWord(value){if(!options.multiple)return value;var words=trimWords(value);if(words.length==1)return words[0];var cursorAt=$(input).selection().start;if(cursorAt==value.length){words=trimWords(value)}else{words=trimWords(value.replace(value.substring(cursorAt),""));}return words[words.length-1];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$(input).selection(previousValue.length,previousValue.length+sValue.length);}};function hideResults(){clearTimeout(timeout);timeout=setTimeout(hideResultsNow,200);};function hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(timeout);stopLoading();if(options.mustMatch){$input.search(function(result){if(!result){if(options.multiple){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:""));}else{$input.val("");$input.trigger("result",null);}}});}};function receiveData(q,data){if(data&&data.length&&hasFocus){stopLoading();select.display(data,q);autoFill(q,data[0].value);select.show();}else{hideResultsNow();}};function request(term,success,failure){if(!options.matchCase)term=term.toLowerCase();var data=cache.load(term);if(data&&data.length){success(term,data);}else if((typeof options.url=="string")&&(options.url.length>0)){var extraParams={timestamp:+new Date()};$.each(options.extraParams,function(key,param){extraParams[key]=typeof param=="function"?param():param;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{select.emptyList();failure(term);}};function parse(data){var parsed=[];var rows=data.split("\n");for(var i=0;i<rows.length;i++){var row=$.trim(rows[i]);if(row){row=row.split("|");parsed[parsed.length]={data:row,value:row[0],result:options.formatResult&&options.formatResult(row,row[0])||row[0]};}}return parsed;};function stopLoading(){$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(row){return row[0];},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(value,term){return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>");},scroll:true,scrollHeight:180};$.Autocompleter.Cache=function(options){var data={};var length=0;function matchSubset(s,sub){if(!options.matchCase)s=s.toLowerCase();var i=s.indexOf(sub);if(options.matchContains=="word"){i=s.toLowerCase().search("\\b"+sub.toLowerCase());}if(i==-1)return false;return i==0||options.matchContains;};function add(q,value){if(length>options.cacheLength){flush();}if(!data[q]){length++;}data[q]=value;}function populate(){if(!options.data)return false;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=options.data[i];rawValue=(typeof rawValue=="string")?[rawValue]:rawValue;var value=options.formatMatch(rawValue,i+1,options.data.length);if(value===false)continue;var firstChar=value.charAt(0).toLowerCase();if(!stMatchSets[firstChar])stMatchSets[firstChar]=[];var row={value:value,data:rawValue,result:options.formatResult&&options.formatResult(rawValue)||value};stMatchSets[firstChar].push(row);if(nullData++<options.max){stMatchSets[""].push(row);}};$.each(stMatchSets,function(i,value){options.cacheLength++;add(i,value);});}setTimeout(populate,25);function flush(){data={};length=0;}return{flush:flush,add:add,populate:populate,load:function(q){if(!options.cacheLength||!length)return null;if(!options.url&&options.matchContains){var csub=[];for(var k in data){if(k.length>0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else
if(data[q]){return data[q];}else
if(options.matchSubset){for(var i=q.length-1;i>=options.minChars;i--){var c=data[q.substr(0,i)];if(c){var csub=[];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub[csub.length]=x;}});return csub;}}}return null;}};};$.Autocompleter.Select=function(options,input,select,config){var CLASSES={ACTIVE:"ac_over"};var listItems,active=-1,data,term="",needsInit=true,element,list;function init(){if(!needsInit)return;element=$("<div/>").hide().addClass(options.resultsClass).css("position","absolute").appendTo(document.body);list=$("<ul/>").appendTo(element).mouseover(function(event){if(target(event).nodeName&&target(event).nodeName.toUpperCase()=='LI'){active=$("li",list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event){$(target(event)).addClass(CLASSES.ACTIVE);select();input.focus();return false;}).mousedown(function(){config.mouseDownOnSelect=true;}).mouseup(function(){config.mouseDownOnSelect=false;});if(options.width>0)element.css("width",options.width);needsInit=false;}function target(event){var element=event.target;while(element&&element.tagName!="LI")element=element.parentNode;if(!element)return[];return element;}function moveSelect(step){listItems.slice(active,active+1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem=listItems.slice(active,active+1).addClass(CLASSES.ACTIVE);if(options.scroll){var offset=0;listItems.slice(0,active).each(function(){offset+=this.offsetHeight;});if((offset+activeItem[0].offsetHeight-list.scrollTop())>list[0].clientHeight){list.scrollTop(offset+activeItem[0].offsetHeight-list.innerHeight());}else if(offset<list.scrollTop()){list.scrollTop(offset);}}};function movePosition(step){active+=step;if(active<0){active=listItems.size()-1;}else if(active>=listItems.size()){active=0;}}function limitNumberOfItems(available){return options.max&&options.max<available?options.max:available;}function fillList(){list.empty();var max=limitNumberOfItems(data.length);for(var i=0;i<max;i++){if(!data[i])continue;var formatted=options.formatItem(data[i].data,i+1,max,data[i].value,term);if(formatted===false)continue;var li=$("<li/>").html(options.highlight(formatted,term)).addClass(i%2==0?"ac_even":"ac_odd").appendTo(list)[0];$.data(li,"ac_data",data[i]);}listItems=list.find("li");if(options.selectFirst){listItems.slice(0,1).addClass(CLASSES.ACTIVE);active=0;}if($.fn.bgiframe)list.bgiframe();}return{display:function(d,q){init();data=d;term=q;fillList();},next:function(){moveSelect(1);},prev:function(){moveSelect(-1);},pageUp:function(){if(active!=0&&active-8<0){moveSelect(-active);}else{moveSelect(-8);}},pageDown:function(){if(active!=listItems.size()-1&&active+8>listItems.size()){moveSelect(listItems.size()-1-active);}else{moveSelect(8);}},hide:function(){element&&element.hide();listItems&&listItems.removeClass(CLASSES.ACTIVE);active=-1;},visible:function(){return element&&element.is(":visible");},current:function(){return this.visible()&&(listItems.filter("."+CLASSES.ACTIVE)[0]||options.selectFirst&&listItems[0]);},show:function(){var offset=$(input).offset();element.css({width:typeof options.width=="string"||options.width>0?options.width:$(input).width(),top:offset.top+input.offsetHeight,left:offset.left}).show();if(options.scroll){list.scrollTop(0);list.css({maxHeight:options.scrollHeight,overflow:'auto'});if($.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var listHeight=0;listItems.each(function(){listHeight+=this.offsetHeight;});var scrollbarsVisible=listHeight>options.scrollHeight;list.css('height',scrollbarsVisible?options.scrollHeight:listHeight);if(!scrollbarsVisible){listItems.width(list.width()-parseInt(listItems.css("padding-left"))-parseInt(listItems.css("padding-right")));}}}},selected:function(){var selected=listItems&&listItems.filter("."+CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected&&selected.length&&$.data(selected[0],"ac_data");},emptyList:function(){list&&list.empty();},unbind:function(){element&&element.remove();}};};$.fn.selection=function(start,end){if(start!==undefined){return this.each(function(){if(this.createTextRange){var selRange=this.createTextRange();if(end===undefined||start==end){selRange.move("character",start);selRange.select();}else{selRange.collapse(true);selRange.moveStart("character",start);selRange.moveEnd("character",end);selRange.select();}}else if(this.setSelectionRange){this.setSelectionRange(start,end);}else if(this.selectionStart){this.selectionStart=start;this.selectionEnd=end;}});}var field=this[0];if(field.createTextRange){var range=document.selection.createRange(),orig=field.value,teststring="<->",textLength=range.text.length;range.text=teststring;var caretAt=field.value.indexOf(teststring);field.value=orig;this.selection(caretAt,caretAt+textLength);return{start:caretAt,end:caretAt+textLength}}else if(field.selectionStart!==undefined){return{start:field.selectionStart,end:field.selectionEnd}}};})(jQuery);
//}}}
A ''getAmPm'' method has been added to the Date object. Any date object will be able to return whether the datetime is am or pm.
The function can be use like this:
//{{{
var date = new Date();
date.getAmPm();
//}}}
It would return {{{pm}}}.
The Story class governs what is visible to the user on the page, and is instantiated by the TiddlyWiki code when the page loads as the global object story.
In tiddlywiki there is one Story class which gets assigned to a variable called ''story''.
!!Properties
* ''container'': the DOM id of the Element that tiddlers are being displayed in
* ''highlightRegExp'': the current search string, if any
* ''idPrefix'': the string prepended to the DOM ids of tiddlers being displayed
!!Methods
* [[blurTiddler|Story.prototype.blurTiddler]]: remove focus from a tiddler
* [[chooseTemplateForTiddler|Story.prototype.chooseTemplateForTiddler]]: find the template name for a tiddler
* [[closeAllTiddlers|Story.prototype.closeAllTiddlers]]: close all tiddlers on the page
* [[closeTiddler|Story.prototype.CloseTiddler]]: close a single tiddler
* [[createTiddler|Story.prototype.createTiddler]]: show a tiddler on the page
* [[displayTiddler|Story.prototype.displayTiddler]]: animate showing a tiddler on the page
* [[displayTiddlers|Story.prototype.displayTiddlers]]: display many tiddlers simultaneously
* [[findContainingTiddler|Story.prototype.findContainingTiddler]]: find the tiddler containing an Element
* [[focusTiddler|Story.prototype.focusTiddler]]: give a tiddler's edit field keyboard focus
* [[forEachTiddler|Story.prototype.forEachTiddler]]: execute a function on every visible tiddler
* [[gatherSaveFields|Story.prototype.gatherSaveFields]]: gather all saveable edit fields from tiddlers on the page
* [[getTemplateForTiddler|Story.prototype.getTemplateForTiddler]]: return template source code for a tiddler
* [[hasChanges|Story.prototype.hasChanges]]: returns whether there are unsaved changes to a tiddler
* [[permaView|Story.prototype.permaView]]: change the address bar to a permalink to all visible tiddlers
* [[refreshAllTiddlers|Story.prototype.refreshAllTiddlers]]: re-display all tiddlers on the page
* [[refreshTiddler|Story.prototype.refreshTiddler]]: re-display a tiddler
* [[saveTiddler|Story.prototype.saveTiddler]]: save user changes to a tiddler
* [[scrubTiddler|Story.prototype.scrubTiddler]]: remove all DOM ids from a tiddler on the page
* [[search|Story.prototype.search]]: start a user-visible search
* [[setDirty|Story.prototype.setDirty]]: set the dirty flag of a single tiddler
* [[setTiddlerTag|Story.prototype.setTiddlerTag]]: specify tags for a tiddler
A [[SiteIcon|SiteIcon tiddler]]@glossary helps provide some identity to your space. Ideally it'd be a square and a minimum of 48*48 pixels size. You can upload your site icon using the uploader below.
<<binaryUploadPublic title:SiteIcon>>
<html><hr><html>
The getRecursiveTiddlerText method of a [[TiddlyWiki|TiddlyWiki Class]] object returns the source code of a tiddler with links replaced with their contents. That is, if two tiddlers are defined like so:
'''tiddler1'''
{{{
Hello, [[tiddler2]].
}}}
'''tiddler2'''
{{{
world
}}}
executing
{{{
getRecursiveTiddlerText('tiddler1', '', 1)
}}}
returns ''Hello world.'' This method expects three parameters in order:
* the title of the tiddler to retrieve
* default text to return if the tiddler does not exist
* the maximum depth of links to follow
/***
|''Name''|<...>|
|''Description''|<...>|
|''Author''|FND|
|''Version''|<#.#.#>|
|''Status''|<//unknown//; @@experimental@@; @@beta@@; //obsolete//; stable>|
|''Source''|http://devpad.tiddlyspot.com/#<...>|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.0|
|''Requires''|<...>|
|''Keywords''|<...>|
***/
//{{{
(function($) {
var macro = config.macros.randomTiddler = {
locale: {
label: "random",
tooltip: "display a random tiddler"
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var excludeTag = params[0] || "excludeLists";
var btn = createTiddlyButton(place, this.locale.label,
this.locale.tooltip, function() {});
btn.onclick = null; // XXX: hacky, but createTiddlyButton wouldn't add href otherwise
$(btn).data("excludeTag", excludeTag).click(this.onClick);;
},
onClick: function() {
var btn = $(this);
var excludeTag = btn.data("excludeTag");
var tiddlers = store.getTiddlers();
macro.displayRandomTiddler(tiddlers, excludeTag);
},
displayRandomTiddler: function(tiddlers, excludeTag) {
var i = Math.floor(Math.random() * tiddlers.length);
var tid = tiddlers[i];
if(!tid.tags.contains(excludeTag)) {
story.displayTiddler(place, tid);
} else {
this.displayRandomTiddler(tiddlers); // XXX: risks infinite recursion
}
}
};
})(jQuery);
//}}}
Search fields can be created using:
{{{
<<search>>
}}}
Displays as:
<<search>>
A default search term can also be added:
{{{
<<search [term]>>
}}}
Displays as:
<<search [term]>>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Account</title>
<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
<link href="/bags/common/tiddlers/jquery-ui.custom.css" type='text/css' rel='stylesheet' >
<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
</head>
<body>
<div id="container">
<div class="main section">
<a class="app" href="/apps">back to apps</a>
<div class="left">
<div id="siteiconArea">
<h2>Site Icon</h2>
<div>
<img id="siteicon" class="siteicon">
<form id="upload" method="POST" enctype="multipart/form-data">
<input type="hidden" name="title" value="SiteIcon" />
<input type="hidden" name="tags" value="excludeLists">
<input type="hidden" name="csrf_token" class="csrf" />
<input type="file" name="file" />
<input type="submit" value="upload" />
</form>
</div>
</div>
<h2>Find Space</h2>
<form class="spaceSearch">
<input class="inputBox" type="text" placeholder="find space" />
<a href="http://docs.tiddlyspace.com/What%20is%20a%20Space%3F" class="help"
title="What is a space?">What is a space?</a>
<button>view all</button>
</form>
<div class='list-container'>
You are a member of the following spaces:
<ul class='ts-space-search'>
</ul>
</div>
<h2>Create New Space</h2>
<form class="ts-spaces">
<input class="inputBox" type="text" name="spacename" placeholder="space name"><span class="hostSuffix">.tiddlyspace.com</span>
<input type="submit" value="Create Space" />
</form>
</div>
<div class="right">
<h2>Change Password</h2>
<form class="ts-password">
<input class="inputBox" placeholder="existing password" type="password" name="password">
<input class="inputBox" placeholder="new password" type="password" name="new_password">
<input class="inputBox" placeholder="new password" type="password" name="new_password_confirm">
<input type="submit" value="Change password">
</form>
<h2>OpenID</h2>
<h3>Why OpenID?</h3>
<a href="http://openid.net/"><img src="/bags/common/tiddlers/openid.png" alt="openid" ></a><br />
Use just one username and password across hundreds of OpenID-enabled sites.<br />
It's an open standard.<br />
<a href="http://openid.net/what/">learn more</a>
<ul class="ts-identities"></ul>
<form class="ts-openid" target="_top">
<div>
Add an openid:
</div>
<input class="inputBox" type="text" name="openid" placeholder="your openid" />
<input type="submit" value="Register" />
<a href="http://openid.net/get-an-openid/" class="help"
title="What is an open id?">What is an open id?</a>
</form>
</div>
<div class="clear"></div>
</div>
</div>
<script type='text/javascript' src='/bags/common/tiddlers/jquery.js'></script>
<script type='text/javascript' src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script type='text/javascript' src='/bags/common/tiddlers/chrjs.space'></script>
<script type='text/javascript' src='/bags/common/tiddlers/chrjs.users'></script>
<script type='text/javascript' src='/bags/common/tiddlers/chrjs.identities'></script>
<script type='text/javascript' src="/bags/common/tiddlers/jquery-ui.custom.js"></script>
<script type='text/javascript' src='/bags/common/tiddlers/jquery-form.js'></script>
<script type='text/javascript' src="/bags/common/tiddlers/siteiconupload.js"></script>
<script type='text/javascript' src='/bags/common/tiddlers/ts.js'></script>
<script type="text/javascript">
/*
* jQuery UI Autocomplete HTML Extension
*
* Copyright 2010, Scott González (http://scottgonzalez.com)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*/
(function( $ ) {
var proto = $.ui.autocomplete.prototype,
initSource = proto._initSource;
function filter( array, term ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
return $.grep( array, function(value) {
return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
});
}
$.extend( proto, {
_initSource: function() {
if ( this.options.html && $.isArray(this.options.source) ) {
this.source = function( request, response ) {
response( filter( this.options.source, request.term ) );
};
} else {
initSource.call( this );
}
},
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
.appendTo( ul );
}
});
})( jQuery );
/***
_accounts application specific javascript
***/
var link;
ts.init(function(ts) {
if(ts.user.anon) { // redirect to homepage when user not logged in
window.location = ts.getHost();
} else if(ts.user.name === ts.currentSpace){
initSiteIconUpload(ts.user.name);
} else {
link = $("<a />").attr("href", ts.getHost(ts.user.name) + "/_account").text("Change SiteIcon");
$("#siteiconArea div").empty().append(link);
}
$(".hostSuffix").text("." + ts.getHost("").split("//")[1]);
ts.getSpaces(function(spaces) {
$("<div class='info' />").text("You have " + spaces.length + " spaces.").insertBefore($(".spaceSearch")[0]);
$("form.spaceSearch input").autocomplete({
html: true,
source: function(req, response) {
ts.getSpaces(function(spaces) {
var selected = [];
for(var i = 0; i < spaces.length; i++) {
var space = spaces[i];
if(space.name.indexOf(req.term) > -1) {
var host = ts.getHost(space.name) ;
var img = host + "/SiteIcon";
selected.push({
value: space.name,
label: '<a href="' + host + '" target="_parent" class="autocompleteLink"><img src="' + img + '" style="height:24px;width:auto;max-height:24px;max-width:24px;"/>' + space.name + '</a>'
});
}
}
response(selected);
});
},
select: function(event, ui) {
window.top.location = ts.getHost(ui.item.value);
}
});
var $ul = $('.ts-space-search');
$.each(spaces, function(i, space) {
$ul.append($('<li/>').html($('<a/>').attr('href', space.uri)
.text(space.name)));
});
$('form.spaceSearch button').click(function(ev) {
$('.list-container').slideToggle('fast');
ev.preventDefault();
return false;
});
});
});
if(window != window.top) {
$("html").addClass("iframeMode");
$("a").live("click",function(ev) {
$(ev.target).attr("target", "_parent");
});
}
</script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
{{{
createTiddlyButton(parent,text,tooltip,action,className,id,accessKey,attribs)
}}}
The ''createTiddlyButton'' global function renders a link that performs an action when clicked. It takes eight optional parameters:
; parent
: the DOM element where the button will be placed. //(optional)//
; text
: the text displayed as the button's label. //(optional)//
; tooltip
: the text that is displayed when a mouse hovers over the button. //(optional)//
; action
: a function to be executed when the button is clicked. //(optional)//
; className
: the class to apply to the button. //(optional)//
; id
: the button element's id. //(optional)//
; accessKey
: a key that activates the button when typed. //(optional)//
; attribs
: a hash of attributes to be applied to the button element. //(optional)//
If a dom element has a refresh attribute that matches a definition in config.refresher it will run the corresponding refresh functions
by default there are refreshers for "link", [[tiddler|config.refreshers.tiddler]], "content" and "macro"
!Simple Images
{{{
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
}}}
Displays as:
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
!Tooltips for Images
{{{
[img[tooltip|http://wikitext.tiddlyspace.com/fractalveg.jpg]]
}}}
Displays as:
[img[tooltip|http://wikitext.tiddlyspace.com/fractalveg.jpg]]
!Image Links
{{{
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg][http://www.flickr.com/photos/jermy/10134618/]]
}}}
Displays as:
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg][http://www.flickr.com/photos/jermy/10134618/]]
!Floating Images with Text
{{{
[<img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
}}}
[<img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]Displays as.
{{{
@@clear:both;display:block; @@
}}}
Will then clear the float.
@@clear:both;display:block;Like this@@
{{{
[>img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
}}}
[>img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]Displays as.@@clear:both;display:block; @@
!See Also
[[Image Macro]]
TiddlyWiki's architecture for interacting with servers allows it to be plugged into a wide variety of servers.
This is done through the addition of plugins containing custom server adaptors.
Server adaptors are designed to allow for UseCases like importing tiddlers, loading missing tiddlers on the fly and synchronizing changes with a server.
Separate macros and core extensions implement such features by accessing the facilities provided by server adaptors.
*[[ccTiddly|http://svn.tiddlywiki.org/Trunk/contributors/SimonMcManus/adaptors/ccTiddlyAdaptorPlugin.js]]
* [[ConfabbNotes|http://svn.tiddlywiki.org/Trunk/contributors/PhilHawksworth/adaptors/ConfabbNotesAdaptorPlugin.js]]
* [[Confluence|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/ConfluenceAdaptorPlugin.js]]
* [[DAV|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/DavAdaptorPlugin.js]]
* [[FacebookFriends|http://svn.tiddlywiki.org/Trunk/contributors/SimonMcManus/adaptors/FacebookFriendsAdaptorPlugin.js]]
*[[FacebookNews|http://svn.tiddlywiki.org/Trunk/contributors/SimonMcManus/adaptors/FacebookNewsAdaptorPlugin.js]]
* [[JSP Wiki|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/JSPWikiAdaptorPlugin.js]]
* [[MediaWiki|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/MediaWikiAdaptorPlugin.js]]
* [[RawText|http://svn.tiddlywiki.org/Trunk/association/adaptors/RawTextAdaptor.js]]
* [[RSS|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/adaptors/RSSAdaptor.js]]
*[[Socialtext|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/SocialtextAdaptorPlugin.js]]
* [[Synchrotron|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/synchrotronAdaptorPlugin.js]]
*[[TiddlyWeb|https://github.com/tiddlyweb/tiddlywebwikiclient]]
* [[Trac|http://svn.tiddlywiki.org/Trunk/contributors/FND/adaptors/TracAdaptor.js]]
* [[TWiki|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/TWikiAdaptorPlugin.js]]
* [[Twitter|http://svn.tiddlywiki.org/Trunk/contributors/FND/adaptors/TwitterAdaptor.js]]
* [[WikispacesSOAP|http://svn.tiddlywiki.org/Trunk/contributors/SaqImtiaz/verticals/POLS250/common/plugins/WikispacesSoapAdaptorPlugin.js]]
* [[Wordpress|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/WordpressAdaptorPlugin.js]]
*[[ZiddlyWiki|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/WordpressAdaptorPlugin.js]]
!!See Also
* [[ServerAdaptorMechanism]]
The GettingStarted shadow tiddler contains information about how to start using your TiddlyWiki.
You can change it to include anything you desire.
For example a lot of tiddlywiki authors use it to explain what their wiki is about. This is a particularly useful approach because by default the GettingStarted tiddler is in the [[DefaultTiddlers|Shadow - DefaultTiddlers]] tiddler, thus opens automatically upon loading of the page.
By default it is also part of the [[MainMenu|Shadow - MainMenu]] tiddler so is included on the left side of the menu bar above.
/***
|''Name''|TiddlyTagCloudPlugin|
|''Author''|Jon Robson|
|''Version''|0.3.11|
!Usage
{{{ <<tagcloud>> }}} creates a tag cloud of all content.
!Parameters
exclude: name a tag you want to exclude from the tag cloud.
filter: provide a filter to run the tag cloud on a subset of tiddlers see SiteInfo@filters and [[filters syntax]]@docs
threshold:2 - will ignore any tags that occur less than 2 times.
sortOrder: <-,+,""> - sort the resulting tags in descending, ascending or no order
***/
//{{{
(function($) {
var stylesheet = "StyleSheetTagCloud";
config.shadowTiddlers[stylesheet] = ['.tagcloudTag { display: inline-block; border : none; margin-right: 8px; '].join("\n");
store.addNotification(stylesheet, refreshStyles);
var macro = config.macros.tagcloud = {
locale: {
tooltip: "see the %0 occurrences of %1"
},
cache: {},
options: {
fontSize: {
small: 10,
large: 48,
},
threshold: 1,
sortOrder: "+"
},
_cleanup: function() {
for(var i in macro.cache) {
if($(i).length === 0) {
delete macro.cache[i];
}
}
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var id = "tagcloud"+Math.random();
var container = $("<div />").attr("params", paramString).addClass("tagcloud").
attr("id", id).appendTo(place)[0];
macro.refresh(container);
},
refresh: function(container) {
macro._cleanup();
var tags, tag;
var locale = macro.locale;
var paramString = $(container).attr("params");
var args = paramString.parseParams("anon")[0];
var exclude = args.exclude || [];
var tiddlers = args.filter ? store.filterTiddlers(args.filter[0]) : store.getTiddlers();
var count = {};
var lookup = {};
var options = macro.options;
var threshold = args.threshold ? parseInt(args.threshold[0], 10) : options.threshold;
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
tags = tiddler.tags;
for(var j = 0; j < tags.length; j++) {
tag = tags[j];
if(!exclude.contains(tag)) {
lookup[tag] = lookup[tag] || [];
lookup[tag].push(tiddler);
if(!count[tag]) {
count[tag] = 1;
} else {
count[tag] += 1;
}
}
}
}
tags = [];
var largest, smallest, c;
for(var k in count) {
tags.push(k);
if(count[k] < threshold) {
delete count[k];
}
}
var sort = options.sortOrder;
tags = tags.sort(function(i, j) {
if(sort == "+") {
return i < j ? -1 : 1;
} else if(sort == "-") {
return i < j ? 1 : -1;
} else {
return 0;
}
});
for(var l in count) {
if(true) {
c = count[l];
if(!largest) {
largest = c;
} else if(c > largest) {
largest = c;
}
if(!smallest) {
smallest = c;
} else if(c < smallest) {
smallest = c;
}
}
}
var id = $(container).attr("id");
macro.cache[id] = lookup;
for(var l = 0; l < tags.length; l++) {
var tag = tags[l];
if(true) {
c = count[tag];
if(c) {
var size = macro.determineFontSize({ largest: largest, smallest:smallest, occurrences: c });
var btn = createTagButton(container,"[_tagcloud[%0-:-%1]]".format(id, tag),
null,tag,locale.tooltip.format(c, tag));
$(btn).addClass("tagcloudTag").attr("tag", tag).css({ "font-size": size + "px" }).
addClass("button size%0".format(size)).click(function(ev) {
var tag = $(ev.target).attr("tag");
window.setTimeout(function() {
var items = $(".popup li a");
var lastLink = items[items.length - 1];
$(lastLink).text("Open tag " + tag).attr("tiddlylink", tag);
}, 10);
});
// the last line is rather hacky but gets the required result of making it possible to open the tag
}
}
}
},
determineFontSize: function(args) {
var options = macro.options;
var deltaFontSize = options.fontSize.large - options.fontSize.small;
var delta = args.occurrences / (args.largest - args.smallest + 1);
return options.fontSize.small + parseInt(delta * deltaFontSize, 10);
}
};
config.filters._tagcloud = function(results, match) {
var args = match[3] ? match[3].split("-:-") : false;
if(args) {
var id = args[0];
var lookup = macro.cache[id] || {};
var tag = args[1];
var tiddlers = lookup[tag] || [];
return tiddlers;
} else {
return [];
}
};
})(jQuery);
//}}}
!!TiddlyWiki Assembly
* [[Cook]]
* [[Ginsu|Dev:Ginsu]]
* [[Recipes|Recipe]]
* [[Chef|Dev:Chef]]
* [[r4tw]]
!!Debugging and Testing
* [[Firebug|http://www.getfirebug.com]] (Firefox extension)
ColorPalette
StyleSheet
SiteSubtitle
GettingStarted
SiteTitle
MainMenu
SiteIcon
DefaultTiddlers
ViewTemplate
PageTemplate
SideBarOptions
EditTemplate
SiteInfo
SideBarTabs
ToolbarCommands
Takes two arguments - a tiddler title and a document object. If no document object is given the current document is used.
The tiddler title is also used as a unique identifier for that stylesheet.
It directly calls the [[setStylesheet]] function with the value of the tiddler text of the tiddler title given.
The notifyAll method of a [[TiddlyWiki class|TiddlyWiki]] object runs all notification function currently registered to it via [[addNotification|TiddlyWiki.prototype.addNotification]]. If a notification function was tied to a particular tiddler, it is invoked with that tiddler, as usual, and blanket notifications (registered to the null value) are run as well. This method takes no parameters.
This method is called by the TiddlyWiki code starts up as the page loads, but this is an easy way to force a reload of page title, subtitle, stylesheet, and so on.
/***
|''Name''|TiddlySpaceRevertRevision|
|''Description''|Revert to a previous revision|
|''Author''|BenGillies|
|''Version''|0.1|
|''Status''|unstable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Requires''|TiddlyWebAdaptor TiddlySpaceRevisionView|
!Usage
Add a control button to revert to a particular revision.
The button must be called from within a revision, as generated by TiddlySpaceRevisionView
!Code
***/
//{{{
(function($) {
config.commands.revert = {
text: "revert",
tooltip: "make this revision the current one",
handler: function(ev, src, title) {
var revElem = story.getTiddler(title);
var tidToRevert = store.getTiddler($(revElem).attr("revName"));
var revision = store.getTiddler(title);
if ((revision) && (tidToRevert)) {
tidToRevert.text = revision.text;
var newFields = merge({}, revision.fields);
for (var fieldName in newFields) {
if (fieldName.substr(0, 7) === "server.") {
delete newFields[fieldName];
}
}
merge(tidToRevert.fields, newFields);
tidToRevert.tags = merge([], revision.tags);
tidToRevert.fields.changecount = 1;
delete tidToRevert.fields.doNotSave;
store.saveTiddler(tidToRevert.title, tidToRevert.title,
tidToRevert.text, null, null, tidToRevert.tags,
tidToRevert.fields, false, tidToRevert.created, tidToRevert.creator);
autoSaveChanges(true);
}
}
};
})(jQuery);
//}}}
(function($) {
// mock out HTTP requests
jQuery.ajax = function(options, isCallback) {
if(!isCallback) {
return setTimeout(function() {
$.ajax(options, true);
}, 500);
}
if(options.type != "GET") {
console.log("AJAX", options);
}
var xhr = {
getResponseHeader: function() {}
};
var data;
tiddlyweb.commander.notify("URI: " + options.url);
var path = $.map(options.url.split("/"), function(item, i) {
return decodeURIComponent(item);
});
var resource = path.pop();
var bag, recipe;
switch(resource) {
case "recipes":
data = ["Omega"];
break;
case "bags":
data = ["Alpha", "Bravo", "Charlie", "Delta"];
break;
case "tiddlers":
bag = path[1] == "bags" ? path[2] : "Foxtrot";
recipe = path[1] == "recipes" ? path[2] : undefined;
data = $.map(["Foo", "Bar", "Baz"], function(item, i) {
item = {
title: bag + "::" + item,
bag: bag
};
if(recipe) {
item.recipe = recipe;
}
return item;
});
break;
case "revisions":
var container = {
type: path[1] == "bags" ? "bag" : "recipe",
name: path[2]
};
var revs = Math.random().toString().substr(2).split("");
data = $.map(revs, function(item, i) {
var rand = Math.random();
item = {
title: path[path.length - 1],
revision: Math.floor(rand * 1000 * item + 1)
};
item[container.type] = container.name;
return item;
});
break;
case "status":
data = {
username: "DEV",
challengers: ["N/A"],
version: "mock"
};
break;
default:
var type = path.pop();
switch(type) {
case "recipes":
data = {
desc: "lorem ipsum dolor sit amet",
policy: {
"read": [],
"manage": ["R:ADMIN"],
"owner": "administrator"
},
recipe: [
["Alpha", ""],
["Charlie", "select=tag:foo"],
["Bravo", ""]
]
};
break;
case "bags":
data = {
desc: "lorem ipsum dolor sit amet",
policy: {
"read": [],
"write": ["fnd", "cdent", "psd"],
"create": ["ANY"],
"delete": ["NONE"],
"manage": ["R:ADMIN"],
"accept": ["R:ADMIN"],
"owner": "administrator"
}
};
if(resource == "Bravo") {
data = null;
xhr.status = 401;
}
break;
case "tiddlers":
bag = path[1] == "bags" ? path[2] : "Foxtrot";
recipe = path[1] == "recipes" ? path[2] : undefined;
data = {
title: resource,
text: "lorem ipsum\ndolor sit amet\n\nconsectetur adipisicing elit\nsed do eiusmod tempor",
bag: bag,
created: "20100930160300",
modified: "20100930160530"
};
if(recipe) {
data.recipe = recipe;
}
break;
case "revisions":
data = {
title: path.pop(),
text: "lorem ipsum\ndolor sit amet",
created: "20100929110300",
modified: "20100929110400"
};
break;
}
}
if(data) {
xhr.status = 200;
options.success(data, "success", xhr);
} else {
xhr.statusText = "error";
xhr.responseText = resource + " failed";
options.error(xhr, "error", {});
}
};
})(jQuery);
You can change the title and subtitle of your space, this will be visible to people visiting your space as well as being what is shown the browser tabs. The content these are stored in two tiddlers, clicking on the links below will open up these tiddlers which you can edit to make changes.
* [[SiteTitle]]
* [[SiteSubtitle]]
<html><hr><html>
(function($) {
var host;
var init = function() {
host = getHost("/console");
document.location = document.location.toString().split("#")[0] + "#host:" + host;
// display host in status bar -- TODO: use onhashchange event to update live
var statusBar = $("footer p");
$(".host", statusBar).text(host);
$.getJSON(host + "/status", function(data, status, xhr) {
$(".username", statusBar).text(data.username);
});
var col = new Column("index", ["recipes", "bags", "users", "info"]); // XXX: i18n
col.noSort = true;
col.listType = "ul";
delete col.label;
col.controls = null;
col = col.render().addClass("index").appendTo("nav.pane");
$("li", col).eq(2).find("a").addClass("disabled").unbind("click"); // XXX: hacky?
$("nav li a").live("click", function(ev) { // XXX: breaks encapsulation!?
$(this).blur(). // hack to prevent Firefox from invoking :focus
not(".disabled").closest("li").
siblings().children().removeClass("selected").end().end().
find("a").addClass("selected");
});
$("#btnFullscreen").click(function(ev) {
cmd.toggleFullscreen();
});
$("#btnSave").click(function(ev) {
cmd.saveEntity();
});
};
var errback = function(xhr, error, exc) {
var msg = xhr.statusText + ": " + xhr.responseText;
cmd.notify(msg, "error");
};
var cmd = tiddlyweb.commander = {
addNavColumn: function(node, type, names, items, noSort) {
node.nextAll().remove();
var col = new Column(type, names);
if(items) {
col.data = items;
}
col.noSort = noSort || false;
return col.render().addClass(type).appendTo("nav.pane");
},
toggleFullscreen: function() {
var els = $(".pane:visible");
if(els.length > 2) {
els.slice(0, -2).slideUp(function() { // XXX: executed multiple times
els.eq(-2).css("height", "95%"); // XXX: hardcoded size
});
} else {
$(".pane").slideDown(function() { // XXX: fullscreen pane needs special handling to ensure smooth animation
$(this).removeAttr("style");
});
}
},
saveEntity: function() {
var entity = $(".pane article").data("entity");
var name = entity.name || entity.title; // XXX: hacky (violates encapsulation)
// XXX: notify is a bad feedback pattern (global, non-localized)
var callback = function(data, status, xhr) {
cmd.notify(name + " saved successfully", "info"); // XXX: i18n
};
entity.put(callback, errback);
},
notify: function(msg, type) {
type = type || "info";
var statusBar = $("footer .status").hide();
$("footer .notification").removeClass().addClass("notification").
empty().addClass(type).show().text(msg).unbind("click").
click(function(ev) {
$(this).removeClass(type).empty().hide();
statusBar.show();
});
}
};
var filterList = function(ev) {
var el = $(this);
var filter = el.val().toLowerCase();
el.closest(".column").find("li").each(function(i, item) {
var el = $(this);
if(el.find("a").text().toLowerCase().indexOf(filter) != -1) {
el.slideDown();
} else {
el.slideUp();
}
});
};
var columnActions = { // XXX: rename?
index: function(name, column) { // XXX: rename?
if(name == "bags" || name == "recipes") {
var collection = new tiddlyweb.Collection(name, host);
cmd.addNavColumn(column.node, "pending", ["loading..."]); // XXX: i18n
var callback = function(data, status, xhr) {
cmd.addNavColumn(column.node, name, data);
};
collection.get(callback, errback);
} else if(name == "info") {
$.getJSON(host + "/status", function(data, status, xhr) {
// TODO: templating
var list = $("<dl />");
$("<dt />").text("current user").appendTo(list); // XXX: i18n
$("<dd />").text(data.username).appendTo(list); // XXX: i18n
$("<dt />").text("server version").appendTo(list); // XXX: i18n
$("<dd />").text(data.version).appendTo(list); // XXX: i18n
$(".pane article").empty().append(list); // XXX: selector too unspecific?!
});
}
},
recipes: function(name, column) {
var recipe = new tiddlyweb.Recipe(name, host);
var eCallback = function(recipe, status, xhr) {
recipe.render().replaceAll(".pane article"); // XXX: selector too unspecific?!
};
recipe.get(eCallback, errback);
cmd.addNavColumn(column.node, "pending", ["loading..."]); // XXX: i18n
var cCallback = function(data, status, xhr) {
var titles = $.map(data, function(item, i) {
return item.title;
});
cmd.addNavColumn(column.node, "tiddlers", titles, data);
};
recipe.tiddlers().get(cCallback, errback);
},
bags: function(name, column) { // TODO: DRY (cf. recipes)
var bag = new tiddlyweb.Bag(name, host);
var eCallback = function(bag, status, xhr) {
bag.render().replaceAll(".pane article"); // XXX: selector too unspecific?!
};
var eErrback = function(xhr, error, exc) {
if(xhr.status == 401) {
bag.desc = "unauthorized"; // XXX: i18n -- XXX: hacky?
delete bag.policy;
bag.render().replaceAll(".pane article").addClass("error"); // XXX: selector too unspecific?!
} else {
errback.apply(this, arguments);
}
};
bag.get(eCallback, eErrback);
cmd.addNavColumn(column.node, "pending", ["loading..."]); // XXX: i18n
var cCallback = function(data, status, xhr) {
var titles = $.map(data, function(item, i) {
return item.title;
});
cmd.addNavColumn(column.node, "tiddlers", titles, data);
};
bag.tiddlers().get(cCallback, errback);
},
tiddlers: function(name, column) {
var tid;
$.each(column.data, function(i, item) { // XXX: inefficient
tid = item;
return tid.title != name;
});
var eCallback = function(tid, status, xhr) {
tid.render().replaceAll(".pane article"); // XXX: selector too unspecific?!
};
tid.get(eCallback, errback);
cmd.addNavColumn(column.node, "pending", ["loading..."]); // XXX: i18n
var cCallback = function(data, status, xhr) {
var names = $.map(data, function(item, i) {
return item.revision;
});
cmd.addNavColumn(column.node, "revisions", names, data, true);
};
tid.revisions().get(cCallback, errback);
},
revisions: function(name, column) { // TODO: DRY (cf. tiddlers)
var tid;
$.each(column.data, function(i, item) { // XXX: inefficient
tid = item;
return tid.revision != name;
});
var rev = new tiddlyweb.Revision(tid.revision, tid);
var callback = function(tid, status, xhr) {
tid.render().replaceAll(".pane article"); // XXX: selector too unspecific?!
};
rev.get(callback, errback);
}
};
var Column = function(type, items) {
this.type = type;
this.label = tiddlyweb._capitalize(type); // XXX: hacky?
this.listType = "ol";
this.items = items;
var self = this;
this.onClick = function(ev) {
var name = $(this).text(); // XXX: brittle (e.g. i18n)
columnActions[type].apply(this, [name, self]);
};
};
Column.prototype.controls = $('<input type="search" placeholder="filter" />'). // XXX: i18n
change(filterList).keyup(function(ev) {
var filter = $(this).val();
if(filter.length > 2) {
clearTimeout(this.timeout || null);
var self = this;
this.timeout = setTimeout(function() {
filterList.apply(self, []);
}, 500);
}
});
Column.prototype.render = function() {
var heading = this.label ? $("<h3 />").text(this.label) : null;
var controls = this.controls ? this.controls.clone(true) : null;
this.node = $('<section class="column" />').append(heading).append(controls);
var items = this.noSort ? this.items : this.items.sort(function(a, b) { // XXX: inefficient!?
var x = a.toLowerCase ? a.toLowerCase() : a;
var y = b.toLowerCase ? b.toLowerCase() : b;
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
var self = this;
$("<" + this.listType + " />").
append($.map(this.items, function(item, i) {
var btn = $('<a href="javascript:;" />').text(item).
click(self.onClick);
return $("<li />").append(btn)[0];
})).
appendTo(this.node);
return this.node;
};
var getHost = function(cue) {
var prefix = "host:";
var loc = document.location;
var host = loc.hash.split(prefix);
host.shift();
host = host.join(prefix);
var uri;
if(host) {
uri = host.replace(/\/$/, "");
} else if(loc.protocol == "file:") {
uri = "";
} else {
uri = loc.protocol + "//" + loc.hostname;
if(loc.port && $.inArray(loc.port, ["80", "443"]) == -1) {
uri += ":" + loc.port;
}
var path = loc.pathname.indexOf(cue) != -1 ? loc.pathname.split(cue)[0] : "/";
uri += path;
}
return uri.replace(/\/$/, "");
};
init();
})(jQuery);
A Bag is the TiddlyWeb name for a collection of uniquely named [[tiddlers|Tiddler]]. A TiddlySpace [[space|Space]] has a pair of [[Public]] and [[Private]] bags. Each bag has a separate [[Policy]] for [[Access Control]] by [[Users|User]]. A bag may also have a description field, typically containing text stating the purpose of the bag. A [[User]] may create additional bags for a [[space|Space]] and manage the Policy bags through the [[TiddlySpace API]].
The SiteInfo tiddler is a special [[tiddler|Tiddler]] called SiteInfo which provides a public description on a [[space|Space]]. This description can just be text or can also include tags and [[extended fields|Custom Fields]]. It is designed to describe a space to a newcomer and to be used by plugins.
The idea behind its conception was first discussed [[here|http://groups.google.com/group/tiddlyweb/browse_thread/thread/34e6ac1ef870c7e6]].
<!DOCTYPE html>
<html manifest="/bags/common/tiddlers/takenote_manifest.appcache">
<head>
<title>takenote</title>
<link rel="stylesheet" href="/bags/common/tiddlers/notabene.css" />
<link rel="apple-touch-icon" href="/bags/common/tiddlers/touchicon_takenote.png"/>
<link rel="apple-touch-icon-precomposed" href="/bags/common/tiddlers/touchicon_takenote.png"/>
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=0,initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes" />
</head>
<body>
<ul id="backstage">
<!-- no not add a newline between li elements or you will get a margin with inline blocks -->
<li><a href="/dashboard">dashboard</a></li><li><a href="/takenote">takenote</a></li>
<li><a class='connectionStatus'></a></li>
</ul>
<div class="takenotecontainer">
<div class='messageArea'></div>
<div id="note">
<div class="toolbar">
<a id="cancelnote" title="cancel this note">cancel</a>
<a id="deletenote" title="delete this note">delete</a>
<a id="newnote" title="complete this note">complete</a>
</div>
<div class="note_title_container">
<textarea class="note_title" placeholder="Note Title"></textarea>
</div>
<div id="notebody">
<span class="notedate"></span>
<textarea class="note_text" placeholder="Write here..."></textarea>
</div>
<div id="tips">
<div>Tips for cleverer notes:
''<span class="boldTip">bold</span>'' //<span class="italicTip">italic</span>// _<span class="underlineTip">underline</span>_ #tag</div>
<div>[[<a href="http://tiddlyspace.com">Link Name</a>|http://tiddlyspace.com]]
[[<a href="/Note title">Note title</a>]] <span class="imageTip">[img[/SiteIcon<img src="/SiteIcon" />]]</span></div>
</div>
<div id="notemeta"></div>
<div style="display:none">
<a class="syncButton"></a>
</div>
</div>
</div>
<noscript>
Takenote requires javascript to work correctly. Sorry!
</noscript>
<script src="/bags/common/tiddlers/backstage.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/bookmark_bubble.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/tiddlyspace/tiddlers/chrjs" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/chrjs-store.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/jquery-json.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/notabene.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
var takenote;
takenote = notes($(".takenotecontainer")[0], {
host: "/"
});
</script>
</body>
</html>
[[r4tw|http://simonbaird.com/r4tw/]] is a collection of Ruby classes for manipulating [[TiddlyWiki]] files.
[[tiddlywiki_cp|http://rubyforge.org/projects/tiddlywikicp/]] is a Ruby gem based on ''r4tw'', providing a library and command-line interface to create tiddlers from files and vice versa.
!!See Also
* [[Dev:PyTiddlyWiki]]
!Wiki Links
Any words or phrases that are CamelCase or compound words - in which the elements are joined without spaces - will result in them becoming links to tiddlers with that name.
For example,
{{{
WikiWord
}}}
Displays as:
WikiWord
To stop this happening the words must be escaped:
{{{
~WikiWord
}}}
Displays as:
~WikiWord
Alternatively, a tiddler can be linked to using square brackets to encompass the whole tiddler title:
{{{
[[tiddler name]]
}}}
!Pretty Links
Optionally, custom text can be added, separated by a pipe character (|)
{{{
[[alternative link text|tiddler name]]
}}}
Displays as:
[[link to our WikiWords tiddler|WikiWords]]
!External Links
Writing the URL in the text results in a link to that external site:
{{{
http://osmosoft.com
}}}
Displays as:
http://osmosoft.com
Similar to pretty links alternative text can be used to link to external sites:
{{{
[[Visit the Osmosoft site|http://osmosoft.com]]
}}}
Displays as:
[[Visit the Osmosoft site|http://osmosoft.com]]
!Links to Other Spaces
Link to a space by preceding it with {{{@}}}:
{{{
@about
}}}
Displays as:
@about
Suppress space linking with {{{~}}}:
{{{
~@about
}}}
~@about
Link to a tiddler within another space:
{{{
TiddlyWiki@glossary
[[TiddlySpace API]]@glossary
[[Information about the HTTP interface|TiddlySpace API]]@glossary
}}}
Displays as:
TiddlyWiki@glossary
[[TiddlySpace API]]@glossary
[[Information about the HTTP interface|TiddlySpace API]]@glossary
/***
|''Name''|TiddlySpaceBackstage|
|''Version''|0.8.0|
|''Description''|Provides a TiddlySpace version of the backstage and a homeLink macro|
|''Status''|@@beta@@|
|''Contributors''|Jon Lister, Jon Robson, Colm Britton|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceBackstage.js|
|''Requires''|TiddlySpaceConfig ImageMacroPlugin TiddlySpaceViewTypes|
!StyleSheet
.publicLightText {
color: #C0E5FC;
}
.privateLightText {
color: #E2C1D6;
}
.tiddler .error.annotation .button{
display: inline-block;
}
#backstageArea #backstageToolbar a.task_tiddlyspace {
margin: 0px auto auto -75px;
font-weight: bold;
width: 150px;
line-height:24px;
font-size: 1.2em;
padding: 0;
top: 0;
position: absolute;
left: 50%;
}
.task_tiddlyspace .image,
.task_tiddlyspace .svgIcon {
display: inline;
}
.task_tiddlyspace .svgIconText {
display: none;
}
.task_tiddlyspace .logoText {
position: absolute;
top: 0px;
margin-left: 5px;
}
#backstageArea {
z-index: 49;
color: white;
background-color: black;
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #222),color-stop(0.5, #333),color-stop(1, #555));
background: -moz-linear-gradient(center bottom,#222 0%, #333 50%, #555 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222)";
height: 25px;
padding: 0;
}
.backstageBackground {
fill: black;
}
#backstageButton {
overflow: hidden;
}
#backstageButton #backstageShow,
#backstageButton #backstageHide {
margin: 0px;
padding: 0px;
}
#backstageButton #backstageShow:hover,
#backstageButton #backstageHide:hover {
background: none;
color: none;
}
#backstageButton img,
#backstageButton svg {
width: 24px;
height: 24px;
}
#messageArea {
top: 50px;
}
#backstageToolbar {
position: relative;
}
#backstageArea a {
padding: 0px;
margin-left: 0px;
color: white;
background: none;
}
#backstageArea a:hover {
background-color: white;
}
#backstage .tabContents ol,
#backstage .tabContents ul {
padding: auto;
}
#backstageButton a {
margin: 0;
}
.backstagePanelBody .tabContents ul {
padding: 5px;
margin: 5px;
}
#backstage #backstagePanel {
margin-left: 5%;
padding: 0em;
margin-right: 5%;
text-align: center;
}
#backstageToolbar a {
position: relative;
}
#backstageArea a.backstageSelTab,
#backstageToolbar .backstageTask {
line-height: 25px;
color: #767676;
}
.backstageTask .externalImage,
.backstageTask .image {
display: inline;
}
.backstageTask .txtUserName,
.backstageTask .spaceName {
color: #fff;
}
.backstageSelTab .txtUserName,
.backstageSelTab .spaceName,
a:hover .txtUserName,
a:hover .spaceName {
color: #000;
}
.spaceSiteIcon {
margin-right: 10px;
}
.userSiteIcon {
margin-left: 10px;
}
#backstageToolbar .task_space {
position: absolute;
top: 0px;
left: 0%;
}
#backstageToolbar .task_user,
#backstageToolbar .task_login {
display: block;
position: absolute;
top: 0px;
right: 5%;
}
#backstageToolbar .task_login img {
position: relative;
display: inline;
}
#backstageToolbar .task_login img,
#backstageToolbar .task_user img {
float: right;
}
#backstageToolbar .task_space .svgIcon {
float: left;
position: relative;
z-index: 2;
}
#backstageToolbar a span {
z-index: 2;
}
#backstageToolbar .spaceSiteIcon {
float: left;
}
a.backstageTask {
display: block;
}
#backstageToolbar a span.txtUserName,
#backstageToolbar a .txtUserName span {
display: inline;
float: none;
}
#backstage .deleteButton {
margin-left: 0.3em;
font-weight: bold;
color: red;
font-size: 1.6em;
}
#backstage .deleteButton:hover {
background: none;
}
#backstageArea .siteIcon {
display: inline;
}
#backstagePanel .TiddlySpaceLogin {
display: inline;
}
.backstagePanelBody .tabContents .button {
display: inline-block;
margin-right: 10px;
}
.backstagePanelBody .tab {
margin: 0 0 0 0.6em;
padding: 0.4em 0.5em 1px 0.5em;
}
#backstage .tabContents {
padding: 1.5em;
text-align: left;
}
#backstage table {
margin: auto;
}
#backstage .wizard table {
border: 0px;
margin: 0;
}
#backstage .txtSpaceTab li {
border: 1px solid #ddd;
background: #eee;
list-style: none;
margin: 0.5em;
padding: 0.5em;
width: 80%;
}
#backstage .txtSpaceTab li.annotation {
border: 2px solid [[ColorPalette::SecondaryMid]];
}
#backstage div li.listLink {
border: 0px;
width: 78%;
font-size: 0.7em;
}
#backstage div li.listTitle {
font-weight: bold;
text-decoration: underline;
font-size: 1em;
background: #ccc;
width: 100%;
}
#backstage div.txtSpaceTab li .deleteButton {
float: right;
}
#backstage fieldset {
border: solid 1px [[ColorPalette::Background]];
}
#backstage .viewer table,#backstage table.twtable {
border: 0px;
}
#backstageToolbar img {
padding: 0;
}
#backstage .wizard,
#backstage .wizardFooter {
background: none;
}
.viewer td, .viewer tr, .twtable td, .twtable tr {
border: 1px solid #eee;
}
#backstage .inlineList ul li {
background-color: [[ColorPalette::Background]];
border: solid 1px [[ColorPalette::TertiaryMid]];
display: block;
float: left;
list-style: none;
margin-right: 1em;
padding: 0.5em;
}
.backstageClear, .inlineList form {
clear: both;
display: block;
margin-top: 3em;
}
.tiddlyspaceMenu {
text-align: center;
}
span.chunkyButton {
display: inline-block;
padding: 0;
margin: 0;
border: solid 2px #000;
background-color: #04b;
}
span.chunkyButton a.button, span.chunkyButton a:active.button {
white-space: nowrap;
font-weight: bold;
font-size: 1.8em;
color: #fff;
text-align: center;
padding: 0.5em 0.5em;
margin: 0;
border-style: none;
display: block;
}
span.chunkyButton:hover {
background-color: #014;
}
span.chunkyButton a.button:hover {
border-style: none;
background: none;
color: #fff;
}
a.baskstageTask.task_login,
a.baskstageTask.task_user {
_width: 200px;
_text-align: right;
}
#backstageArea #backstageToolbar .task_login img,
#backstageArea #backstageToolbar .task_user img {
_display: inline;
_float: none;
}
#backstage .unpluggedSpaceTab .wizard,
.unpluggedSpaceTab .wizard {
background: white;
border: 2px solid #CCC;
padding: 5px;
}
.syncKey .keyItem {
border: 1px solid black;
display: inline-block;
margin: 0.2em;
padding: 0.1em 0.1em 0.1em 0.1em;
}
.keyHeading {
font-size: 2em;
font-weight: bold;
margin: 0.4em 0em -0.2em;
}
.unpluggedSpaceTab .putToServer,
.unpluggedSpaceTab .notChanged {
display: none;
}
.tiddlyspaceMenu ul {
margin: 0;
padding: 0;
}
.tiddlyspaceMenu ul li {
list-style: none;
}
.unsyncedChanges .unsyncedList {
display: block;
}
.unsyncedList {
display: none;
}
#backstage iframe {
height: 600px;
width: 100%;
border: none;
}
!Code
***/
//{{{
(function($) {
var name = "StyleSheet" + tiddler.title;
config.shadowTiddlers[name] = "/*{{{*/\n%0\n/*}}}*/".
format(store.getTiddlerText(tiddler.title + "##StyleSheet")); // this accesses the StyleSheet section of the current tiddler (the plugin that contains it)
store.addNotification(name, refreshStyles);
if(!config.extensions.tiddlyweb.status.tiddlyspace_version) { // unplugged
config.extensions.tiddlyweb.status.tiddlyspace_version = "<unknown>";
config.extensions.tiddlyweb.status.server_host = {
url: config.extensions.tiddlyweb.host }; // TiddlySpaceLinkPlugin expects this
}
var disabled_tabs_for_nonmembers = ["PluginManager", "Backstage##FileImport",
"Backstage##BatchOps", "Backstage##SpaceMembers",
"TiddlySpaceTabs##Private", "TiddlySpaceTabs##Drafts"];
var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
var imageMacro = config.macros.image;
if(config.options.chkBackstage === undefined) {
config.options.chkBackstage = true;
}
config.tasks.user = {
text: "user: ",
tooltip: "user control panel",
unpluggedText: "unplugged user",
content: "<html><iframe frameBorder='0' src='" + config.extensions.tiddlyweb.host + "/_account'></iframe></html>"
};
config.tasks.space = {
text: "space: ",
tooltip: "space control panel",
className: "right"
};
config.tasks.tiddlyspace = {
text: "",
tooltip: "",
content: "<<tiddler Backstage##Menu>>"
};
if(window.location.protocol == "file:") {
config.unplugged = true; // TODO: move into extensions.tiddly{web/space} namespace!?
config.tasks.space.content = "<<tiddler Backstage##SpaceUnplugged>>";
} else {
config.tasks.space.content = "<html><iframe frameBorder='0' src='/_space'></iframe></html>";
}
config.backstageTasks = ["tiddlyspace", "user", "space"];
config.messages.backstage.prompt = "";
// initialize state
var _show = backstage.show;
backstage.show = function() {
// selectively hide backstage tasks and tabs based on user status
var tasks = $("#backstageToolbar .backstageTask").show();
if(!config.unplugged) {
tweb.getUserInfo(function(user) {
if(user.anon) {
$(".task_user", tasks).hide();
tiddlyspace.disableTab(disabled_tabs_for_nonmembers);
} else {
$(".task_login", tasks).hide();
}
});
}
// display backstage
return _show.apply(this, arguments);
};
if(readOnly) {
tiddlyspace.disableTab(disabled_tabs_for_nonmembers);
}
var tasks = config.tasks;
var commonUrl = "/bags/common/tiddlers/%0";
// mock out renderAvatar if unavailable -- XXX: temporary hotfix, not a permanent solution!
tiddlyspace.renderAvatar = tiddlyspace.renderAvatar || function() {};
backstage.tiddlyspace = {
locale: {
member: "You are a member of this space.",
nonmember: "You are not a member of this space.",
loggedout: "You are currently logged out of TiddlySpace.",
unplugged: "You are unplugged."
},
checkSyncStatus: function(tiddler) {
var bs = backstage.tiddlyspace;
var t = store.filterTiddlers("[is[unsynced]]");
var unsyncedList = $("#backstage .tiddlyspaceMenu .unsyncedList");
if(t.length > 0 && !readOnly) {
bs.tweakMiddleButton("unsyncedIcon");
$("#backstage").addClass("unsyncedChanges");
} else {
bs.tweakMiddleButton();
$("#backstage").removeClass("unsyncedChanges");
}
refreshElements($("#backstage")[0]);
if(tiddler) {
var title = typeof(tiddler) === "string" ? tiddler : tiddler.title;
var el = story.getTiddler(title) || false;
if(el) {
refreshElements(el);
}
}
},
userButton: function(backstageArea, user) {
// override user button (logged in) to show username
var userBtn = $("[task=user]", backstageArea).empty();
if(config.unplugged && user.anon) {
$("<span />").text(tasks.user.unpluggedText).appendTo(userBtn);
} else if(!config.unplugged && user.anon) {
userBtn.remove();
} else {
$("<span />").text(tasks.user.text).appendTo(userBtn);
$("<span />").addClass("txtUserName").text(user.name).appendTo(userBtn);
var container = $("<span />").appendTo(userBtn)[0];
tiddlyspace.renderAvatar(container, user.name,
{ imageOptions: { imageClass:"userSiteIcon", height: 24, width: 24 },
labelOptions: { include: false } });
}
},
showButton: function() {
var showBtn = $("#backstageShow")[0];
var altText = $(showBtn).text();
$(showBtn).empty();
imageMacro.renderImage(showBtn, "backstage.svg",
{ altImage: commonUrl.format("backstage.png"), alt: altText});
},
hideButton: function() {
var hideBtn = $("#backstageHide")[0];
altText = $(hideBtn).text();
$(hideBtn).empty();
imageMacro.renderImage(hideBtn, "close.svg",
{ altImage: commonUrl.format("close.png"), alt: altText, width: 24, height: 24 });
},
middleButton: function(backstageArea, user) {
var bs = backstage.tiddlyspace;
var backstageToolbar = $("#backstageToolbar", backstageArea)[0];
if(config.unplugged) {
config.messages.memberStatus = bs.locale.unplugged;
} else if(!user.anon) {
config.messages.memberStatus = readOnly ? bs.locale.nonmember : bs.locale.member;
} else {
config.messages.memberStatus = bs.locale.loggedout;
}
// construct the tiddlyspace logo
var backstageLogo = $("#[task=tiddlyspace]").empty()[0];
$("<span />").addClass("iconContainer").appendTo(backstageLogo);
$('<span class="logoText"><span class="privateLightText">tiddly</span>' +
'<span class="publicLightText">space</span></span>').
appendTo(backstageLogo);
bs.tweakMiddleButton();
},
tweakMiddleButton: function(iconName) {
var backstageLogo = $("#[task=tiddlyspace] .iconContainer").empty()[0];
var backstageToolbar = $("#backstageToolbar");
var plugin = backstage.tiddlyspace;
if(!iconName) {
iconName = readOnly ? "publicIcon" : "privateAndPublicIcon";
}
config.macros.image.renderImage(backstageLogo, iconName, { width: 24, height: 24 });
},
spaceButton: function(backstageArea, user) {
// override space button to show SiteIcon
var btn = $("[task=space]", backstageArea).show();
if(user && user.anon && config.unplugged) {
btn.hide();
return;
}
btn.empty();
tiddlyspace.renderAvatar(btn[0], currentSpace,
{ imageOptions: { imageClass:"spaceSiteIcon", height: 24, width: 24 },
labelOptions: { include: false } });
$("<span />").text(tasks.space.text).appendTo(btn);
$("<span />").addClass("spaceName").text(currentSpace).appendTo(btn);
},
addClasses: function(backstageArea) {
var tasks = $(".backstageTask", backstageArea);
for(var i = 0; i < tasks.length; i++) {
var btn = $(tasks[i]);
var taskName = btn.attr("task");
btn.addClass("task_%0".format(taskName));
}
}
};
var _init = backstage.init;
backstage.init = function() {
_init.apply(this, arguments);
var init = function(user) {
var backstageArea = $("#backstageArea")[0];
var bs = backstage.tiddlyspace;
store.addNotification(null, bs.checkSyncStatus);
bs.userButton(backstageArea, user);
bs.showButton();
bs.hideButton();
bs.middleButton(backstageArea, user);
bs.spaceButton(backstageArea, user);
bs.addClasses(backstageArea); // for IE styling purposes
bs.checkSyncStatus();
};
tweb.getUserInfo(init);
};
var home = config.macros.homeLink = {
locale: {
linkText: "your home space"
},
handler: function(place) {
var container = $("<span />").appendTo(place)[0];
tweb.getUserInfo(function(user) {
if(!user.anon && user.name != currentSpace) {
createSpaceLink(container, user.name, null, home.locale.linkText);
}
});
}
};
config.macros.exportSpace = {
handler: function(place, macroName, params) {
var filename = params[0] ||
"/tiddlers.wiki?download=%0.html".format(currentSpace);
$('<a class="button">download</a>'). // XXX: i18n
attr("href", filename).appendTo(place);
}
};
$.extend(config.messages, {
syncExplanation: "You are currently viewing an offline version of this TiddlySpace. From here you can sync your offline copy with the online version.",
syncListHeading: "Unsaved tiddlers listed below"});
config.extensions.ServerSideSavingPlugin.reportSuccess = function(msg, tiddler) {
backstage.tiddlyspace.checkSyncStatus(tiddler);
msg = config.extensions.ServerSideSavingPlugin.locale[msg];
var link = "/" + encodeURIComponent(tiddler.title);
displayMessage(msg.format([tiddler.title]), link);
};
})(jQuery);
//}}}
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
Type the text for 'Read-Only_Mode'
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
/***
|''Name''|ImageMacroPlugin|
|''Version''|0.9.4|
|''Description''|Allows the rendering of svg images in a TiddlyWiki|
|''Author''|Osmosoft|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Notes''|Currently only works in modern browsers (not IE)|
|''Requires''|BinaryTiddlersPlugin|
!Usage
{{{<<image SVG>>}}} will render the text of the tiddler with title SVG as an SVG image (but not in ie where it will fail silently)
!!Parameters
width/height: specify width/height parameters
link: make the image link to a given location
tiddlyLink: link to a tiddler
!Notes
Binary tiddlers in TiddlyWeb when passed through the wikifier will be shown as images.
eg. {{{<<view text wikified>>}}} on a binary tiddler will show the image.
{{{<<view fieldname image>>}}}
will render the value of the tiddler field 'fieldname' as an image. This field can contain a tid
{{{<<image SiteIcon>>}}}
will create an image tag where the tiddler has content type beginning image and not ending +xml
will attempt to create svg object in other scenarios
{{{<<image /photos/x.jpg>>}}}
will create an image tag with src /photos/x.jpg as long as there is not a tiddler called /photos/x.jpg in
which case it will render that tiddler as an image. Note for the case of svg files it will attempt to render as an svg if possible via the image
tag. It doesn't embed the svg in the dom for security reasons as svg code can contain javascript.
!Code
***/
//{{{
(function($) {
var macro = config.macros.image = {
shim: "/bags/common/tiddlers/shim",
ieVersion: config.browser.isIE ? parseInt(config.browser.ieVersion[1], 10) : false,
svgns: "http://www.w3.org/2000/svg",
xlinkns: "http://www.w3.org/1999/xlink",
svgAvailable: document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
_fixPrefix: 1,
_external_cache: {},
_image_tag_cache: {},
_image_dimensions: {},
locale: {
badImage: "This image cannot be displayed."
},
handler: function(place, macroName, params, wikifier, paramString, tiddler){
var imageSource = params[0];
// collect named arguments
var args = macro.getArguments(paramString, params);
this.renderImage(place, imageSource, args);
},
init: function() {
var startupImages = store.getTaggedTiddlers("systemImage");
var place = $("<div />").attr("id", "systemImageArea").appendTo("body").hide()[0];
for(var i = 0; i < startupImages.length; i++) {
var image = startupImages[i];
macro.renderImage(place, image.title, { idPrefix: "" });
}
var data = new Image();
data.onload = function() {
// note ie 8 only supports data uris up to 32k so cannot be relied on
macro.supportsDataUris = this.width != 1 || this.height != 1 ? false : true;
macro.supportsDataUris = macro.ieVersion && macro.ieVersion < 9 ? false : macro.supportsDataUris;
};
data.onerror = data.onload;
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
},
refreshImage: function(src) {
var elements = macro._image_tag_cache[src] ? macro._image_tag_cache[src] : [];
if(macro._image_dimensions[src]) {
macro._image_dimensions[src] = false;
}
for(var i = 0; i < elements.length; i++) {
var el = $(elements[i]);
var newSrc = "%0?nocache=%1".format(src, Math.random());
el.attr("src", newSrc); // force reload
}
},
isBinaryImageType: function(contentType) {
return (contentType && contentType.indexOf("image") === 0 &&
contentType.indexOf("+xml") != contentType.length - 4) ? true : false;
},
isImageTiddler: function(tiddler) {
return macro.isSVGTiddler(tiddler) || macro.isBinaryImageTiddler(tiddler);
},
isSVGTiddler: function(tiddler) {
var type = tiddler ? tiddler.fields['server.content-type'] : false;
return type == "image/svg+xml";
},
isBinaryImageTiddler: function(tiddler) {
return macro.isBinaryImageType(tiddler.fields['server.content-type']);
},
renderImage: function(place, imageSource, options) {
var imageTiddler = store.getTiddler(imageSource);
var container;
var classes = ["image"];
if(options.link) {
classes = classes.concat(["imageLink", "externalLink"]);
container = $("<a />").attr("href", options.link).appendTo(place)[0];
} else if(options.tiddlyLink) {
classes.push("imageLink");
container = createTiddlyLink(place, options.tiddlyLink, false);
} else {
container = $("<span />").appendTo(place)[0];
}
$(container).addClass(classes.join(" "));
options = options ? options : {};
if(imageTiddler && macro.isBinaryImageTiddler(imageTiddler)) { // handle the case where we have an image url
return macro._renderBinaryImageTiddler(container, imageTiddler, options);
} else if(imageTiddler){ // handle the case where we have a tiddler
return macro._renderSVGTiddler(container, imageTiddler, options);
} else { // we have a string representing a url
return macro._renderBinaryImageUrl(container, imageSource, options);
}
},
_renderAlternateText: function(container, options) {
var img;
var src = options.src || "";
if(options.width && options.height) {
img = $("<img />").attr("src", src).addClass("svgImageText").attr("width", options.width).
attr("height", options.height).appendTo(container);
}
var alt = options.alt;
if(img && alt) {
img.attr("alt", alt).attr("title", alt);
} else if(alt) {
$(container).addClass("svgImageText").text(alt);
}
macro._image_tag_cache[src] = img;
},
_renderSVGTiddler: function(place, tiddler, options) {
if(!options) {
options = {};
}
merge(options, { tiddler: tiddler, fix: true});
if(macro.svgAvailable) {
this._importSVG(place, options); // display the svg
} else if(options.altImage) {
var image = options.altImage;
delete options.altImage;
this._renderBinaryImageUrl(place, image, options);
} else {
this._renderAlternateText(place, options); // instead of showing the image show the alternate text.
}
},
_renderBinaryImageTiddler: function(place, tiddler, options) {
var resourceURI;
var fields = tiddler.fields;
if(fields["server.type"] == "tiddlyweb") { // construct an accurate url for the resource
resourceURI = "%0/%1/tiddlers/%2".format(config.defaultCustomFields["server.host"],
fields["server.workspace"], encodeURI(fields["server.title"]));
} else { // guess the url for the resource
resourceURI = tiddler.title;
}
var ctype = fields["server.content-type"] || tiddler.type;
var text = tiddler.text;
if(macro.supportsDataUris && ctype && text.indexOf("<html") == -1) {
var uri = "data:%0;base64,%1".format(ctype, text);
options.src = resourceURI;
return macro._renderBinaryImageUrl(place, uri, options);
} else if(options.src) {
return macro._renderBinaryImageUrl(place, options.src, options);
} else {
return macro._renderBinaryImageUrl(place, resourceURI, options);
}
},
_renderImageTag: function(container, src, width, height, options) {
var img;
img = $("<img />").appendTo(container);
if(height) {
img.attr("height", height);
}
if(width) {
img.attr("width", width);
}
if(macro.ieVersion && macro.ieVersion < 7 && macro.shim && options.ie6png) {
$(img).css({width: userW, height: userH,
filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%0', sizingMethod='scale')".format(src)
}).attr("src", macro.shim);
} else {
img.attr("src", src);
}
if(!macro._image_tag_cache[options.srcUrl]) {
macro._image_tag_cache[options.srcUrl] = [];
}
img = $(img).addClass(options.imageClass)[0];
macro._image_tag_cache[options.srcUrl].push(img);
return img;
},
_getDimensions: function(realDimensions, reqDimensions, preserve) {
var w = realDimensions.width;
var h = realDimensions.height;
var reqh = reqDimensions.height;
var reqw = reqDimensions.width;
var finalw = w, finalh = h;
var ratiow = reqw / w, ratioh = reqh / h;
var scaledw = ratioh * w;
var scaledh = ratiow * h;
if(!reqw && reqh) {
finalw = scaledw;
finalh = reqh;
} else if(reqw && !reqh) {
finalw = reqw;
finalh = scaledh;
} else if(reqh && reqw) {
var preserveWidth = w > h ? true : false;
if(preserve) {
if(preserveWidth && scaledh < reqh) {
finalh = scaledh;
finalw = reqw;
} else {
finalh = reqh;
finalw = scaledw;
}
} else {
finalw = reqw;
finalh = reqh;
}
}
return { width: parseInt(finalw, 10), height: parseInt(finalh, 10) };
},
_renderBinaryImageUrl: function(container, src, options) {
var srcUrl = options.src ? options.src : src;
srcUrl = srcUrl.indexOf("/") === -1 ? "/%0".format(srcUrl) : srcUrl; // for IE.
var image_dimensions = macro._image_dimensions[srcUrl];
var image = new Image(); // due to weird scaling issues where you use just a width or just a height
var createImageTag = function(dimensions, error) {
if(error) {
var altImage = options.altImage;
if(altImage) {
delete options.altImage;
macro._renderBinaryImageUrl(container, altImage, options);
} else {
options.src = src;
macro._renderAlternateText(container, options);
}
} else {
var dim = macro._getDimensions(dimensions, {
width: options.width, height: options.height }, options.preserveAspectRatio);
options.srcUrl = srcUrl;
macro._renderImageTag(container, src, dim.width, dim.height, options);
}
};
if(!image_dimensions) {
image.onload = function() {
var dimensions = { width: image.width, height: image.height};
macro._image_dimensions[srcUrl] = dimensions;
createImageTag(dimensions);
};
image.onerror = function() {
createImageTag(null, true);
};
image.src = src;
} else {
createImageTag(image_dimensions);
}
},
_generateIdPrefix: function(){
return "twsvgfix_" + (this._fixPrefix++).toString() + "_";
},
_fixSVG: function(childNodes, idPrefix) {
var urlPattern = /url\(\#([^\)]*)\)*/ig;
var fixes = [
{ attr: "id", pattern: /^(.*)$/ig },
{ attr: "href", namespace: macro.xlinkns, pattern: /^#(.*)$/ig }
];
var url_fixes = ["filter", "fill", "mask", "stroke", "style"];
for(var i = 0; i < url_fixes.length; i++) {
fixes.push({ attr: url_fixes[i], pattern: urlPattern });
}
for(var t = 0; t < childNodes.length; t++) {
var node = childNodes[t];
for(var a = 0; a < fixes.length; a++) {
var fix = fixes[a];
var attr = fix.attr;
var ns = fix.namespace || "";
if(node.hasAttributeNS && node.hasAttributeNS(ns, attr)) {
var v = node.getAttributeNS(ns, attr);
fix.pattern.lastIndex = 0;
var match = fix.pattern.exec(v);
if(match) {
// Make sure replacement string doesn't contain any single dollar signs
var toReplace = match[1];
if(toReplace.indexOf(idPrefix) !== 0 && toReplace.indexOf("twglobal_") !== 0) {
var replacement = (idPrefix + toReplace).replace("$", "$$$$");
v = v.replace(match[1], replacement);
}
node.setAttributeNS(ns, attr,v);
}
}
}
var children = node.childNodes;
if(children.length > 0) {
this._fixSVG(children, idPrefix);
}
}
},
_importSVG: function(place, options){
options = options ? options : {};
var svgDoc, tiddlerText = options.tiddler.text;
if (window.DOMParser) {
svgDoc = new DOMParser().parseFromString(tiddlerText, "application/xml").documentElement;
var idPrefix = options.idPrefix || this._generateIdPrefix();
this._fixSVG([svgDoc], idPrefix);
var el = document.importNode(svgDoc, true);
var svgHolder = document.createElementNS(macro.svgns,"svg");
var width = options.width;
var height = options.height;
if(width || height) {
if(width && height) { // set view box of containing svg element based on the svg viewbox and width and height.
var viewBox = el.getAttribute("viewBox");
var topLeft = "0 0";
if(viewBox) {
topLeft = viewBox.replace(/([0-9]*) +([0-9]*) +([0-9]*) +([0-9]*) */gi,"$1 $2");
}
svgHolder.setAttributeNS(macro.svgns, "viewBox", "0 0 %0 %1".format(width, height));
} else {
if(!width) {
width = el.getAttribute("width");
}
if(!height) {
height = el.getAttribute("height");
}
}
svgHolder.setAttribute("width", width);
svgHolder.setAttribute("height", height);
el.setAttribute("width", "100%");
el.setAttribute("height", "100%");
svgHolder.setAttribute("class", "svgImage svgIcon %0".format(options.imageClass || ""));
svgHolder.appendChild(el);
place.appendChild(svgHolder);
}
else {
var existing = el.className ? el.className.baseVal : "";
el.setAttribute("class","svgImage %0".format(existing));
place.appendChild(el);
}
// if a tiddler attribute is set this is read as a link
$("[tiddler], [tiddlyLink]", place).attr("refresh", "link").click(function(ev) {
var tiddler = $(ev.target).attr("tiddlyLink");
if(tiddler) {
story.displayTiddler(ev.target, tiddler);
}
});
}
},
getArguments: function(paramString, params) {
var args = paramString.parseParams("name", null, true, false, true)[0];
var options = {};
for(var id in args) {
if(true) {
var p = args[id];
if(id == "def") {
options[id] = p;
} else {
options[id] = p[0];
}
}
}
var width = isNaN(params[1]) ? false : parseInt(params[1], 10);
var height = isNaN(params[2]) ? false : parseInt(params[2], 10);
options.width = macro.lookupArgument(options, "width", width);
options.height = macro.lookupArgument(options, "height", height);
options.preserveAspectRatio = args.preserveAspectRatio &&
args.preserveAspectRatio[0] == "yes" ? true : false;
options.tiddlyLink = macro.lookupArgument(options, "tiddlyLink", false);
options.link = macro.lookupArgument(options, "link", false);
return options;
},
lookupArgument: function(args, id, ifEmpty) {
return args[id] ? args[id] : ifEmpty;
}
};
// update views
var _oldwikifiedview = config.macros.view.views.wikified;
// update wikifier to check tiddler type before rendering
merge(config.macros.view.views, {
wikified: function(value, place, params, wikifier, paramString, tiddler) {
if(macro.isImageTiddler(tiddler) && params[0] == "text") {
var newplace = $("<div />").addClass("wikifiedImage").appendTo(place)[0];
macro.renderImage(newplace, tiddler.title, { alt: macro.locale.badImage });
} else {
_oldwikifiedview.apply(this, arguments);
}
},
image: function(value, place, params, wikifier, paramString, tiddler) {
// a field can point to another tiddler whereas text is the current tiddler.
var title = params[0] == "text" ? tiddler.title : value;
var args = macro.getArguments(paramString, params);
macro.renderImage(place, title, args);
}
});
config.shadowTiddlers.StyleSheetImageMacro = [".wikifiedImage svg, .wikifiedImage .image { width: 80%; }",
".svgImageText { background-color:[[ColorPalette::Error]]; color:#ddd; display: inline-block; }",
"span.svgImageText { display: inline-block; overflow: hidden; }"
].join("");
store.addNotification("StyleSheetImageMacro", refreshStyles);
})(jQuery);
//}}}
A ''daySuffix'' method has been added to the Date object. Any date object will be able to return the current day suffix, i.e ''th'', ''rd'', ''st''.
The function can be use like this:
//{{{
var date = new Date();
date.daySuffix();
//}}}
It could return {{{th}}}.
The ''saveTiddler'' method of a [[TiddlyWiki class|TiddlyWiki Class]] object is typically called in response to the author clicking the '''done''' link after editing a tiddler.
This method takes six parameters:
* the old title of the tiddler
* the new title of the tiddler
* the tiddler's source code
* the name of the author
* the modification date
* the tags (as an array of strings).
This feeds directly into [[Tiddler]]'s [[set]] method, and does not save changes to the document on disk.
/*{{{*/
Background: #e0f4e2
Foreground: #0a1e0c
PrimaryPale: #c6ebc9
PrimaryLight: #7fd286
PrimaryMid: #3eb348
PrimaryDark: #0d250f
SecondaryPale: #ebc6e2
SecondaryLight: #d27fbf
SecondaryMid: #b33e98
SecondaryDark: #250d20
TertiaryPale: #e8c6eb
TertiaryLight: #cd7fd2
TertiaryMid: #ab3eb3
TertiaryDark: #240d25
Error: #f88
ColorPaletteParameters: HSL([125|9], [0.48168796743266284],[0.1|0.8514583313371986])
/*}}}*/
The sortTiddlers function of the ''TiddlyWiki'' class takes 2 parameters
{{{
store.sortTiddlers(tiddlers, field);
}}}
where
tiddlers - is an array of tiddler objects
field - is the field you wish to sort the tiddlers by (e.g modified or created). It accepts any of the default tiddler fields and can also be used with any extended fields you might have given to tiddlers.
The field parameter can also be prepended with a '+' or a '-' to indicated whether you want the tiddlers to be sorted in ascending or descending order.
For example if I wanted to sort the tiddlers by 'changecount' in descending order I'd put the following:
{{{
var sortedTiddlers = store.sortTiddlers(tiddlers, "-changecount");
}}}
The function then returns the array of tiddlers which has been sorted.
Eric:
FireBug's console interferes with the browser's handling of XMLHttpRequest functions. The problem is generally triggered by selecting "Show XMLHttpRequests" from the FireBug Console "Options" menu (open FireBug to access the menu).
In the previous version of FireBug, disabling this menu option avoided the problem. However, in the latest FireBug installation (v1.0.1), it seems that isn't enough, and the problem can appear even if the "Show..." menu it unchecked.
One workaround is to completely disable FireBug until needed (via FireFox's Tools>Addons menu item). Another workaround that temporarily fixes the problem is to TOGGLE (i.e., set and then clear) the "Show XMLHttpRequests" menu item just before doing the upload. This seems to stop FireBug from interferring in the NEXT XMLHttpRequest. Curiously, even though the menu item remains unchecked, any subsequent XMLHttpRequests will again fail until you toggle the menu again, which is quite annoying!
Forget those workarounds...
I think I've found a workaround that let's you keep FireBug enabled, and doesn't need a menu toggle each time:
In FireBug, first switch to the "Net" tab. Then, in the Options menu for Net, select "Disable Network Monitoring". This seems to stop the
problem from recurring each time you upload.... YAY!!!!
This is a simple macro that outputs the version of TiddlyWiki that is being used.
{{{
<<version>>
}}}
Displays as:
<<version>>
This is tiddlywiki.org on the new platform "TiddlySpace".
Some information is already migrated from the old wikipedia but there is still a lot to do.
The old dot-org wikipedia was littered with spam and not well maintained so there are some benefits to move over to the TiddlySpace platform.
# cleanup during migration
# update of the information
# write and display examples in our own markup
''You can also contribute to this wiki!''
To do so, you need to signup for TiddlySpace.
If you signup you will get your own Tiddly"Space"Wiki (your first space-name is also your editor-name) where you can write and publish, private and public tiddlers.
You will also be able to contribute on this @tiddlywiki space. (every TiddlySpace member can).
After you signed-up you can login on TiddlySpace (via your own space or here) and start contributing.
;Some guidelines for this wiki:
* language is English (create other languages in other spaces...you can link them here)
* test/check content before posting
;Things you can do:
* migrate articles from the old wikipedia here: http://oldwiki.tiddlywiki.org (but first please check if the information is still accurate and up to date -- if you are not sure about something, try to test or ask in the [[community forum|The community forum]], and adjust before publishing here)
* write new content
Don't know where to start?
Check your bookmarks in your browser...any links to articles in the old wikipedia? (might be good content!)
Dead links (from everywhere) to articles in the old wikipedia might be an indication that some info is missing here.
or...
...improve this tiddler...
;Situation:
You have a TiddlyWiki file on your pc and want to share this as a website online. (by sending or linking the web-address (the "url"))
Meanwhile you also want to edit the same TiddlyWiki local and add content.
;One of the options is Dropbox
Dropbox is a cloudservice that can be used for synchronizations of folders between pc's.
The Dropbox functionality can both be used via a website and installed on you local computer (both Mac, Windows and Linux)
In the following guide you need to have Dropbox installed on your pc! (see ''Dropbox installation'' below)
Dropbox has many great features like sharing folders between users and other pc's...this guide will __only__ cover the usage of the ''public'' folder and TiddlyWiki to publish your local TiddlyWiki.
!!!Step 1
*Go to Dropbox and sign-up for an account.
*Download Dropbox and install it on your computer.
*Finish the installation settings so Dropbox is attached to the account you created.
!!!Step 2
*You will now have a Dropbox folder on your pc (depending where you installed it.. homefolder or desktop (all is ok))
*Inside the Dropbox are a number of pre-created folders.
!!!Step 3
*Open the "Public" folder inside the Dropbox-folder and create a folder ("tw" for example).
*Put (copy-paste or drag) a TiddlyWiki inside the "tw" folder you just created.
!!!Step 4
*Visit the Dropbox service online and login.
(now you can see the same document structure similar to your local Drobox folder)
*Go to the "Public" folder and open the "tw" folder you just created locally.
(since Dropbox synchronizes with your local folder the new "tw" folder should be there)
*Open the "tw" folder and locate the TiddlyWiki.
*The dialog (arrow on the right side) will give you the option for delete, move etc.
''The "public-url" is the link to your TiddlyWiki file over the internet.''
//(example image "copy public url")//
[img[dropbox.png]]
!!!Step 5 (the test)
Edit your local TiddlyWiki and check (reload page) the public url to see the changes.
!!!Dropbox installation
Visit this url: https://www.dropbox.com to sign-up for the service and to download Dropbox for local installation.
Watch the video to see more features about Dropbox.
!!!Downside of Dropbox urls
It is not possible to have nice domain-names instead of the Dropbox url's.
Your TiddlyWiki's will allway's have url's similar to:
{{{
http://dl.dropbox.com/u/YOUR_NUMBER/tw/empty.html
}}}
!!!Tip
Many TiddlyWiki users have a Dropbox to publish and share so called "minimal testcases" (MTC's) in the googlegroups (TiddlyWiki's where the "private" content is stripped of...only showing an issue)...so they can easily share ideas or issues.
Wiki markup is a formatting syntax for wiki contents ("wikitext").
It is a highly simplified version of HTML, used for structuring textual contents.
As such, wiki markup offers a set of simple formatting codes that the wiki software (or "engine") then translates into HTML (a process often called "wikification") when the content is displayed in a browser.
Different wiki engines often have different syntax conventions.
* [[TiddlyWiki Markup]]
* [[MediaWiki Markup]]
* [[Markdown|Markdown Markup (if you could call it that :)]]
''Note: while there isn't yet nice, userfriendly documentation of it on the wiki for it, there exist formatter plugins for many different types of wiki markup. Muchas gracias to [[User:MartinBudden|MartinBudden]] for these. They can be found '''[http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/ here]'''.''
[[Category:Wiki Markup]] [[Category:Disambiguation]]
This is run during a refresh as a result of a call to [[refreshDisplay]]
For any dom elements with attribute refresh set to tiddler one of two things will happen:
For all tiddlers defined in changeList [[Story.prototype.refreshTiddler]] is run.
For all tiddlers that are not defined in changeList, [[refreshElements]] is run
The view macro is a powerful macro that allows you to access fields on a given tiddler and format them.
The first parameter is the field to access (note tags does not work).
The second parameter defines a [[view type|view macro types]] which defines how the value of that field should be rendered.
{{{
<<view title link>>
}}}
renders the link of the current tiddler i.e. <<view title link>>
<<tiddler About>>
[[Click here for a list of Frequently Asked Questions|TiddlyWiki FAQ]].
<<tagcloud exclude:excludeLists exclude:excludeSearch exclude:"TiddlyWiki FAQ" exclude:excludePublisher exclude:excludeMissing exclude:systemConfig>>
(Text copy-pasted from old tiddlywiki.org and only slightly edited. Feel free to improve.)
("[transclusion on Wikipedia|http://en.wikipedia.org/wiki/Transclusion]")
Using the tiddler macro {{{<<tiddler>>}}}, contents of one tiddler can be embedded from another tiddler:
{{{<<tiddler [[Foo]]>>}}}
!!Partial Transclusion
With the use of [[slices]] and [[sections]], specific parts can be transcluded from another tiddler:
{{{
<<tiddler [[tiddler::sliceLabel]]>>
<<tiddler [[tiddler##sectionHeading]]>>
}}}
!!!Examples
{{Tiddler|1=Slices|2=
label1: lorem
label2: ipsum
label3: dolor
{{!}}label4{{!}}sit{{!}}
{{!}}label5{{!}}amet{{!}}
{{!}}label6{{!}}consectetur{{!}}
}}
<pre>
<<tiddler [[Slices::label1]]>>
</pre>
{{Tiddler|1=Sections|2=
!Heading1
Lorem ipsum dolor sit amet.
!Heading2
Consectetur adipisicing elit.
!Heading3
Sed do eiusmod tempor incididunt ut labore.
}}
<pre>
<<tiddler [[Sections##Heading1]]>>
</pre>
== Parametric Transclusion ==
Using the [[NewTiddler]] macro's <code>with:</code> parameter, placeholders (<code>$1</code>-<code>$9</code>) in the transcluded contents can be replaced with the desired value:
<pre>
<<tiddler [[Foo]] with:"bar" "baz" ...>>
</pre>
=== Examples ===
{{Tiddler|1=QuoteTemplate|2=
<<<
$1
<<<
{{{$2}}}
}}
{{Tiddler|1=Quotations|2=
<nowiki>
<<tiddler [[QuoteTemplate]] with:"Alas poor Yorick" "Shakespeare">>
</nowiki>
}}
This will show:
<blockquote style="padding: 5px; background-color: #EEE;">
<blockquote>
Alas poor Yorick
</blockquote>
Shakespeare
</blockquote>
cf. [http://groups.google.com/group/TiddlyWiki/browse_thread/thread/075ada78dc1349ad/edb8d22f5d4419bc?#edb8d22f5d4419bc <nowiki>[tw]</nowiki> templates / transclusion (parametric)]
== Editing Transcluded Contents ==
* [http://tw.lewcid.org/#TiddlerWithEditPlugin TiddlerWithEditPlugin]: adds "double-click to edit source" capabilities to the core Tiddler macro
* [http://www.tiddlytools.com/#EditTiddlerPlugin EditTiddlerPlugin]: embeds an "edit" link in tiddler content to invoke edit on any specified tiddler title
== StyleSheet Transclusion ==
Within [[Style Sheets]], [[PrettyLinks]] are treated like import statements; the contents of the targeted tiddler are included as [[CSS]] code.
== Transcluded Html Scripts ==
{{Quote|[http://groups.google.com/group/tiddlywiki/browse_thread/thread/c4aa71ecb0f7d4cf/7e2272e3bc4593eb?#7e2272e3bc4593eb Eric]|
<pre>
Transclusions can be used generate program- driven output, embedded in specific
tiddler content (like an inline script or a plugin-defined macro).
Transclusions are invoked by using the
<<tiddler TiddlerName with: param param param ...>>
syntax. The 'param' values are automatically inserted in place of
any 'substitution markers' ("$1" through "$9") that are embedded in the
transcluded content. This allows you to use the transclusion as if it was a
macro function: passing in parameter values and generating enhanced output in
response.
Some transclusions are simple substitutions, allowing you to use an abbreviated
syntax to render pre-formatted blocks of content, like this:
<<tiddler ShowQuotation with: [[...quote...]] [[author]]>>
where ShowQuotation contains:
$2 wrote:
{{{
$1
}}}
Transclusions can do much more than simply insert a few values into a
pre-defined format. By using a combination of 'hidden sections' and some
cleverly written 'evaluated parameters' invoked from the <<tiddler>> macro, it
is possible to build some complex programmed behaviors
into a transcluded tiddler.
However, while macros and inline scripts can use virtually any javascript coded
logic you can imagine, transclusions only contain standard TW syntax, without
relying upon installation of any supporting plugins (i.e.,
InlineJavascriptPlugin). Although this limits their abilities somewhat, there
are still a wide variety of programmatically-generated output and/or behaviors
that they can produce.
In fact, when possible, I have been converting many of my previously written
TiddlyTools inline scripts into 'transclusions', in order to completely
eliminate their dependence on InlineJavascriptPlugin. By using only TW native
syntax, it allows these former scripts to work properly and consistently,
regardless of whether they are installed in an empty TW document or one that
has been highly customized with lots of plugins.
For the current listing of 'transclusions' available on TiddlyTools, see:
http://www.TiddlyTools.com#txtCatalogTab:transclusions
</pre>
}}
Cook is the build tool for [[TiddlyWiki]].
It utilizes [[recipes|Recipe]] to stitch together TiddlyWiki HTML files from their constituent chunks.
!!External Resources
* github [[Cooker|https://github.com/TiddlyWiki/cooker]]
* [[Cook|http://trac.tiddlywiki.org/wiki/Cook]] (old)
* [[Ginsu|http://trac.tiddlywiki.org/wiki/Ginsu]] (old)
!!!See Also
* [[Ginsu]]
* [[Recipes|Recipe]]
* [[Chef]]
(function() {
var getCSRFToken = function(window) {
// XXX: should not use RegEx - cf.
// http://www.quirksmode.org/js/cookies.html
// https://github.com/TiddlySpace/tiddlyspace/commit/5f4adbe009ed4bda3ce39058a3fb07de1420358d
var regex = /^(?:.*; )?csrf_token=([^(;|$)]*)(?:;|$)/;
var match = regex.exec(document.cookie);
var csrf_token = null;
if (match && (match.length === 2)) {
csrf_token = match[1];
}
return csrf_token;
};
if (typeof config !== 'undefined' && config.extensions &&
config.extensions.tiddlyspace &&
config.extensions.tiddlyspace.getCSRFToken === null) {
config.extensions.tiddlyspace.getCSRFToken = getCSRFToken;
} else {
window.getCSRFToken = getCSRFToken;
}
})(window);
!!Preloading New Tiddlers with Boilerplate Contents
[[How To/Preloading New Tiddlers with Boilerplate Contents]] - Eric
!!Including Username in the Title or Subtitle
[[Including Username in the Title or Subtitle]] - Eric
!!Displaying different kinds of tiddlers
[[Displaying different kinds of tiddlers]] - Eric
!!Make a tiddler open in folded mode
[[Make a tiddler open in folded mode]] - Eric
!!Automatically open today's journal tiddler on startup
[[Automatically open today's journal tiddler on startup]] - Eric
!!Display Number of External Links in a Tiddler
[[How To/Display number of external links in a tiddler]] - Eric
!!Change the Title Bar
[[How To/Change the title bar]] - Eric
!!Synchronizing TW Files
[[How To/Synchronize TW files]] - Eric
!!Multi-line Contents in a List
[[How To/Multi-line contents in a list]] - Eric
!!Build a Menu Tree in TW
[[How To/Build a menu tree in TW]] - Eric
!!Display a Variable Within a Tiddler
[[How To/Display a variable within a tiddler]] - Eric
!!How To Add Content From Text Files
[[How To/How To Add Content From Text Files]] - Eric
!!Custom Template with Custom Toolbar
[[How To/Custom Template with Custom Toolbar]] - Eric
!!Header Macro/Plugin (for Custom Graphic Header)
[[How To/Header Macro/Plugin (for Custom Graphic Header)]] - Eric
!!A script from "file://" is requesting enhanced abilities
[[A script from "file://" is requesting enhanced abilities]] - Eric
!!Correct Syntax for Naming a Slice
[[How To/Correct Syntax for Naming a Slice]] - Eric
!!Embedding Macros in [[ ]] to use for links to other tiddlers
[[How To/Embedding Macros in double brackets to use for links to other tiddlers]] - Eric
!!How to Get the Content of a Tiddler and Edit Them in a Macro
[[How To/How to Get the Content of a Tiddler and Edit Them in a Macro]] - Eric
!!Important Differences Between 'Plugins' and 'Scripts'
[[How To/Important Differences Between 'Plugins' and 'Scripts']] - Eric
!!Plugins and Importing Tiddlers
[[How To/Plugins and Importing Tiddlers]] - Eric
!!Basic Info to Provide When Asking for Help
[[How To/Basic Info to Provide When Asking for Help]] - Eric
Refreshes the backstage if open and calls the [[refreshElements]] function for all elements in the dom element with id "contentWrapper"
There are a few ways to find a tiddler.
*Look on the Main Menu
*Type a keyword or the tiddler's name into the search box
*Select the All tab on the right-hand menu to see an alphabetical list of all tiddlers
*Select the Tags tab on the right-hand menu to browse tags/keywords
*Select the Timeline tab on the right-hand menu to see tiddlers most recently edited/added
[[Category:FAQ]]
[[Category:Using TiddlyWiki]]
The options macro, used predominately in the backstage, allows the user to set a number of cookie based options that affect the enabled features of the Tiddlywiki. These settings can be trivial, such as do you want animations enabled, or can be used for more complex things, such as enable regular expressions searches.
It is used as below:
{{{
<<options>>
}}}
Options can be used by plugin developers to add settings that can be used by their plugin.
Displays as:
<<options>>
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
Many thanks to the following contributors for keeping TiddlyWiki.org up to date:
{{inlineList{
<<groupBy modifier groupTemplate:Templates##Faces exclude:None>>
}}}
Get yourself in the above list by contributing to this page!
The date macro will display the current date and time:
{{{
<<today>>
}}}
Displays as:
<<today>>
This macro accepts one parameter - a date format. Such as:
{{{
<<today DD/MM/YYYY>>
}}}
Displays as:
<<today DD/MM/YYYY>>
Read more about [[Date Formats]]
Custom Macros are all Macros in a TiddlyWiki that are not part of Core Macros. Custom macros can be coded by the user, or copied from another site or repository.
Much of the power of TiddlyWiki lies in the ease with which users can create macros and [[Plugins]] to customize their wikis, and share them with each other.
Information on how to code a Custom Macro can be found in [[Dev:Custom Macros]].
You can bundle CSS in a plugin using the following mechanism taking advantage of [[Tiddler Heading Transclusion]]
To do this, first include a comment like so in the plugin:
{{{
/*
!StyleSheet
body { border: solid 1px black; }
!Code
*/
}}}
Ensure you use the {{{!Code}}} to signal to the end of the section and thus the stylesheet.
In the code include the following lines at the top of your plugin:
{{{
var name = "StyleSheet" + tiddler.title;
config.shadowTiddlers[name] = "/*{{{*/\n%0\n/*}}}*/".
format(store.getTiddlerText(tiddler.title + "##StyleSheet")); // this accesses the StyleSheet section of the current tiddler (the plugin that contains it)
store.addNotification(name, refreshStyles);
}}}
!Block Quotations
Blocks of text can be displayed as quotations:
{{{
<<<
Steve Jobs: "computers are like a bicycle for our minds"
<<<
}}}
Displays as:
<<<
Steve Jobs: "computers are like a bicycle for our minds"
<<<
!Nested Quotations
Quotes can be displayed on multi-levels:
{{{
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3
}}}
Displays as:
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3
!Nested Quotations inside Block Quotations
{{{
<<<
Steve Jobs: "computers are like a bicycle for our minds"
> blockquote, level 1
Some more text.
<<<
}}}
Displays as:
<<<
Steve Jobs: "computers are like a bicycle for our minds"
> blockquote, level 1
Some more text.
<<<
The [[Space]] created for a [[User]] when they [[Register]] with [[TiddlySpace]].
The [[Home Space]] has the same name as the [[User]] and is used by the system to collect information about the user, such as their [[avatar|SiteIcon]], and [[Plugin|plugins]] may establish similar conventions for other commonly used information. For example a [[Tiddler]] entitled [[Twitter]] may be used for the [[User]]'s username for http://twitter.com.
It is possible for a [[User]] to [[add a member|Add Member]] to their [[Home Space]]. It is also possible for a [[User]] to remove themselves from their own [[Home Space]], or be removed by another [[Member]] of the [[Space]] from their [[Home Space]].
(Text copy-pasted from old [[tiddlywiki.org|http://oldwiki.tiddlywiki.org/wiki/Transclusion]] and only slightly edited. Feel free to improve.)
[[Wikipedia article|http://en.wikipedia.org/wiki/Transclusion]] on transclusion.
Using the tiddler macro {{{<<tiddler>>}}}, contents of one tiddler can be embedded from another tiddler:
{{{<<tiddler [[Foo]]>>}}}
!!Partial Transclusion
With the use of [[slices]] and [[sections]], specific parts can be transcluded from another tiddler:
{{{
<<tiddler [[tiddler::sliceLabel]]>>
<<tiddler [[tiddler##sectionHeading]]>>
}}}
!!!Examples
{{{
''Tiddler: Slices''
label1: lorem
label2: ipsum
label3: dolor
|label4|sit|
|label5|amet|
|label6|consectetur|
}}}
{{{<<tiddler [[Slices::label1]]>>}}}
{{{
''Tiddler: Sections''
!Heading1
Lorem ipsum dolor sit amet.
!Heading2
Consectetur adipisicing elit.
!Heading3
Sed do eiusmod tempor incididunt ut labore.
}}
}}}
{{{<<tiddler [[Sections##Heading1]]>>}}}
!!Parametric Transclusion
Using the [[NewTiddler]] macro's <code>with:</code> parameter, placeholders {{{($1-$9)}}} in the transcluded contents can be replaced with the desired value:
{{{<<tiddler [[Foo]] with:"bar" "baz" ...>>}}}
!!!Examples
''Tiddler: QuoteTemplate''
{{{
<<<
$1
<<<
{{{$2}}}
}}}
''Tiddler: Quotations''
{{{<<tiddler [[QuoteTemplate]] with:"Alas poor Yorick" "Shakespeare">>}}}
This will show:
Alas poor Yorick
Shakespeare
!!!Editing Transcluded Contents
* [[TiddlerWithEditPlugin|http://tw.lewcid.org/#TiddlerWithEditPlugin]] adds "double-click to edit source" capabilities to the core Tiddler macro
* [[EditTiddlerPlugin|http://www.tiddlytools.com/#EditTiddlerPlugin]] embeds an "edit" link in tiddler content to invoke edit on any specified tiddler title
!!StyleSheet Transclusion
Within [[Style Sheets]], [[PrettyLinks]] are treated like import statements; the contents of the targeted tiddler are included as [[CSS]] code.
!!Transcluded Html Scripts
(from Eric in [[google group|http://groups.google.com/group/tiddlywiki/browse_thread/thread/c4aa71ecb0f7d4cf/7e2272e3bc4593eb?#7e2272e3bc4593eb]])
{{{
Transclusions can be used generate program- driven output, embedded in specific
tiddler content (like an inline script or a plugin-defined macro).
Transclusions are invoked by using the
<<tiddler TiddlerName with: param param param ...>>
syntax. The 'param' values are automatically inserted in place of
any 'substitution markers' ("$1" through "$9") that are embedded in the
transcluded content. This allows you to use the transclusion as if it was a
macro function: passing in parameter values and generating enhanced output in
response.
Some transclusions are simple substitutions, allowing you to use an abbreviated
syntax to render pre-formatted blocks of content, like this:
<<tiddler ShowQuotation with: [[...quote...]] [[author]]>>
where ShowQuotation contains:
$2 wrote:
{{{
$1
}}}
Transclusions can do much more than simply insert a few values into a
pre-defined format. By using a combination of 'hidden sections' and some
cleverly written 'evaluated parameters' invoked from the <<tiddler>> macro, it
is possible to build some complex programmed behaviors
into a transcluded tiddler.
However, while macros and inline scripts can use virtually any javascript coded
logic you can imagine, transclusions only contain standard TW syntax, without
relying upon installation of any supporting plugins (i.e.,
InlineJavascriptPlugin). Although this limits their abilities somewhat, there
are still a wide variety of programmatically-generated output and/or behaviors
that they can produce.
In fact, when possible, I have been converting many of my previously written
TiddlyTools inline scripts into 'transclusions', in order to completely
eliminate their dependence on InlineJavascriptPlugin. By using only TW native
syntax, it allows these former scripts to work properly and consistently,
regardless of whether they are installed in an empty TW document or one that
has been highly customized with lots of plugins.
For the current listing of 'transclusions' available on TiddlyTools, see:
http://www.TiddlyTools.com#txtCatalogTab:transclusions
}}}
{{{
[element = ]createExternalLink(place, url[, label])
}}}
The ''createExternalLink'' global function renders a link to an outside Web page. It requires two parameters:
; place
: the DOM element to render into. The link is appended to any existing content.
; url
: the URL to point to.
; label
: optional text label to display.
This function returns a DOM element reference to the link.
This tiddler contains the markup used to display tiddlers in edit mode. It is designed to make it easy to change the layout/structure of the tiddler in edit mode.
By default it contains the following markup:
{{{
<div class='toolbar'
macro='toolbar [[ToolbarCommands::EditToolbar]] icons:yes'>
</div>
<div class='heading editorHeading'>
<div class='editor title' macro='edit title'></div>
<div class='tagClear'></div>
</div>
<div class='annotationsBox' macro='annotations'>
<div class='editSpaceSiteIcon'
macro='tiddlerOrigin height:16 width:16 label:no interactive:no'>
</div>
<div class="privacyEdit" macro='setPrivacy label:no interactive:no'></div>
<div class='tagClear'></div>
</div>
<div class='editor' macro='edit text'></div>
<div class='editorFooter'>
<div class='tagTitle'>tags</div>
<div class='editor' macro='edit tags'></div>
<div class='tagAnnotation'>
<span macro='message views.editor.tagPrompt'></span>
<span macro='tagChooser excludeLists'></span>
</div>
</div>
}}}
TiddlyWiki's architecture for interacting with servers allows it to be plugged into a wide variety of servers. This is done through the addition of plugins containing custom server adaptors. Server adaptors are designed to allow for use cases like importing tiddlers, loading missing tiddlers on the fly and synchronising changes with a server. Separate macros and core extensions implement such features by accessing the facilities provided by server adaptors.
Server adaptors are designed to use a familiar model akin to a device driver, adapting a standardised interface to whatever is required by the underlying server: [[WebDAV|http://en.wikipedia.org/wiki/Webdav]], ZiddlyWiki, [MediaWiki|http://en.wikipedia.org/wiki/MediaWiki]], [[Socialtext|http://www.socialtext.com/]] or HTML scraping.
Many server architectures are [[REST|http://en.wikipedia.org/wiki/REST]] based, and TiddlyWiki server adaptors are particularly easy to create for common REST patterns. It is also possible to create TiddlyWiki server adaptors for severs with an [[XML-RPC|http://en.wikipedia.org/wiki/XML-RPC]] interface.
Server adaptors are registered by name in the global object <code>config.adaptors</code>. Each entry is a reference to an object constructor for that type of server adaptor. The adaptor object must implement the following methods:
* [[Adaptor.openHost]]
* [[Adaptor.openWorkspace]]
* [[Adaptor.getTiddler]]
* [[Adaptor.close]]
Additionally the adaptor may implement the following methods:
* [[Adaptor.getWorkspaceList]] (required to support the Import Tiddlers UseCase)
* [[Adaptor.getTiddlerList]] (required to support the Import Tiddlers UseCase)
* [[Adaptor.putTiddler]] (required to support the Sync UseCase)
* [[Adaptor.getTiddlerRevision]]
* [[Adaptor.getTiddlerRevisionList]]
The adaptor object is used through the life of a connection to a server; see [[ServerAdaptorConcepts]] for details. Many of the methods use an AsynchronousPattern of callbacks to deliver their results.
Custom formatters for the WikifierFormatterMechanism are often used alongside server adaptors to allow TiddlyWiki to display content in the native format of a server.
[[TiddlyWiki|http://tiddlywiki.com]] is a single html file which has all the characteristics of a [[wiki|WikiWikiWeb]] - including all of the content, the functionality (including editing, saving, tagging and searching) and the style sheet. Because it's a single file, it's very portable - you can email it, put it on a web server or share it via a [[USB stick|WikiOnAStick]].
The //createTiddler// method of the [[Story Class]] opens a tiddler on the page. If a tiddler by the requested name doesn't exist, it appears ready to edit. This method takes four parameters:
* the overall parent DOM element to display the tiddler inside.
* the DOM element inside the first parameter to display directly after. A null value places it at the end of the entire element.
* the title of the tiddler to display.
* the template to use to display the tiddler. It should be either the constant //~DEFAULT_VIEW_TEMPLATE// or //~DEFAULT_EDIT_TEMPLATE//.
This method returns the newly created DOM element.
/*!
|''Name:''|NiceTaggingPlugin|
|''Description:''|Creates a nicer interface for adding and removing TiddlyWiki. Ideal for tiddly novices. |
|''Version:''|0.6.6|
|''Date:''|October 2010|
|''Source:''|http://svn.tiddlywiki.org/Trunk/contributors/JonRobson/plugins/niceTagging/plugins/NiceTaggingPlugin.js|
|''Author:''|Jon Robson|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.3|
|''Dependencies:''||
!Usage
{{{<<niceTagger tags>>}}} or {{{<<niceTagger field>>}}}
!!Additional Parameters
splitOn: <character>
valuesSource: <tiddler title>
textcase: <lower>
!StyleSheet
.tip {font-style:italic;font-weight:bold;}
input.dp-applied {width: 140px; float: left;}
.niceTagger input {width:200px; float:left;}
.deleter {color:red; font-weight:bold; padding:2px; cursor:pointer;}
.ac_results {padding: 0px;border: 1px solid black;background-color: white;overflow: hidden;z-index: 99999;}
.ac_results ul {width: 100%;list-style-position: outside;list-style: none;padding: 0;margin: 0;}
.ac_results li {margin: 0px;padding: 2px 5px;cursor: default;display: block;font: menu;font-size: 12px;line-height: 16px;overflow: hidden;}
.ac_loading {background: white url('indicator.gif') right center no-repeat;}
.niceTaggerAdder input {width:auto; display: inline;}
.ac_odd {background-color: #eee;}
.ac_over {background-color: #0A246A;color: white;}
*/
//{{{
(function($) {
config.shadowTiddlers.NiceTaggingStyle = store.getTiddlerText(tiddler.title + "##StyleSheet");
store.addNotification("NiceTaggingStyle", refreshStyles);
String.prototype.toJSON = function(){
var namedprms = this.parseParams(null, null, true);
var options ={};
for(var i=0; i < namedprms.length;i++){
var nameval = namedprms[i];
if(nameval.name) {
options[nameval.name] = nameval.value;
}
}
return options;
};
var macro = config.macros.niceTagger = {
lingo:{
add: "add"
},
twtags: {},
initialised:{},
init: function(field){
field = !field ? 'tags' : field;
if(this.initialised[field]){
if(field == 'tags') {
var numTags = store.getTags();
if(numTags.length == this.twtags[field].length) {
return;
}
} else {
return;
}
}
var tiddlers= store.getTiddlers();
macro.twtags[field] = [];
var uniqueSuggestions = [];
for(var i=0; i < tiddlers.length; i++){
var tid = tiddlers[i];
var values;
if(field=='tags') {
values = tid.tags;
} else {
values= tid.fields[field];
values = values ? values : "";
values = values.readBracketedList();
}
for(var j=0; j < values.length; j++){
uniqueSuggestions.pushUnique(values[j]);
}
}
macro.twtags[field] = uniqueSuggestions;
this.initialised[field] =true;
},
save: function(title, field, listvalues, place, autosavechanges) {
var tiddler = store.getTiddler(title);
var tiddlerEl = story.getTiddler(title);
var valueToSave;
valueToSave = String.encodeTiddlyLinkList(listvalues);
var el = $("[edit=%0]".format([field]), tiddlerEl);
if(el.length === 0) {
el = $("<input />").attr("type", "hidden").attr("edit", field).appendTo(place);
}
el.val(valueToSave);
var dummy = new Tiddler(title);
if(field == "tags") {
dummy.tags = listvalues;
} else {
dummy.fields[field] = valueToSave;
}
return dummy;
},
refreshFieldDisplay: function(place, tiddler, field) {
var container = $(".niceTagger", place);
container.empty();
var values;
if(!field || field == 'tags') {
values = tiddler.tags;
} else {
values = tiddler.fields[field] ? tiddler.fields[field].readBracketedList() : [];
}
for(var t = 0; t < values.length; t++){
var tag = values[t];
$("<span />").addClass("tag").text(tag).appendTo(container);
$("<span />").addClass("deleter").text("x").attr("deletes", escape(tag)).appendTo(container);
}
$(".deleter", place).click(function(ev){
var todelete = $(ev.target).attr("deletes");
var newValues = [];
for(var i = 0; i < values.length; i++){
var value = values[i];
if(escape(value) != todelete) {
newValues.push(value);
}
}
tiddler = macro.save(tiddler.title, field, newValues, place, tiddler.autosavechanges);
macro.refreshFieldDisplay(place, tiddler, field);
});
},
saveNewValue: function(tiddler, field, value, container, splitChar) {
var tiddlerEl = story.getTiddler(tiddler.title);
var editEl = $("[edit=%0]".format([field]), tiddlerEl);
var adder = $(".niceTaggerAdder input[type=text]", container);
var saveThis;
if(editEl.length > 0) {
saveThis = editEl.val() || "";
saveThis = saveThis.readBracketedList();
} else {
if(field == 'tags') {
saveThis = tiddler.tags;
} else {
var val = tiddler.fields[field];
val = val ? val : "";
saveThis = val.readBracketedList();
}
}
value = typeof(value) == 'string' ? value.trim() : value;
if(value.length === 0) {
return;
}
var newValues;
if(splitChar && value && value.indexOf(splitChar) != -1){
newValues = value.split(splitChar);
} else {
newValues = [value];
}
for(var i = 0; i < newValues.length;i++){
var svalue = newValues[i];
saveThis.pushUnique(svalue);
}
tiddler = macro.save(tiddler.title, field, saveThis, container, tiddler.autosavechanges);
macro.refreshFieldDisplay(container, tiddler, field);
$(adder).val("");
},
getSuggestionsFromTiddler: function(srcTiddler, textcase){
var suggestions = [];
if(srcTiddler){
var src = store.getTiddler(srcTiddler);
var text = src.text;
var tempdiv = document.createElement("div");
wikify(text, tempdiv, null, src);
var html = $(tempdiv).html();
suggestions = html.split(/<br\/?>/gi);
}
var finalSuggestions = [];
for(var i=0; i < suggestions.length; i++){
var val = suggestions[i].trim();
if(textcase && textcase == "lower") {
val = val.toLowerCase();
}
finalSuggestions.pushUnique(val);
}
return finalSuggestions;
},
removeFromList: function(list,removeList){
var uniqueSuggestions = [];
for(var i=0; i < list.length; i++){
var s =list[i];
if(s && typeof(s) == 'string'){
if(uniqueSuggestions.indexOf(s) ==-1 && removeList.indexOf(s) ==-1){
uniqueSuggestions.push(s);
}
}
}
return uniqueSuggestions;
},
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var options = paramString.toJSON();
var args = paramString.parseParams("anon")[0];
if(options.autoSaveChanges) {
tiddler.autosavechanges = true;
}
if(!options.field) {
options.field = args.anon ? args.anon[0] : "tags";
}
this.init(options.field);
var container = $("<div />").addClass("niceTaggerContainer").attr("field", options.field).
appendTo(place)[0];
var displayer = $("<div />").addClass("niceTagger").appendTo(container)[0];
macro.refreshFieldDisplay(container, tiddler, options.field);
var tagplace = $("<div />").addClass("niceTaggerAdder").appendTo(container)[0];
var splitChar = options.splitOn;
var adder;
if($().autocomplete){
params = paramString.parseParams("anon", null, true, false, false);
var textcase = getParam(params, "case");
var srcTiddler = getParam(params, "valuesSource");
var suggestions;
if(srcTiddler) {
suggestions = macro.getSuggestionsFromTiddler(srcTiddler, textcase);
} else {
suggestions = [];
}
var tagsoff = getParam(params,"nostoretags");
if(!tagsoff) {
suggestions = suggestions.concat(macro.twtags[options.field]);
}
var ignoreList = paramString.parseParams("exclude", null, true, false, true);
if(ignoreList && ignoreList[0] && ignoreList[0].exclude) {
ignoreList = ignoreList[0].exclude;
} else {
ignoreList = ["excludeList"];
}
suggestions = macro.removeFromList(suggestions, ignoreList);
var addtaghandler = function(v) {
macro.saveNewValue(tiddler, options.field, $(v).val(), container, splitChar);
};
$("<input type='text' name=\""+options.field+"\" value=\"\"/>").autocomplete(suggestions,{ matchContains: true, selectFirst:false }).result(addtaghandler).appendTo(tagplace);
adder = $("input", tagplace)[0];
} else {
adder = document.createElement("input");
tagplace.appendChild(adder);
}
$(adder).keypress(function (ev) {
ev.stopPropagation();
if(ev.which == 13){
var results = $(".ac_over",".ac_results"); //is anything highlighted in autocomplete plugin ?
var value;
if(results.length === 0) {
value = $(ev.target).val();
} else {
value = $(results[0]).val();
}
macro.saveNewValue(tiddler, options.field, value, container, splitChar);
}
});
var addbutton = document.createElement("input");
addbutton.type = "button";
addbutton.value = macro.lingo.add;
addbutton.className = "adder";
tagplace.appendChild(addbutton);
$(addbutton).click(function(e){
var val = $(adder).val() || "";
macro.saveNewValue(tiddler, options.field, val, container, splitChar);
});
}
};
_setTiddlerField = Story.prototype.setTiddlerField;
Story.prototype.setTiddlerField = function(title, value, mode, field) {
var tiddler = store.getTiddler(title) || new Tiddler(title);
var container = $(".niceTaggerContainer[field=%0]".format([field]),
story.getTiddler(title));
if(container.length > 0) {
macro.saveNewValue(tiddler, field, value, container[0]);
} else {
_setTiddlerField.apply(this, arguments);
}
};
})(jQuery); //end alias
//}}}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="301 225 48 52"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<g>
<path d="M 333.00003 234 L 306 258.75003 L 301.5 270 L 312.75 265.50003 L 339.75 240.74998 Z M 337.5 229.50002
L 335.24988 231.75008 L 341.99997 238.50003 L 344.24997 236.24995 Z M 342 225.00003 L 339.74988 227.25009
L 346.5 234.00005 L 348.75 231.75003 Z M 301.5 273.9719 C 301.5 273.9719 309.59888 277.99927 317.70013 273.97183
C 325.80066 269.94437 341.99997 276.65686 341.99997 276.65686 L 341.99997 273.97195
C 341.99997 273.97195 325.80014 267.2594 317.70013 271.28687 C 309.6 275.31451 301.5 271.28683 301.5 271.28683 Z"
fill="#101010" class="glyph"/>
</g>
</g>
</svg>
TiddlyWiki core code has been migrated to GitHub and can be found at http://github.com/tiddlywiki/tiddlywiki
Various plugins and support code is still in the older Subversion repository at http://svn.tiddlywiki.org.
Open the [[SiteTitle]] tiddler. (The tiddler is in GettingStarted but can also be found using the search box or listed under the All or Timeline tabs on the right-hand menu.)
Type the TiddlyWiki name in the main text box (below the yellow box which says 'this shadow tiddler...')
Click on Done (grey menu at top right of tiddler). The name should now be displayed in the header at the top of the TiddlyWiki.
The TiddlyWiki's sub-title can be changed by opening and editing the [[SiteSubtitle]] tiddler.
The ''getTags'' method of a [[Tiddler]] object returns a string representing all tags that the author has assigned to it. Spaces separate tags, and double brackets indicate tags with spaces in them. For example if you have a fetched a tiddler from the store and saved it in a variable ''tiddler'' you would use it like so:
{{{
tiddler.getTags();
}}}
It would return something like:
{{{
"method [[tiddlywiki api]]"
}}}
This method takes no parameters.
The TabAll tiddler contains a command to list all of the tiddler in your TiddlyWiki.
{{{
<<list all>>
}}}
In TiddlyWiki this list appears as default in the {{{All}}} tab on the right-hand menu.
To enable editing of the Tiddlywikis in...
'' Internet Explorer ''
'''Have to add an image here'''
* In IE, choose Tools > Internet Options
* Go to the Security tab and select "Local Intranet" Zone
* Click Default Level (to clear the Custom Level settings)
* Set the Security level to Low
* Close all open browsers
* You can now edit the wiki
Also Try:
If TiddlyWiki has been downloaded using Internet Explorer on Windows XP with Service Pack 2 and stored on an NTFS-formatted drive, any attempts to save changes will usually fail with the following error message:
It's not possible to save changes. Possible reasons include:
- your browser doesn't support saving (Firefox, Internet Explorer, Safari and Opera all work if properly configured)
- the pathname to your TiddlyWiki file contains illegal characters
- the TiddlyWiki HTML file has been moved or renamed
The solution is to right-click on the TiddlyWiki HTML file and choose Properties. If the file is blocked, there will be an Unblock button on the resulting property sheet, which will remove the protection and allow the file to be saved.
'' Safari / Opera ''
The updated [[TiddlySaver|http://www.tiddlywiki.com/#TiddlySaver]] Java applet permits TiddlyWiki to save changes from Safari & Opera, eliminating the Java Policy step <br>
<br>
URL: http://www.tiddlywiki.com/#TiddlySaver <br>
Filename: TiddlySaver.jar <br>
File Type: Java applet <br>
Location: Saved in the same directory as the TiddlyWiki file <br>
Note: TiddlySaver.jar is signed by UnaMesa Association, their certificate is signed by Thawte Code Signing CA intermediate certificate & is chained to the Thawte Premium Server CA root certificate. The first time this applet runs, allow the browser to trust the certificate chain to be able to use the applet, even if the certificate is indicated as valid <br>
<br>
Note that there is no longer any need for a .java.policy file <br>
<br>
Ensure that if a backup directory is specified in AdvancedOptions, which does not exist, TiddlySaver will not run; due to a software bug <br>
<br>
Appreciation for the original TiddlySaver code: Andrew Gregory <br>
Appreciation for arranging the certificate magic: BidiX
'' Opera Portable Edition ''
... cannot save. It cannot use TiddlySaver.jar, because it does not support Java.
'' Opera on Ubuntu ''
If your version of Ubuntu doesn't currently have Java installed, when you try to save changes you will receive a message that reads like the following:
<localhost>
It's not possible to save changes. Possible reasons include:
- your browser doesn't support saving (Firefox, Internet Explorer, Safari and Opera all work if properly configured)
- the pathname to your TiddlyWiki file contains illegal characters
- the TiddlyWiki HTML file has been moved or renamed
To fix this:
#[[Download java|https://help.ubuntu.com/community/Java]].
#Then update Opera to use the new Java libraries. [[Source Instructions|http://ubuntuforums.org/showthread.php?t=69275]]
##First find the java library using "locate libjava.so".
##In Opera, enable Java, set the "Java Options" folder to the java library folder.
#Finally, reboot Opera.
When you next try to save changes, you will be greeted by a permissions dialog to allow saving. You should now be able to save your changes!
'' See Also ''
* [[It's not possible to save changes]]
[[Category:FAQ]]
[[Category:Getting Started]]
[[Category:Browser Issues]]
Open MainMenu for editing. Position the cursor where the item is to appear and type in the name of the tiddler. If the tiddler's name is a WikiWord it will work automatically as a link. If not, insert two square brackets either side of the tiddler name: <code><nowiki>[[tiddler name]]</nowiki></code>.
Close MainMenu. You should now see the new item displayed.
> Your best bet is to upload them and maintain them on tiddlyspace.com
People use several approaches for distributing TiddlyWiki plugins:
- Publish at tiddlyspace
- Publish on github
- Publish on your own site (eg tiddlytools.com)
- Publish on [[tiddlyspot|http://www.tiddlyspot.com]]
TiddlyHub didn't really take off; it doesn't really achieve much more
than doing a Google search.
The most important thing is probably to announce your plugin in a
message to the group.
The global function {{{wikify}}} renders TiddlyWiki source code into an element. There are four parameters to this function:
* the source code to render
* the DOM element to render into
* a regular expression to highlight
* the [[Tiddler]] that the source belongs to
At it's simplest it is used like so
{{{
wikify("String to ''wikify'', place);
}}}
Which would display as below (if place was this location):
String to ''wikify''
!!!Also see
* [[wikifyStatic]]
* [[wikifyPlainText]]
{{{
story.findContainingTiddler(element);
}}}
The ''findContainingTiddler'' method of the [[Story|Story Class]] class returns the DOM element corresponding to an entire tiddler on the page that encloses the DOM element passed to the method. If the passed element is not inside a tiddler, a null value is returned.
; element
: the DOM element passed to the method.
I just started using this tonight and decided to save it. Got the above and did google searches and mess with my internet sites and all that crud.
Then I took a minute and thought, it's a .html file. Let's try saving it from File > Save As in IE and renaming it. So I did that and named it "test." I then opened test.html with "Open With" in IE from where I saved it and did a couple changes, then I saved it using the "save" feature in the "backstage" shortcut in the upper right. It saved this time. I went and looked in the folder where "test.html" was saved and it saved it how tiddlywiki claimed they name saved files: test.eightnumbers.morenumbers
I closed IE and then opened test.numbers.numbers and it opened and it had kept my changes.
My guess is that the "empty" file that they sent to get started with is not working correctly or maybe you just need to do this anyways.
Hope this helps someone.
The following bubble appears on every Tiddler@glossary
The number inside it represents the number of spaces that ''you'' follow who have a tiddler with the same name.
[img[followbubble]]
It is primarily used as a way to collaborate on a given subject.
See [[What is following?]]@faq
Join the TiddlyWiki IRC channel: irc://irc.freenode.net/tiddlywiki irc.freenode.net #tiddlywiki
Or use the interface below....
<html><div align="center"><iframe src="http://webchat.freenode.net?channels=tiddlywiki&uio=d4" "frameborder="0" width="100%" height="400"></iframe></div></html>
A convenience function.
Takes a tag and sortField (optional) and returns all tiddlers which have the tag given, sorted by sortField if given.
Note the same result can be achieved by using [[TiddlyWiki.prototype.getValueTiddlers]] or [[TiddlyWiki.prototype.reverseLookup]].
|~ViewToolbar|+editTiddler +cloneTiddler > fields refreshTiddler changeToPublic changeToPrivate revisions syncing permalink references jump closeOthers < closeTiddler|
|~EditToolbar|+saveTiddler saveDraft -cancelTiddler deleteTiddler|
|~RevisionToolbar|> fields revert|
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
The ''getLinks'' method of a [[Tiddler]] object returns an array of strings, each corresponding to a link present in the tiddler's source code. There are no parameters to this method.
Use:
{{{
var tiddlerObj = store.getTiddler('Dev:Macros');
tiddlerObj.getLinks();
}}}
It returns only the links to other tiddlers, it does not return external links.
Returns {{{["TiddlyWiki", "Dev:Plugin Development", "Dev:Plugin Specifications"]}}}
Using this method is preferable to examining the ''links'' property directly. {{{why?}}}
The //getTemplateForTiddler// method of the [[Story]] class returns HTML source code ready to be used as a template that is stored inside a tiddler. This method takes three parameters:
* the title of the tiddler that is about to be displayed
* the title of the tiddler containing the template source code. Note that the constants //~DEFAULT_VIEW_TEMPLATE// and //~DEFAULT_EDIT_TEMPLATE// do not work here.
* a reference to the Tiddler about to be displayed
Only the second parameter is actually used by the TiddlyWiki code, but the other information is passed for the benefit of plugin developers who override this method.
! Inline Formatting
| ''To Format Text As...'' | ''Use This Mark-Up'' |
| ''Bold'' | {{{''Bold''}}} Two single-quotes, not a double-quote. |
| //Italics// | {{{//Italics//}}} |
| ''//Bold Italics//'' | {{{''//Bold Italics//''}}} |
| __Underline__ | {{{__Underline__}}} |
| --Strikethrough-- | {{{--Strikethrough--}}} |
| Super^^script^^ | {{{Super^^script^^}}} |
| Sub~~script~~ | {{{Sub~~script~~}}} |
| @@Highlight@@ | {{{@@Highlight@@}}} |
| <nowiki>PlainText No ''Formatting''</nowiki> | {{{ <nowiki>PlainText No ''Formatting''</nowiki> }}} |
! Block Elements
!! Headings
!<nowiki>!</nowiki>Heading Level 1
!!<nowiki>!!</nowiki>Heading Level 2
!!!<nowiki>!!!</nowiki>Heading Level 3
!!!!<nowiki>!!!!</nowiki>Heading Level 4
!!!!!<nowiki>!!!!!</nowiki>Heading Level 5
!!!!!!<nowiki>!!!!!!</nowiki>Heading Level 6
!! Unordered Lists
!!! Example
* Unordered List, Level 1
** Unordered List, Level 2
*** Unordered List, Level 3
!!!Mark-Up Used
{{{
* Unordered List, Level 1
** Unordered List, Level 2
*** Unordered List, Level 3
}}}
!! Ordered Lists
!!! Example
# Ordered List, Level 1A
# Ordered List, Level 1B
## Ordered List, Level 2A
### Ordered List, Level 3A
!!! Mark-Up Used
{{{
# Ordered List, Level 1A
# Ordered List, Level 1B
## Ordered List, Level 2A
### Ordered List, Level 3A
}}}
!! Definition Lists
!!! Example
; term
: description
!!! Mark-Up Used
{{{
; term
: description
}}}
!! Blockquotes
!!! Example
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3
!!! Mark-Up Used
{{{
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3
}}}
!!! Block Example
<<<
blockquote
<<<
!!! Mark-Up Used
{{{
<<<
blockquote
<<<
}}}
!! Preformatted
!!! Example
{{{
preformatted (e.g. code)
}}}
!!! Markup Used
<nowiki>{{{</nowiki>
<nowiki>preformatted (e.g. code)</nowiki>
<nowiki>}}}</nowiki>
!! Tables
{{annotation{There is also an in-depth article on [[Tables]].}}}
Columns are delimited by a single pipe character ({{{|}}}); a new line creates a new row.
!!!Example
|CssClass|k
|!heading column 1|!heading column 2|h
|row 1, column 1|row 1, column 2|
|row 2, column 1|row 2, column 2|
|>|COLSPAN|
|ROWSPAN| … |
|~| … |
|CssProperty:value;…| … |
|caption|c
!!!Markup
{{{
|CssClass|k
|!heading column 1|!heading column 2|h
|row 1, column 1|row 1, column 2|
|row 2, column 1|row 2, column 2|
|>|COLSPAN|
|ROWSPAN| … |
|~| … |
|CssProperty:value;…| … |
|caption|c
}}}
Notes:
* The {{{>}}} marker creates a "colspan", causing the current cell to merge with the one to the right.
* The {{{~}}} marker creates a "rowspan", causing the current cell to merge with the one above.
!! Images
See [[tiddlywiki.com|http://www.tiddlywiki.com/#EmbeddedImages]]
! Links
* [[WikiWord|WikiWords]] are automatically transformed to hyperlinks to the respective tiddler
** the automatic transformation can be suppressed by preceding the respective WikiWord with a tilde ({{{~}}}): {{{~WikiWord}}}
* [[PrettyLinks]] are enclosed in double square brackets and contain the desired tiddler name: {{{[[tiddler name]]}}}
** optionally, a custom title or description can be added, separated by a pipe character ({{{|}}}): {{{[[title|target]]}}} ''N.B.:'' The target can also be any website (i.e. URL), folder or file.
!! Examples
* a simple website (URL) requires no markup: {{{http://domain.tld}}}
* website (URL) : {{{[[label|http://domain.tld]]}}}
* Unix-style folder: {{{[[label|file:///folder/file]]}}}
* Windows drive-mapped folder {{{[[label|file:///c:/folder/file]]}}}
* Windows network share: {{{[[label|file://///server/folder/file]]}}}
* File in a local subfolder of the TiddlyWiki location: {{{[[label|folder/file]]}}}
! Custom Styling
* inline styles: {{{@@CssProperty:value;CssProperty:value;...@@}}} ''N.B.:''' CSS color definitions should use lowercase letters to prevent the inadvertent creation of WikiWords.
* class wrapper: <nowiki>{{customClass{...}}}</nowiki>
!! Example
{{indent{
lorem ''ipsum'' dolor '''sit''' amet
}}}
(The <code>indent</code> is provided by the TiddlyWiki core in [[StyleSheetLayout]].)
! Inserting HTML
raw HTML can be inserted by enclosing the respective code in HTML tags ({{{<html>...</html>}}}).
! Avoiding Wikificitation ==
To prevent wiki markup from taking effect for a particular section (e.g. special characters), that section can be enclosed in three double quotes: e.g. {{{"""WikiWord"""}}} (cf. [[Escaping]]).
! Special Markers
* {{{<br>}}} forces a manual line break
* {{{----}}} and {{{<hr>}}} create a horizontal rule
* [[HTML entities|http://www.tiddlywiki.com/#HtmlEntities]]
* {{{>}}} calls the respective [[Macros|macro]]
* To hide text within a tiddler so that it is not displayed, it can be wrapped in {{{/%}}} and {{{%/}}}. This can be a useful trick for hiding drafts or annotating complex markup.
! See Also
* [[Wiki Markup]]
* [[Multi-Line Contents]]
* [[Tiddler format]] (TiddlyWiki markup version / Cheat Sheet)
* [[Macros]]
* [[Customization]]
Takes four arguments lookupField,lookupValue,lookupMatch,sortField (optional)
Loops through all tiddlers in the store to find all tiddlers with lookupField set to lookupValue.
lookupField can be a tiddler attribute or a tiddler field, however at the current time doesn't support modifier, creator, modified or created (See trac ticket [[1440|http://trac.tiddlywiki.org/ticket/1440]] for progress on this issue)
* If lookupMatch is set to false, it will return all the tiddlers where the lookupField ''does not match'' lookupValue.
* If lookupMatch is set to true, all tiddlers where the lookupField ''matches'' lookupValue will be returned.
If sortField is not given sorts by title by default.
The TabMoreMissing tiddler contains a command to list all of the tiddlers that have links to them but are undefined.
{{{
<<list missing>>
}}}
In TiddlyWiki this list appears as default in the {{{Missing}}} tab on the right-hand menu.
The tiddler macro allows you to [[transclude|Tranclusion]] the text of other tidders, or sections of other tiddlers, into your current tiddler.
!!Basic Usage
The basic usage is:
{{{
<<tiddler tiddlerToTransclude>>
}}}
This displays as:
<<<
<<tiddler tiddlerToTransclude>>
<<<
Have a look at the actual [[tiddlerToTransclude]] tiddler.
!!Transcluding Sections and Slices
Instead of transcluding an entire tiddler, you can also transclude individual [[slices|Slice]] or [[sections|Section]]:
{{{
<<tiddler [[Title::sliceLabel]]>>
<<tiddler [[Title##sectionHeading]]>>
}}}
!!Parameterised Transclusion
Using the {{{with:}}} parameter, placeholders in the transcluded content can be replaced with a desired value. For example:
{{{
<<tiddler anotherTiddlerToTransclude with:"Jim" "Oz">>
}}}
Which displays as:
<<<
<<tiddler anotherTiddlerToTransclude with:"Jim" "Oz">>
<<<
Have a look at the actual [[anotherTiddlerToTransclude]].
The refreshTiddler method of the [[Story]] class re-renders a tiddler's source code on the page through the given template. It takes three parameters:
* the title of the tiddler to display
* the template to use for display. You should use either the constant //~DEFAULT_VIEW_TEMPLATE// or //~DEFAULT_EDIT_TEMPLATE// in most cases.
* a boolean representing whether to force re-rendering even if the tiddler and template has not changed, or if there are unsaved changes to the tiddler.
This method returns an DOM element reference to the tiddler on the page.
Note this is a destructive event which will force the complete re-rendering of a tiddler in the story re-executing any macros within a template will be re-executed so much be used wisely.
{{{
story.displayTiddler(TiddlerName);
}}}
E.g.
{{{
story.displayTiddler('SiteTitle');
}}}
Versions of TiddlyWiki before and including 2.6.3 are known to have an issue with the upgrade function. To upgrade these versions you will need to download an empty latest version of TiddlyWiki and import your content into it using the "import" function in the backstage. See [[Upgrading from TiddlyWiki version 2.6.3 or before]].
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="78 222 60 60"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<g>
<path d="M 107.92718 244.14815 L 86.651474 222.89253 L 78.85206 230.69925 L 100.120415 251.9476 L 78.774 273.27396
L 86.57342 281.08075 L 107.927216 259.74707 L 129.39981 281.19946 L 137.19922 273.39267 L 115.73397 251.94763
L 137.121155 230.58054 L 129.32175 222.77374 Z" fill="black" class="glyph"/>
</g>
</g>
</svg>
'''Interactive delete'''
Open the tiddler for editing. Click on Delete (grey menu at top right of tiddler).
'''Consider installing the TrashPlugin'''
See http://ido-xp.tiddlyspot.com/#TrashPlugin
This allows a delete to be undone
However you will want to Empty The Trash Regularly as you can't reuse a tiddler name until it is really deleted.
'''Deleting a Tiddler which is also a Tag'''
When you have "Reference Needed"
Deleting a Tiddler which is also a Tag will prompt you with "remove tag from N tiddlers"
'''Batch Delete'''
This can be achieved by using Tiddler Tweaker Plugin:
http://www.TiddlyTools.com/#TiddlerTweakerPlugin
You can also use Export Tiddlers Plugin:
http://www.TiddlyTools.com/#ExportTiddlersPlugin
Or using the DelleteAllTagged bookmarklet
http://lewcid.org/tiddlywiki-bookmarklets/
A bookmarklet is a small piece of JavaScript code, which you can save as a bookmark.
[[Category:FAQ]]
[[Category:Using TiddlyWiki]]
Click on 'new tiddler' (top right-hand menu). A new tiddler will open.
To name the tiddler, type over the words 'new tiddler' in the top text box.
Enter the tiddler's contents into the main text box.
Click on Done (grey menu at top right of tiddler).
To add the tiddler to the menuu, see [[Add Menu Item]].
This text has been transcluded from another tidder.
This script allows you to convert lists to wiki links.
{{{
<script label="L2W" title="convert list to wikilinks">
var here=story.findContainingTiddler(place);
if (!here) return;
var title=here.getAttribute("tiddler");
var tid=store.getTiddler(title);
var t=store.getTiddlerText(tiddler.title) ;
var target = store.getTiddler(tiddler.title) ;
var txt='[['+tid.text.split('\n').join(']]\n[[')+']]';
store.saveTiddler
(tid.title,tid.title,txt,tid.modifier,tid.modified,tid.tags,tid.fields);
</script>
}}}
Paste a line seperated list into a tiddler then "run" the script on the list to get double bracketed list items.
Source: Måns Mårtensson http://groups.google.com/group/tiddlywiki/browse_thread/thread/a8922becd1f29938#
The [[glossary|http://glossary.tiddlyspace.com]] is a [[Space]] defining the terminology used in TiddlySpace. The glossary is included in documentation [[spaces|Space]] such as @docs and @tiddlyspace. Feel free to add it to your [[Space]].
<<list filter [tag[term]]>>
This behaviour requires a plugin to be installed. Install SinglePageModePlugin from http://tiddlytools.com. See [[How do I install a plugin?]] for more info.
/***
|''Name''|ErrorHandlerPlugin|
|''Version''|0.4.3|
|''Author''|Jon Robson|
|''Description''|Localised tiddler save errors including edit conflict resolution.|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
tiddlyspace.getLocalTitle = function(title, workspace, suffix) {
var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
if(!suffix) {
var isPublic = endsWith(workspace, "_public");
suffix = tiddlyspace.resolveSpaceName(workspace);
if(currentSpace == suffix) {
suffix = isPublic ? "public" : "private";
} else {
suffix = "@%0".format(suffix);
}
}
return "%0 *(%1)*".format(title, suffix);
};
var sssp = config.extensions.ServerSideSavingPlugin;
var msgs = config.messages.editConflict = {
loading: "Loading..",
resolve: "[[Edit Conflict]]@glossary: this tiddler may have been changed by someone else.",
reviewDiff: "review (recommended)",
reviewDiffTooltip: "review changes made to this tiddler",
reviewDiffError: "error retrieving revision.",
save: "overwrite",
saveTooltip: "make this revision the top revision of this tiddler",
discard: "cancel",
discardTooltip: "undo changes to this tiddler and get most recent version",
diffTitle: "%0",
diffFieldTitle: "%0 - fields",
diffTextTitle: "%0 - text",
updating: "updating your version...",
diffHeader: ["Review the changes that have been made whilst you were editing this tiddler. ",
"Fold relevant changes back into your version.\n",
"{{removed{Red}}} highlight shows content removed. ",
"{{added{Green}}} highlight shows content added.\n"].join(""),
diffTextHeader: "View changes in text",
diffFieldsHeader: "View changes in fields"
};
var plugin = config.extensions.errorHandler = {
diffTags: ["excludeLists", "excludeMissing", "excludeSearch"],
displayMessage: function(message, tiddler, context) {
var desc = context && context.httpStatus ? context.statusText :
sssp.locale.connectionError;
var reportArea = plugin.reportError(tiddler.title);
var msg = $("<div />").appendTo(reportArea);
if(message == "saveConflict") {
wikify(msgs.resolve, msg[0]);
var choiceArea = $("<div />").appendTo(reportArea)[0];
plugin.editConflictHandler(choiceArea, tiddler);
} else {
msg.text(sssp.locale[message].format(tiddler.title, desc));
}
},
editConflictHandler: function(container, tiddler) {
var title = tiddler.title;
var myrev = tiddler.fields["server.page.revision"];
// note user now needs to edit, fix problem and save.
// TODO: make sure this gets reset in save callback
store.getTiddler(title).fields["server.page.revision"] = "false";
var diffBtn = createTiddlyButton(container, msgs.reviewDiff, msgs.reviewDiffTooltip, function(ev) {
var title = $(ev.target).data("title");
plugin.displayDiff(ev.target, store.getTiddler(title), myrev);
});
var saveBtn = createTiddlyButton(container, msgs.save, msgs.saveTooltip, function(ev) {
var title = $(ev.target).data("title");
var tid = store.saveTiddler(store.getTiddler(title));
autoSaveChanges(null, [tid]);
});
var ignoreBtn = createTiddlyButton(container, msgs.discard, msgs.discardTooltip, function(ev) {
var title = $(ev.target).text(msgs.updating).data("title");
plugin.resetToServerVersion(store.getTiddler(title));
});
$([diffBtn, ignoreBtn, saveBtn]).data("title", title);
},
getDiffTiddlerTexts: function(diffText) {
var chunks = diffText.split("\n \n");
if(chunks.length < 2) {
return [chunks[0], ""];
} else {
var diffFieldsText = "{{diff{\n%0\n}}}".format(chunks[0]);
diffText = '{{diff{\n%0\n}}}'.format(chunks.splice(1, chunks.length).join("\n"));
return [diffText, diffFieldsText];
}
},
makeDiffTiddler: function(title, diff) {
var newTiddler = new Tiddler(title);
var tags = plugin.diffTags;
newTiddler.text = msgs.loading;
newTiddler.fields.doNotSave = true;
newTiddler.tags = diff ? tags.concat(["diff"]) : tags;
newTiddler = store.saveTiddler(newTiddler);
$.extend(store.getTiddler(title).fields,
config.defaultCustomFields); // allow option to save it
return newTiddler;
},
displayDiff: function(src, tiddler, latestRevision) {
var adaptor = tiddler.getAdaptor();
var title = tiddler.title;
var ts = new Date().formatString("0hh:0mm:0ss");
var suffix = "edit conflict %0".format(ts);
var diffTitle = tiddlyspace.getLocalTitle(msgs.diffTitle.format(title), "", suffix);
var diffTextTitle = tiddlyspace.getLocalTitle(msgs.diffTextTitle.format(title), "", suffix);
var diffFieldsTitle = tiddlyspace.getLocalTitle(msgs.diffFieldTitle.format(title), "", suffix);
plugin.makeDiffTiddler(diffTextTitle, true);
plugin.makeDiffTiddler(diffFieldsTitle, true);
var newTiddler = plugin.makeDiffTiddler(diffTitle, false);
newTiddler.text = ['%0\n<<slider chkViewDiffText "%1" "%2">>\n',
'<<slider chkViewDiffField "%3" "%4">>'].join("").
format(msgs.diffHeader, diffTextTitle, msgs.diffTextHeader,
diffFieldsTitle, msgs.diffFieldsHeader);
store.saveTiddler(newTiddler);
var callback = function(r) {
var text = plugin.getDiffTiddlerTexts(r);
store.getTiddler(diffTextTitle).text = text[0];
store.getTiddler(diffFieldsTitle).text = text[1];
story.refreshTiddler(diffTitle, null, true);
};
var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
ajaxReq({
type: "get",
dataType: "text",
url: "/diff?format=unified&rev1=%0/%1/%2&rev2=%0/%1".format(workspace, title, latestRevision),
success: callback,
error: function() {
displayMessage(msgs.reviewDiffError);
}
});
story.displayTiddler(src, diffTitle);
},
resetToServerVersion: function(tiddler) {
var adaptor = tiddler.getAdaptor();
var ctx = {
host: tiddler.fields["server.host"],
workspace: "bags/" + tiddler.fields["server.bag"]
};
adaptor.getTiddler(tiddler.title, ctx, null, function(context) {
store.saveTiddler(context.tiddler);
story.refreshTiddler(tiddler.title);
store.setDirty(false);
});
},
reportError: function(title) {
var el = story.getTiddler(title);
if(!el) {
el = story.displayTiddler(null, title);
}
return $("<div />").addClass("error annotation").prependTo(el)[0];
}
};
sssp.reportFailure = function(message, tiddler, context) {
config.options.chkViewDiffText = config.options.chkViewDiffText === undefined ?
true : config.options.chkViewDiffText;
config.options.chkViewDiffFields = config.options.chkViewDiffFields || false;
plugin.displayMessage(message, tiddler, context);
};
})(jQuery);
//}}}
ControlView is the mechanism which TiddlySpace employs to prevent the serving of content from other [[spaces|Space]] which would otherwise available via [[recipes|Recipe]] and [[bags|Bag]] sharing the same TiddlyWeb instance.
Without ControlView, it would be possible to construct a URI to serve content from {{{evilspace}}} which //appeared// to belong to the {{{goodspace}}} domain, for example: http://goodspace.tiddlyspace.com/recipes/evilspace_public/tiddlers/all_good_is_evil this is compounded by the ability for a TiddlySpace to be served by their [[Own Domain]].
Prevent a WikiWord from automatically becoming a link by putting a tilde character (~) in front of it. For example, to prevent BMWs and McDonalds from becoming tiddler links, insert the ~ char like this:
<nowiki>Take the ~BMWs to ~McDonalds</nowiki>
'' DisableWikiLinksPlugin ''
The [http://www.tiddlytools.com/#DisableWikiLinksPlugin DisableWikiLinksPlugin] gives several options to customize automatic WikiWord linking, such as disabling it completely or only for tiddlers which don't already exist. After importing the plugin, these options must be enabled manually in the DisableWikiLinksPlugin tiddler; it may also be necessary to close and re-open the TiddlyWiki browser page before using the plugin for the first time.
All options are off by default, so settings applied by one user/in one browser will not be active for others. If you want to ensure that your options are in effect for, say, Web viewers, you can create a tiddler, e.g. DisableWikiLinksDefault, with a [[systemConfig]] tag and content like this:
<nowiki>
config.options.chkDisableWikiLinks=false;
config.options.chkAllowLinksFromShadowTiddlers=false;
config.options.chkDisableNonExistingWikiLinks=false;
config.options.txtDisableWikiLinksList="DisableWikiLinksList";
config.options.txtDisableWikiLinksTag="excludeWikiWords";
</nowiki>
Set the values to the defaults you prefer (e.g. change "false" to "true").
'' See Also ''
* [[WikiWords]]
* [[Escaping#Wiki_Markup]]
[[Category:FAQ]]
[[Category:Using TiddlyWiki]]
This page is meant as an overview of the basic TiddlyWiki architecture.
* [[store|Store]] (The [[TiddlyWiki Class]])
* [[story|Dev:Story]]
* [[notifications|config.options.notify]]
* [[wikifier|Dev:Wikifier]]
* [[formatters|Dev:Formatters]]
* [[macros|Dev:Macros]]
* [[toolbar commands|Dev:Toolbar Commands]]
* [[saving|Dev:FileSystem]]
* [[adaptors|Dev:Server Adaptor Mechanism]]
Wikitext is a markup language that describes how text should be formatted (for example it allows you to mark specific text as being in bold). There is a space dedicated to explaining this language at @wikitext
Add the following to any tiddler:
<nowiki><<version>></nowiki>
The [[Version (macro)|version macro]] will show you the version number of your TiddlyWiki document.
If you're feeling adventurous, you could also look at the source code of
your document; near the top, there will be a section looking like this:
major: 2, minor: 2, revision: 6, date: new Date("Oct 18, 2007")
In this case, that would be v2.2.6.
/***
|''Name''|TiddlySpaceTiddlerIconsPlugin|
|''Version''|0.8.10|
|''Status''|@@beta@@|
|''Author''|Jon Robson|
|''Description''|Provides ability to render SiteIcons and icons that correspond to the home location of given tiddlers|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceTiddlerIconsPlugin.js|
|''Requires''|TiddlySpaceConfig BinaryTiddlersPlugin ImageMacroPlugin TiddlySpacePublishingCommands|
!Notes
{{{<<tiddlerOrigin>>}}} shows the origin of the tiddler it is being run on.
In TiddlySpace terms this means it will determine whether the tiddler is external, public or private.
Where private it will analyse whether a public version exists and distinguish between the different scenarios.
If a tiddler is external, the SiteIcon of that external space will be shown
!Parameters
width / height : define a width or height of the outputted icon
label: if label parameter is set to yes, a label will accompany the icon.
!Code
***/
//{{{
(function($) {
if(!config.macros.image) {
throw "Missing dependency: ImageMacroPlugin";
}
var imageMacro = config.macros.image;
var tiddlyspace = config.extensions.tiddlyspace;
var tweb = config.extensions.tiddlyweb;
var cmds = config.commands;
var cmd = cmds.publishTiddler;
tiddlyspace.resolveSpaceName = function(value) {
var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
if(value) {
value = value.indexOf("bags/") === 0 ? value.substr(5) : value;
value = value.indexOf("recipes/") === 0 ? value.substr(8) : value;
if(value.indexOf("@") === 0) {
value = value.substr(1);
}
if(endsWith(value, "_public")) {
value = value.substr(0, value.length - 7);
} else if(endsWith(value, "_private")) {
value = value.substr(0, value.length - 8);
}
value = value.toLowerCase();
}
return value;
};
tiddlyspace.renderAvatar = function(place, value, options) {
options = options ? options : {};
options.labelOptions = options.labelOptions ? options.labelOptions : { include: false, height: 48, width: 48 };
options.imageOptions = options.imageOptions ? options.imageOptions : {};
options.imageOptions.altImage = "/bags/common/tiddlers/defaultUserIcon";
var container = $('<div class="siteIcon" />').appendTo(place);
value = tiddlyspace.resolveSpaceName(value);
tweb.getStatus(function(status) {
var link, noLabel;
if(!value || value == config.views.wikified.defaultModifier ||
value == config.views.wikified.shadowModifier) {
var icon = config.views.wikified.shadowModifier == value ? "shadowIcon" : "missingIcon";
if(store.tiddlerExists(icon)) {
imageMacro.renderImage(container, icon, options.imageOptions);
} else {
noLabel = true;
}
} else {
var spaceURI;
if(value != tiddlyspace.currentSpace.name) {
spaceURI = options.notSpace ? tiddlyspace.getHost(status.server_host) :
tiddlyspace.getHost(status.server_host, value);
}
link = spaceURI ? $("<a />").attr("href", spaceURI) : $("<span />");
link.text(value);
var imageOptions = options.imageOptions;
if(options.spaceLink && !imageOptions.link) {
imageOptions.link = spaceURI;
}
var avatar = options.notSpace ? false : value;
var uri = tiddlyspace.getAvatar(status.server_host, avatar);
imageMacro.renderImage(container, uri, options.imageOptions);
if(!value) {
value = "tiddlyspace";
}
}
if(!noLabel && options.labelOptions.include) {
var prefix = $("<span />").text(options.labelOptions.prefix || "")[0];
var suffix = $("<span />").text(options.labelOptions.suffix || "")[0];
$('<div class="label" />').append(prefix).append(link).
append(suffix).appendTo(container);
}
});
if(value) {
var prefix = options.labelOptions.prefix || "";
var suffix = options.labelOptions.suffix || "";
var label = "%0%1%2".format(prefix, value, suffix);
$(container).attr("title", label);
}
};
var originMacro = config.macros.tiddlerOrigin = {
locale: {
"shadow": "shadow tiddler",
"missing": "missing tiddler",
"private": "private",
"unknown": "unknown state",
"public": "public",
"unsyncedPrivate": "unsynced and private",
"unsyncedPublic": "unsynced and public",
externalPrefix: "from ",
externalBagSuffix: " bag",
externalSuffix: " space",
publishPrivateDeletePrivate: "Are you sure you want to make this tiddler public?",
moveToPrivate: "Are you sure you want to make this tiddler private? Only members will be able to see it.",
pleaseWait: "please wait..",
keepPublic: "keep public",
cannotPublishDirtyTiddler: "The current tiddler is unsaved so cannot be published. Please save the tiddler first.",
keepPrivate: "keep private",
makePublic: "make public",
makePrivate: "make private"
},
handler: function(place, macroName, params,wikifier, paramString, tiddler){
var adaptor = tiddler.getAdaptor();
var btn = $("<div />").addClass("originButton").attr("params", paramString).
attr("refresh", "macro").attr("macroName", macroName).appendTo(place)[0];
$(btn).data("tiddler", tiddler);
originMacro.refresh(btn);
},
refresh: function(btn) {
$(btn).empty();
var paramString = $(btn).attr("params");
var tiddler = $(btn).data("tiddler");
var options = originMacro.getOptions(paramString);
var type = tiddlyspace.getTiddlerStatusType(tiddler);
originMacro.renderIcon(tiddler, type, btn, options);
},
getOptions: function(paramString) {
paramString = "%0 label:no width:48 height:48 spaceLink:yes preserveAspectRatio:yes".format(paramString);
var parsedParams = paramString.parseParams("name");
var params = parsedParams[0].name;
var options = {
labelOptions: originMacro._getLabelOptions(parsedParams),
imageOptions: imageMacro.getArguments(paramString, []),
noclick: parsedParams[0].interactive &&
parsedParams[0].interactive[0] == "no" ? true : false
};
if(!options.noclick) {
var spaceLink = parsedParams[0].spaceLink;
options.spaceLink = spaceLink && spaceLink[0] == "no" ? false : true;
} else {
options.spaceLink = false;
}
return options;
},
_getLabelOptions: function(parsedParams) {
parsedParams = parsedParams[0];
var includeLabel = !parsedParams.label || ( parsedParams.label && parsedParams.label[0] == "yes" );
var prefix = parsedParams.labelPrefix ? parsedParams.labelPrefix[0] : false;
var suffix = parsedParams.labelSuffix ? parsedParams.labelSuffix[0] : false;
return { include: includeLabel, suffix: suffix, prefix: prefix };
},
_isSpace: function(value) {
value = value ? value : "";
var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
if(endsWith(value, "_private") || endsWith(value, "_public")) {
return true;
} else {
return false;
}
},
renderIcon: function(tiddler, type, button, options) {
var locale = originMacro.locale;
originMacro.annotateTiddler(button, type);
if(type != "external") {
originMacro.showPrivacyRoundel(tiddler, type, button,
options);
} else {
var prefix = options.labelOptions.prefix, suffix = options.labelOptions.suffix;
var space = tiddler.fields["server.bag"];
options.notSpace = !originMacro._isSpace(space);
options.labelOptions.prefix = prefix ? prefix : locale.externalPrefix;
options.labelOptions.suffix = suffix ? suffix : (options.notSpace ? locale.externalBagSuffix : locale.externalSuffix);
tiddlyspace.renderAvatar(button, space, options);
}
},
showPrivacyRoundel: function(thisTiddler, privacyType, button, options) {
// there is a public tiddler as well as the current tiddler!
// TODO: not this is not enough.. we also need to check if the public tiddler is the same as..
// .. the private tiddler to determine whether this is a draft
// use of hashes would be useful here.
$(button).empty();
var icon = "%0Icon".format(privacyType);
if(privacyType.indexOf("unsynced") === 0 && !store.tiddlerExists(icon)) {
icon = "unsyncedIcon";
}
if(privacyType == "shadow") {
if(!store.tiddlerExists(icon)) {
icon = "bags/tiddlyspace/tiddlers/SiteIcon";
}
}
if(privacyType == "missing" && !store.tiddlerExists(icon)) {
return; // the user is not making use of the missingIcon
} else {
imageMacro.renderImage(button, icon, options.imageOptions);
originMacro.showLabel(button, privacyType, options.labelOptions);
var cmd = originMacro.iconCommands[privacyType];
if(cmd && thisTiddler && !options.noclick) {
$(button).click(function(ev) {
cmd(ev, thisTiddler);
});
}
}
},
annotateTiddler: function(place, type) {
var tidEl = $(story.findContainingTiddler(place));
tidEl.
removeClass("private public external privateAndPublic privateNotPublic shadow").
addClass(type);
},
showLabel: function(button, type, options) {
var locale = originMacro.locale;
var label = options.label ? options.label : locale[type];
label = label ? label : locale.unknown;
if(options && options.include) {
$('<div class="roundelLabel" />').html(label).appendTo(button);
}
$(button).attr("title", label);
},
confirm: function(ev, msg, onYes, options) {
options = options ? options : {};
onYes = onYes ? onYes : function(ev) {};
var btn = $(".originButton", $(ev.target).parents())[0];
var popup = Popup.create(btn);
$(popup).addClass("confirmationPopup");
$("<div />").addClass("message").text(msg).appendTo(popup);
$("<button />").addClass("button").text(options.yesLabel || "yes").appendTo(popup).click(onYes);
$("<button />").addClass("button").text(options.noLabel || "no").click(function(ev) {
Popup.remove();
}).appendTo(popup);
Popup.show();
ev.stopPropagation();
return false;
},
alert: function(ev, msg) {
var popup = Popup.create(ev.target);
$(popup).addClass("confirmationPopup alert");
$("<div />").addClass("message").text(msg).appendTo(popup);
Popup.show();
ev.stopPropagation();
},
reportDirty: function(el) {
originMacro.alert(el, originMacro.locale.cannotPublishDirtyTiddler);
},
iconCommands: {
"public": function(ev, tiddler) {
if(!readOnly) {
var locale = originMacro.locale;
var msg = locale.moveToPrivate;
if(story.isDirty(tiddler.title)) {
originMacro.reportDirty(ev);
} else {
originMacro.confirm(ev, msg, function(ev) {
var target = $(ev.target);
var onComplete = function(info) {};
var privateBag = cmd.toggleBag(tiddler, "private");
cmd.moveTiddler(tiddler, {
title: tiddler.title,
fields: { "server.bag": privateBag }
}, onComplete);
}, { yesLabel: locale.makePrivate, noLabel: locale.keepPublic });
}
}
},
"private": function(ev, tiddler) {
if(!readOnly) {
var locale = originMacro.locale;
var adaptor = tiddler.getAdaptor();
var publishTo = tiddler.fields["publish.name"] || tiddler.title;
var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
tiddler.fields["server.workspace"] = workspace;
var publicBag = cmd.toggleBag(tiddler, "public");
var msg;
msg = locale.publishPrivateDeletePrivate;
var title = tiddler.title;
var newTitle = publishTo || tiddler.title;
tiddler.fields["server.page.revision"] = "false";
store.addTiddler(tiddler);
if(story.isDirty(tiddler.title)) {
originMacro.reportDirty(ev);
} else {
originMacro.confirm(ev, msg, function(ev) {
var onComplete = function(info) {};
cmd.moveTiddler(tiddler, {
title: newTitle,
fields: { "server.bag": publicBag }
}, onComplete);
}, { yesLabel: locale.makePublic, noLabel: locale.keepPrivate });
}
}
}
}
};
})(jQuery);
//}}}
The ''getOrphaned'' method of a [[TiddlyWiki class|TiddlyWiki]] object returns an array of strings, each the name of an orphaned tiddler (a tiddler with no links to it). This array is sorted by name.
It takes no parameters and is used like this;
{{{
store.getOrphans();
}}}
Line breaks can be forced explicitly:
{{{
Some text with a<br>line break in the middle
}}}
Displays as:
Some text with a<br>line break in the middle
The ''closeTiddler'' method of the [[Story]] class closes a single tiddler from the page. It takes three parameters in this order:
* the title of the tiddler
* a boolean value indicating whether to animate closing the tiddler
* a boolean value indicating whether to animate slowly. To see this in action, hold down the Shift, Option, or Alt key while clicking the ''close'' button for a tiddler.
You would use it in a plugin like so:
{{{
story.closeTiddler('tiddlerTitle', true, false);
}}}
This function does not return any value.
/***
|''Name''|GroupByPlugin|
|''Description''|Mimics allTags macro to provide ways of creating lists grouping tiddlers by any field|
|''Version''|0.6.1|
|''Author''|Jon Robson|
|''Status''|beta|
!Usage
{{{<<groupBy tags>>}}}
mimics allTags macro
{{{<<groupBy server.bag>>}}}
groups by the server.bag field (this version contains TiddlySpace specific code for turning a bag into a space name)
{{{groupBy modified dateFormat:"YYYY"}}}
group tiddlers by year.
{{{<<groupBy tags exclude:excludeLists exclude:systemConfig>>}}}
group tiddlers by tag but exclude the tags with values excludeLists and systemConfig
Within that group you can also exclude things by filter
{{{groupBy modifier filter:[tag[film]]}}}
will group tiddlers tagged with film by modifier.
***/
//{{{
(function($) {
var taglocale = config.views.wikified.tag;
var macro = config.macros.groupBy = {
locale: {
tooltip: "all tiddlers in group %0",
noTiddlers: "no tiddlers",
openAllText: taglocale.openAllText,
openAllTooltip: taglocale.openAllTooltip,
openTiddler: "open tiddler with title %0"
},
morpher: {
// TODO: note currently the following 2 morphers are TiddlySpace specific and probably should be in separate plugin
"server.workspace": function(value, options) {
return macro.morpher["server.bag"](value.replace("bags/", "").replace("recipes/", ""));
},
"server.bag": function(value, options) {
if(typeof(value) !== "string") {
return false;
} else if(value.indexOf("_public") === -1 && value.indexOf("_private") === -1) {
value = "*%0".format(value); // add star for non-space bags.
}
return value.replace("_public", "").replace("_private", "");
},
created: function(value, options) {
return value.formatString(options.dateFormat || "DD MMM YYYY");
},
modified: function(value, options) {
return macro.morpher.created(value, options);
}
},
handler: function(place, macroName, params, wikifier, paramString) {
var field = params[0] || "server.workspace";
var dateFormat = params[1] || "DD MMM YYYY";
var container = $("<div />").attr("macroName", macroName).addClass("groupBy").
attr("refresh", "macro").attr("fieldName", field).
attr("paramString", paramString).
attr("dateFormat", dateFormat).appendTo(place)[0];
macro.refresh(container);
},
isTypeArray: function(value) {
var valueType = typeof value;
if(valueType === "object" && typeof value.length === "number" &&
!(value.propertyIsEnumerable("length")) &&
typeof value.splice === "function") { //is Array
return true;
} else {
return false;
}
},
_onClickGroup: function(ev, options) {
var i, target = ev.target, locale = macro.locale;
var tiddlers = $(target).closest(".templateContainer").data("tiddlers");
var popup = $(Popup.create(target)).addClass("taggedTiddlerList")[0];
var value = $(target).attr("value");
var openAll = createTiddlyButton($("<li />").appendTo(popup)[0],
locale.openAllText.format(value), locale.openAllTooltip);
$(openAll).click(function(ev) {
story.displayTiddlers(ev.target, tiddlers);
return false;
});
var listBreak = $("<li />").addClass("listBreak").html("<div />").appendTo(popup);
for(i = 0; i < tiddlers.length; i++) {
var item = $("<li />").appendTo(popup)[0];
var template = store.getTiddlerText(options.template) || macro.template;
wikify(template, item, null, tiddlers[i]);
}
listBreak.clone().appendTo(popup);
$(createTiddlyLink($("<li />").appendTo(popup)[0], value, false)).
text(locale.openTiddler.format(value));
Popup.show();
ev.stopPropagation();
return false;
},
_refresh: function(container, tiddlers, options) {
var totalGroups = 0, locale = macro.locale, i, j;
var excludeValues = options.exclude;
var values = {}, value_ids = [];
var field = options.field;
var morpher = macro.morpher[field] || function(value) {
return value;
};
for(i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var value = tiddler[field] || tiddler.fields[field];
value = macro.isTypeArray(value) ? value : [ value ];
for(j = 0; j < value.length; j++) {
var v = morpher(value[j], options);
if(v && excludeValues.indexOf(v) === -1) {
totalGroups += 1;
if(!values[v]) {
values[v] = [];
}
values[v].push(tiddler);
value_ids.pushUnique(v);
}
}
}
var ul = $("<ul />").appendTo(container)[0];
if(totalGroups === 0) {
$("<li />").addClass("listTitle").text(locale.noTiddlers);
}
value_ids = value_ids.sort();
var groupTemplate = store.getTiddlerText(options.groupTemplate);
var onClick = function(ev) {
macro._onClickGroup(ev, options);
};
for(i = 0; i < value_ids.length; i++) {
var title = value_ids[i];
var info = getTiddlyLinkInfo(title);
tiddlers = values[title];
var btn = createTiddlyButton($("<li />").appendTo(ul)[0],
"%0 (%1)".format(title, tiddlers.length), locale.tooltip.format(title), null, info.classes);
if(groupTemplate) {
$(btn).empty();
wikify(groupTemplate, btn, null, tiddlers[0]);
}
$(btn).click(onClick).attr("value", title).attr("refresh", "link").attr("tiddlyLink", title);
$(btn).addClass("templateContainer").data("tiddlers", tiddlers);
}
},
refresh: function(container) {
container = $(container).empty();
var paramString = container.attr("paramString");
var args = paramString.parseParams("name", null, true, false, true)[0];
var options = { field: container.attr("fieldName"), dateFormat: container.attr("dateFormat"), exclude: args.exclude || [],
template: args.template ? args.template[0] : false, groupTemplate: args.groupTemplate ? args.groupTemplate[0] : "" };
var tiddlers = args.filter ? store.filterTiddlers(args.filter[0]) : store.getTiddlers("title");
macro._refresh(container, tiddlers, options);
},
template: "<<view title link>>"
};
}(jQuery));
//}}}
/***
|''Name''|TiddlySpaceFilters|
|''Description''|provide TiddlySpace-specific filter extensions|
|''Author''|Jon Robson|
|''Version''|0.6.1|
|''Status''|@@beta@@|
|''CoreVersion''|2.6.2|
|''Requires''|TiddlySpaceConfig|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<tsList Private>>
<<tsList Public>>
<<tsList Draft>>
}}}
!Code
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var privateBag = tiddlyspace.getCurrentBag("private");
var publicBag = tiddlyspace.getCurrentBag("public");
config.filterHelpers = {
is: {
"private": function(tiddler) {
var bag = tiddler.fields["server.bag"];
return bag == privateBag;
},
"public": function(tiddler) {
var bag = tiddler.fields["server.bag"];
return bag == publicBag;
},
draft: function(tiddler) {
var fields = tiddler.fields;
var bag = fields["server.bag"];
return (privateBag == bag && fields["publish.name"]) ? true : false;
},
local: function(tiddler) {
return config.filterHelpers.is["public"](tiddler) ||
config.filterHelpers.is["private"](tiddler);
},
unsynced: function(tiddler) {
return tiddler ? tiddler.isTouched() : false;
}
}
};
config.filters.is = function(results, match) {
var candidates = store.getTiddlers("title");
var type = match[3];
for (var i = 0; i < candidates.length; i++) {
var tiddler = candidates[i];
var helper = config.filterHelpers.is[type];
if(helper && helper(tiddler)) {
results.pushUnique(tiddler);
}
}
return results;
};
})(jQuery);
//}}}
The slider macro allows embedding tiddlers within another tiddler, with the option to toggle the visibility of the [[transclusion|transcluded]] content:
{{{
<<slider cookie tiddler label tooltip>>
}}}
* {{{cookie}}}: variable to save the state of the slider (e.g. {{{chkFooSlider}}})
* {{{tiddler}}}: name of the tiddler to include in the slider
* {{{label}}}: title text of the slider
* {{{tooltip}}}: tooltip text of the slider
For example:
{{{
<<slider chkTestSlider [[OptionsPanel]] "Options" "Open advanced options">>
}}}
/***
|''Name''|DiffFormatter|
|''Description''|highlighting of text comparisons|
|''Author''|FND|
|''Version''|0.9.0|
|''Status''|beta|
|''Source''|http://svn.tiddlywiki.org/Trunk/contributors/FND/formatters/DiffFormatter.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Keywords''|formatting|
!Description
Highlights changes in a unified [[diff|http://en.wikipedia.org/wiki/Diff#Unified_format]].
!Notes
Based on Martin Budden's [[DiffFormatterPlugin|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/DiffFormatterPlugin.js]].
!Usage
The formatter is applied to blocks wrapped in <html><code>{{{diff{..}}}</code></html> within tiddlers tagged with "diff".
!Revision History
!!v0.9 (2010-04-07)
* initial release; fork of DiffFormatterPlugin
!StyleSheet
.diff { white-space: pre; font-family: monospace; }
.diff ins, .diff del { display: block; text-decoration: none; }
.diff ins { background-color: #dfd; }
.diff del { background-color: #fdd; }
.diff .highlight { background-color: [[ColorPalette::SecondaryPale]]; }
!Code
***/
//{{{
(function() {
config.shadowTiddlers.StyleSheetDiffFormatter = store.getTiddlerText(tiddler.title + "##StyleSheet");
store.addNotification("StyleSheetDiffFormatter", refreshStyles);
var formatters = [{
name: "diffWrapper",
match: "^\\{\\{diff\\{\n", // XXX: suboptimal
termRegExp: /(.*\}\}\})$/mg,
handler: function(w) {
var el = createTiddlyElement(w.output, "div", null, "diff");
w.subWikifyTerm(el, this.termRegExp);
}
}, {
name: "diffRange",
match: "^(?:@@|[+\\-]{3}) ",
lookaheadRegExp: /^(?:@@|[+\-]{3}) .*\n/mg,
handler: function(w) {
createTiddlyElement(w.output, "div", null, "highlight").
innerHTML = "…";
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
}, {
name: "diffAdded",
match: "^\\+",
termRegExp: /(\n)/mg,
handler: function(w) {
var el = createTiddlyElement(w.output, "ins", null, "added");
w.subWikifyTerm(el, this.termRegExp);
}
}, {
name: "diffRemoved",
match: "^-",
termRegExp: /(\n)/mg,
handler: function(w) {
var el = createTiddlyElement(w.output, "del", null, "removed");
w.subWikifyTerm(el, this.termRegExp);
}
}
];
config.parsers.diffFormatter = new Formatter(formatters);
config.parsers.diffFormatter.format = "diff";
config.parsers.diffFormatter.formatTag = "diff";
})();
//}}}
/***
|''Name''|EditTemplateFieldsPlugin|
|''Version''|0.4.6|
|''Status''|beta|
|''Author''|Jon Robson|
|''Description''|Provides editing of custom fields|
|''Requires''||
|''Source''||
!Usage
put {{{<div macro="editFields"></div>}}} into your EditTemplate.
or {{{<div macro="viewFields"></div>}}} into your ViewTemplate.
!Todo
Support newlines in input boxes.
!Code
***/
//{{{
(function($) {
var viewFields = config.macros.viewFields = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var fields = editFields.getFields(tiddler).concat(params);
var done = {};
for(var i = 0; i < fields.length; i++) {
var name = fields[i];
var val = tiddler.fields[name];
if(!done[name] && val) {
done[name] = true;
$("<div class='fieldValue' />").text("%0 : %1".format(name, val)).appendTo(place);
}
}
}
};
var editFields = config.macros.editFields = {
fieldType: {
images: ["image", "geo.marker"]
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var options = {
fields: params
};
this.createInterface(place, tiddler, options);
},
getFields: function(tiddler) {
var whitelisted = ["changecount"];
var fields = [];
for(var i in tiddler.fields) {
var val = tiddler.fields[i];
if(i.indexOf("server.") !== 0 && i.indexOf("_") !== 0 && typeof(val) == "string" && !whitelisted.contains(i) && val) {
fields.push(i);
}
}
return fields;
},
createInterface: function(place, tiddler, options) {
var fieldContainer = $("<div class='tiddlerCustomFields' />").appendTo(place);
var included = [];
if(tiddler) {
var fields = editFields.getFields(tiddler);
for(var i = 0; i < fields.length; i++) {
var name = fields[i];
var val = tiddler.fields[name];
this.addNewField(fieldContainer, name, val);
included.push(name);
}
}
for(var j = 0; j < options.fields.length; j++) {
var field = options.fields[j];
if(!included.contains(field)) {
this.addNewField(fieldContainer, field, "");
}
}
$("<button />").text("add new field").click(function() {
editFields.addNewField(fieldContainer, "", "");
}).appendTo(place);
},
addNewField: function(place, name, value) {
var container = $("<div />").appendTo(place);
if(editFields.fieldType.images.contains(name)) {
valueInput = $("<select />");
$("<option />").val("").text("").appendTo(valueInput);
$.each(store.filterTiddlers("[is[image]]"), function(i, tiddler) {
var opt = $("<option />").val(tiddler.title).text(tiddler.title).appendTo(valueInput)[0];
if(value === tiddler.title) {
$(opt).attr("selected", true);
}
});
} else {
type = value.indexOf("\n") > -1 ? "textarea" : "text";
var valueInput = type == "text" ? $("<input type='text' />") : $("<textarea />");
}
valueInput.attr("edit", name).val(value).appendTo(container);
$("<button class='delete' />").text("delete").click(function(ev) {
var answer = confirm("Are you sure you want to remove this field?");
if(answer) {
var attr = $(ev.target).attr("field");
var p = $(ev.target).parent();
$("[edit]", p).val("");
$(p).hide();
}
}).appendTo(container);
var nameInput = $("<input class='fieldName' type='text' />").val(name).
change(function(ev) {
var el = $(ev.target);
valueInput.attr("edit", el.val());
}).prependTo(container);
}
}
})(jQuery);
//}}}
This is a method that has been added to the standard String object. It is used to parse a space-separated string of name:value parameters that are usually given to a TiddlyWiki macro. It is used by calling it on a string like so:
{{{
str.parseParams(args....);
}}}
It takes upto 5 arguments (defaultName,defaultValue,allowEval,noNames,cascadeDefaults).
* defaultName - used as the key of key value pair if lone words used.
* defaultValue - used as the value of key value pair if lone words used.
* allowEval - if 'true' allows you to use [[evaluated parameters|Evaluated Parameters]], evaluated parameters are not allowed in TiddlySpace.
* noNames - if ''true'' then string is just split on the spaces.
* cascadeDefaults - if 'true' takes the first lone word or first key as the key for all subsequent lone words until another key:valur pair is parsed. At which point that because the key for any lone words that follow.
The result is an array of objects:
* result[0] = object with a member for each parameter name/key, value of that member being an array of values
* result[1..n] = one object for each parameter, with 'name' and 'value' members
!!Examples
Simplest, for string only containing key:value pairs
{{{
str = "foo:bar";
str.parseParams(null, null, false, false, false);
}}}
returns
{{{
result[0] = { foo=["bar"] }
result[1] = { name="foo", value="bar" }
}}}
Containing a mix
{{{
str = "test foo:bar";
str.parseParams("xyz", null, false, false, false);
}}}
returns
{{{
result[0] = { xyz="test", foo=["bar"] }
result[1] = { name="xyz", value="test" }
result[2] = { name="foo", value="bar" }
}}}
needs review...
Using the [[NewTiddler (macro)|newTiddler macro]] [[Macros|Core Macros]], newly-created tiddlers can be "preloaded" with boilerplate contents.
These predefined contents can either be entered directly, or retrieved from another tiddler.
!!Examples
{{{
<<newTiddler label:"new record"
text:"foo"
tag:"bar"
>>
}}}
{{{
<<newTiddler label:"new record"
text:{{store.getTiddlerText("bar")}}
tag:"bar"
>>
}}}
Both of these macro calls will create a button with
* the label/caption "new record"
* the tag "bar"
While the former macro creates a tiddler with "foo" as predefined content, the latter will add the contents from the tiddler called "bar" to the newly created tiddler.
To close all open tiddlers:
{{{
<<closeAll>>
}}}
Displays as:
<<closeAll>>
''Note to everyone''
This FAQ is under construction and quite incomplete, yet it is a start. If you can contribute questions and answers that would be great.
''FAQ''
''Basics''
* [[What is TiddlyWiki?]]
* [[What can I do with TiddlyWiki?]]
* [[What do I need to run TiddlyWiki?]]
* [[Can I use TiddlyWiki as a multi-user/collaborative/server based wiki?]]
''Getting Started''
* [[Getting your own TiddlyWiki file]]
* [[Configuring your browser to allow saves to disk]]
* [[I put my TiddlyWiki file on my web server and I can't save]]
''Using TiddlyWiki''
* [[Autosave]]
* [[Add Menu Item]]
* [[Special Characters and Symbols|Adding Special characters and symbols to TiddlyWiki content]]
* [[Create Tiddler]]
* [[Delete Tiddler]]
* [[TiddlyWiki on the iPhone|Does TiddlyWiki work on an iPhone?]]
* [[Change where backups are saved]]
* [[Editing and saving a tiddler]]
* [[Find a tiddler]]
* [[TiddlyWiki markup|Formatting Text]]
* [[How do I deactivate a wiki word?]]
* [[How do I link to a tiddler without a wiki word name?]]
* [[How do I make searching work better?]]
* [[Insert a Picture]]
* [[Is there a WYSIWYG version of TiddlyWiki?]]
* [[Keyboard Shortcuts|KeyboardShortcuts]]
* [[Naming a TiddlyWiki]]
* [[PersistentOptions|http://tiddlywiki.com/#PersistentOptions]]
* [[Resize Image]]
* [[Saving the file]]
* [[Tags]]
* [[TiddlyWiki Markup]]
* [[URL Commands|StartupParameters]]
* [[What is a tiddler?]]
* [[What is a wiki word?|WikiWord]]
* [[Where can I get nightly builds of the TiddlyWiki trunk?]]
* [[How do I know what version I'm running?]]
* [[Broken links in Firefox]]
''Troubleshooting''
* [[How big can my file get before it gets too slow/doesn't work?|PerformanceIssues]]
* [[I keep getting "A script is making this page run slow" in Firefox]]
* [[My settings don't get saved]]
* [[Special characters are not displaying correctly]]
* [[Lots of spaces get changed to one space|PreserveSpaces]]
* [[I get 'Permission denied to call method XMLHttpRequest.open' when using UploadPlugin or ImportTiddlers]]
* [[Getting "failed to save" in FF or "Permission Denied" in IE?]]
''Configuration''
* [[Can I make it only show one tiddler at a time like a regular wiki?]]
* [[Can I use MediaWiki style markup instead of the built in TiddlyWiki markup. Or Twiki or Trac style markup?]]
* [[How do I change the date format for new journals?]]
* [[How do I change how a tiddler looks?]]
* [[How do I change how tiddler editing looks?]]
* [[How do I change my default options?|http://tiddlywiki.com/#PersistentOptions]]
* [[How do I change the colours and the fonts?]]
* [[How do I change the layout of my TiddlyWiki?]]
* [[How do I change the RSS behaviour, so that changing a tiddler creates a new RSS post]]
* [[How do I have a different tiddler toolbar for web users?]]
* [[How do I make my table cells vertically aligned?]]
* [[How do I right-justify some text in a tiddler?]]
* [[How do I justify all the text in every tiddler?]]
* [[Shadow Tiddlers]]
''Customization''
*[[Where do I store my created plugin?]]
''Tips and Tricks''
* [[How can I make a "home" button that opens just the default tiddlers?]]
* [[How can use my logo as the SiteTitle but still have text in the html page title?]]
* [[How do I right-justify some text in a tiddler?]]
* [[How do I justify all the text in every tiddler?]]
* [[How do I make my table cells vertically aligned?]]
* [[How can I encrypt some of my data?]]
* [[How can I avoid all text being selected when I edit a tiddler?]]
''Macros''
* [[What is a macro?]]
* [[Core_Macros|What macros are built in to TiddlyWiki?]]
* [[What about commands?]]
''Plugins ''
* [[How do I install a plugin?]]
* [[What is a plugin?]]
* [[Where do I find plugins?]]
* [[Plugin recommendations|Which plugins should I use for the task at hand?]]
''For Developers''
* [[TiddlyWiki Development Space|http://tiddlywikidev.tiddlyspace.com/]]
* [[TiddlyWiki Family Development Spaces]]
''Getting Things Done (GTD)''
* [[What is GTD?]]
* [[Can I use TiddlyWiki for GTD?]]
''Indexes''
In the spirit of TagglyTagging these could perhaps replace the manual list above...
* '''[[:Category:FAQ|FAQ Index]]'''
* '''[[:Category:FAQ Section|FAQ Categories]]'''
This macro displays the current date and time.
!Usage
{{{
<<today [dateFormat]>>
}}}
(cf. Date Formats) also: try the date format in quotes if the regular format doesn't work for you
<<tagcloud filter:"[is[local]]" exclude:excludeLists exclude:excludeSearch exclude:excludePublisher>>
Each [[space|Space]] is identified by a [[Space Name]] which may only contain lowercase letters, digits or hyphens. The [[Space Name]] is unique to a TiddlySpace server, and appears as the [[subdomain]] for the server. For example the space {{{glossary}}} on the server http://tiddlyspace.com may be reached at http://glossary.tiddlyspace.com
/***
|''Name''|TiddlyFileImporter|
|''Version''|0.3.8|
|''Author''|Ben Gillies|
|''Type''|plugin|
|''Description''|Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.|
!Usage
Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.
!Requires
tiddlyweb
tiddlywebplugins.reflector
!Code
***/
//{{{
(function($){
if(!version.extensions.TiddlyFileImporter)
{ //# ensure that the plugin is only installed once
version.extensions.TiddlyFileImporter = { installed: true };
}
config.macros.fileImport = {
reflectorURI: '/reflector?csrf_token=%0',
incorrectTypeError: 'Incorrect File Type. You must upload a TiddlyWiki',
uploadLabel: 'Upload',
uploadLabelPrompt: 'Import tiddlers from this TiddlyWiki',
step1FileText: 'File:',
step1URLText: 'URL:',
step1PostText: 'In the next screen you will select the tiddlers to import.',
step1Title: 'Step 1: Pick a TiddlyWiki to import',
step1TypeChooser: 'Import From:',
step3Html: ['<input type="hidden" name="markList" />',
'<input type="hidden" checked="true" name="chkSync" />',
'<input type="hidden" name="chkSave" />',
'<input type="hidden" name="txtSaveTiddler" />'].join(),
handler: function(place, macroName, params, wikifier, paramString) {
var wizard = new Wizard();
wizard.createWizard(place, 'Import a TiddlyWiki');
this.restart(wizard);
},
restart: function(wizard) {
var me = config.macros.fileImport;
wizard.addStep(me.step1Title, ['<input type="hidden" ',
'name="markList" />'].join(""));
var markList = wizard.getElement('markList');
var uploadWrapper = document.createElement('div');
markList.parentNode.insertBefore(uploadWrapper, markList);
uploadWrapper.setAttribute('refresh', 'macro');
uploadWrapper.getAttribute('macroName', 'fileImport');
var iframeName = 'reflectorImporter' + Math.random().toString();
me.createForm(uploadWrapper, wizard, iframeName);
$(uploadWrapper).append('<p>' + me.step1PostText + '</p>');
wizard.setValue('serverType', 'tiddlyweb');
wizard.setValue('adaptor', new config.adaptors.file());
wizard.setValue('host', config.defaultCustomFields['server.host']);
wizard.setValue('context', {});
var iframe = $(['<iframe name="' + iframeName + '" ',
'style="display: none" />'].join("")).appendTo(uploadWrapper);
var onSubmit = function(ev) {
var uploadType = $('select[name=uploadtype]', wizard.formElem).val();
if (uploadType == "file") {
// set an onload ready to hijack the form
me.setOnLoad(uploadWrapper, wizard, iframe[0]);
wizard.importType = 'file';
wizard.formElem.submit();
} else {
var csrf_token = config.extensions.tiddlyspace.getCSRFToken();
$.ajax({
url: "%0/reflector?csrf_token=%1".format(
config.defaultCustomFields["server.host"], csrf_token),
type: "POST",
dataType: "text",
data: {
uri: $("input", ".importFrom", wizard.formElem).val()
},
success: function(data, txtStatus, xhr) {
wizard.POSTResponse = data;
me.importTiddlers(uploadWrapper, wizard);
},
error: function(xhr, txtStatus, error) {
displayMessage(["There was an error fetching the ",
'url: ', txtStatus].join(""));
me.restart(wizard);
}
});
return false;
}
};
wizard.setButtons([{
caption: me.uploadLabel,
tooltip: me.uploadLabelPrompt,
onClick: onSubmit
}]);
$(wizard.formElem).submit(function(ev) {
onSubmit(ev);
ev.preventDefault();
});
},
createForm: function(place, wizard, iframeName) {
var form = wizard.formElem;
var me = config.macros.fileImport;
form.action = me.reflectorURI.format(
config.extensions.tiddlyspace.getCSRFToken());
form.enctype = 'multipart/form-data';
form.encoding = 'multipart/form-data';
form.method = 'POST';
form.target = iframeName;
onSelectChange = function(e) {
var changeTo = $(this).val();
if (changeTo == "file") {
$(".importFrom").html('%0 <input type="file" name="file" />'.
format(me.step1FileText));
} else {
$(".importFrom").html('%0 <input type="text" name="uri" />'.
format(me.step1URLText));
}
};
$(place).append('<span>%0</span>'.format(me.step1TypeChooser)).
append($(['<select name="uploadtype"><option value="file" selected="selected">file',
'<option value="uri">url</select>'].join("")).change(onSelectChange)).
append('<div class="importFrom">%0<input type="file" name="file" /></div>'.
format(me.step1FileText));
},
setOnLoad: function(place, wizard, iframe) {
var me = config.macros.fileImport;
var loadHandler = function() {
me.importTiddlers.apply(this, [place, wizard, iframe]);
};
iframe.onload = loadHandler;
completeReadyStateChanges = 0;
iframe.onreadystatechange = function() {
if (++(completeReadyStateChanges) == 5) {
loadHandler();
}
};
},
importTiddlers: function(place, wizard, iframe) {
var tmpStore = new TiddlyWiki();
var POSTedWiki = "";
if (wizard.importType == "file") {
try {
POSTedWiki= iframe.contentWindow
.document.documentElement.innerHTML;
} catch(e) {
displayMessage(config.macros.fileImport.incorrectTypeError);
config.macros.fileImport.restart(wizard);
return;
}
// now we are done, so remove the iframe
$(iframe).remove();
} else {
POSTedWiki = wizard.POSTResponse;
}
tmpStore.importTiddlyWiki(POSTedWiki);
var newTiddlers = tmpStore.getTiddlers();
var workspace = config.defaultCustomFields['server.workspace'];
var context = {
status: true,
statusText: 'OK',
httpStatus: 200,
adaptor: wizard.getValue('adaptor'),
tiddlers: newTiddlers
};
context.adaptor.store = tmpStore;
wizard.setValue('context', context);
wizard.setValue('workspace', workspace);
wizard.setValue('inFileImport', true);
config.macros.importTiddlers.onGetTiddlerList(context, wizard);
}
};
var _onGetTiddler = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
if (wizard.getValue('inFileImport')) {
var me = config.macros.importTiddlers;
if(!context.status)
displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
var tiddler = context.tiddler;
var fields = tiddler.fields;
merge(fields, config.defaultCustomFields);
fields["server.workspace"] = wizard.getValue('workspace');
delete fields['server.permissions'];
delete fields['server.bag'];
fields['server.page.revision'] = 'false';
delete fields['server.recipe'];
fields.changecount = 1;
store.suspendNotifications();
store.saveTiddler(tiddler.title, tiddler.title, tiddler.text,
tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields,
false, tiddler.created);
store.resumeNotifications();
var remainingImports = wizard.getValue("remainingImports")-1;
wizard.setValue("remainingImports",remainingImports);
if(remainingImports === 0) {
if(context.isSynchronous) {
store.notifyAll();
refreshDisplay();
}
wizard.setButtons([
{caption: me.doneLabel, tooltip: me.donePrompt, onClick: me.onClose}
],me.statusDoneImport);
autoSaveChanges();
}
} else {
_onGetTiddler.apply(this, arguments);
}
};
var _onCancel = config.macros.importTiddlers.onCancel;
config.macros.importTiddlers.onCancel = function(e)
{
var wizard = new Wizard(this);
if (!wizard.getValue('inFileImport')) {
return _onCancel.apply(this, arguments);
}
var place = wizard.clear();
config.macros.fileImport.restart(wizard);
return false;
};
var _step3Html = config.macros.importTiddlers.step3Html;
var _onGetTiddlerList = config.macros.importTiddlers.onGetTiddlerList;
config.macros.importTiddlers.onGetTiddlerList = function(context, wizard) {
var fileImport = config.macros.fileImport;
var importTiddlers = config.macros.importTiddlers;
if (wizard.getValue('inFileImport')) {
importTiddlers.step3Html = fileImport.step3Html;
} else {
importTiddlers.step3Html = _step3Html;
}
_onGetTiddlerList.apply(this, arguments);
};
})(jQuery);
//}}}
/*{{{*/
body {
font-size: 1em;
font-family: helvetica, arial, sans-serif;
background-color: #fff;
color: [[ColorPalette::Foreground]];
}
body ul { margin: 0; }
#popup {
background-color: [[ColorPalette::TertiaryPale]];
}
#popup.confirmationPopup, .followList {
font-size: 0.8em;
padding: 1em;
border: solid 1px [[ColorPalette::SecondaryMid]];
background-color: [[ColorPalette::SecondaryPale]];
}
.followList .listTitle {
text-decoration: underline;
}
#popup .followTiddlersList a {
display: inline;
padding: 0;
}
#popup li a {
color: [[ColorPalette::PrimaryMid]];
font-weight: bold;
}
#popup li a:hover {
color: [[ColorPalette::PrimaryPale]];
background: [[ColorPalette::PrimaryMid]];
}
#popup li.listTitle {
border-bottom: 1px solid #000;
font-weight: bold;
margin-bottom: 10px;
}
#popup.followList {
margin-left: 50px;
margin-top: -30px;
}
.followTiddlersList .label {
display: block;
left: 10px;
top: 0px;
line-height: 16px;
position: relative;
}
#popup .followTiddlersList .siteIcon{
height: auto;
}
#popup .followTiddlersList li{
clear: both;
display: block;
height: 48px;
margin-bottom: 8px;
position: relative;
}
#popup .followTiddlersList a{
display: inline;
}
#displayArea {
margin: 0;
top: 0px;
left: 0px;
width: 100%;
position: relative;
}
.revisionCloak {
position: absolute;
position: fixed !important;
height: 100%;
width: 100%;
top: 0;
left: 0;
border: 0;
margin: 0;
padding: 0;
opacity: 0.5;
filter: alpha(opacity=50);
background-color: #000;
}
/* *** Header *** */
.header {
position: relative;
background-color: [[ColorPalette::PrimaryMid]];
_width: 100%; /* ie 6 demands */
}
.headerForeground {
background-color: [[ColorPalette::PrimaryMid]];
float: left;
margin: 24px 16px 0px 72px;
padding: 0;
position: relative;
top: 0;
_width: 70%; /*ie6: needed for the background to actually be transparent*/
_background-color: transparent; /*ie6: needed to show the search box*/
}
.clearFloat {
clear: both;
}
#contentWrapper {
position: relative;
padding-top: 1px;
top: -1px;
}
#tiddlerDisplay {
_position: relative; /* ie 6*/
}
.siteTitle {
clear: both;
display: block;
font-size: 32px;
font-weight: bold;
line-height: 32px;
}
.siteSubtitle {
display: block;
font-size: 14px;
height: 16px;
margin-bottom: 8px;
}
#sidebarSearch {
padding: 0;
position: absolute;
right: 80px;
top: 8px;
width: 176px;
}
#sidebarSearch .txtOptionInput {
width: 100%;
margin-top: 5px;
_color: #bbb; /* ie6 danger */
}
#sidebarSearch .txtOptionInput:focus {
color: #000;
}
#sidebarSearch .searchButton {
display: none;
}
/* *** Menu Bar *** */
#mainMenu {
position: static;
text-align: left;
margin-left: 72px;
float: left;
width: auto;
padding: 0;
font-size: 1em;
line-height: normal;
}
#mainMenu a {
color: #fff;
padding: 8px;
font-size: 0.9em;
margin-right: 16px;
}
#mainMenu a:hover {
background-color: [[ColorPalette::PrimaryMid]];
color: [[ColorPalette::Background]]
}
#sidebarOptions {
margin-right: 72px;
float: right;
font-size: 1.1em;
line-height: 1.6em;
min-height: 1em;
padding-top: 0;
}
#sidebarOptions a {
margin-right: 8px;
}
.confirmationPopup .button,
#sidebarOptions .button {
cursor: pointer;
line-height: 1.4em;
text-align: center;
margin-right: 8px;
margin-left:-2px;
}
.confirmationPopup .button {
font-size: 0.9em;
padding: 2px;
}
#sidebarOptions .button {
font-size: 0.7em;
float: left;
width: 80px;
padding: 0px;
color: #fff;
}
.confirmationPopup a.button,
#sidebarOptions a {
border: none;
margin: 0 0.2em;
padding: 0.6em 0.25em;
display: inline;
color: #666;
}
.confirmationPopup a.button:hover,
#sidebarOptions a:hover {
color: #000;
}
.confirmationPopup a.button:active,
#sidebarOptions a:active {
border: solid 1px [[ColorPalette::PrimaryMid]];
background-color: #fff;
background: -webkit-gradient( linear, left bottom, left top, color-stop(0.1,rgb(200,200,200)), color-stop(1, rgb(100,100,100)));
background: -moz-linear-gradient(center bottom , rgb(200,200,200) 10%,rgb(100,100,100) 100%) repeat scroll 0 0 transparent;
}
/* *** Sidebar *** */
#sidebar .wizard table {
margin: 0px;
}
.tabContents .listTitle:first-child {
margin-top: 0px;
}
#menuBar {
background: [[ColorPalette::PrimaryLight]];
left: 0;
right: 0;
position: relative;
margin: 0;
padding: 0.5em 0 0.5em 0;
min-height: 1em;
overflow: hidden;
_width: 100%; /* for ie 6 */
}
#sidebarOptions a.button:hover {
color: [[ColorPalette::PrimaryPale]];
background: [[ColorPalette::PrimaryMid]];
}
#tiddlerDisplay, #searchResults {
margin: 16px 448px 0 72px;
}
#sidebarTabs {
position: absolute;
right: 72px;
width: 352px;
top: 0;
}
#sidebarTabs .tabsetWrapper .tabset {
width: 87px;
border-top: 1px solid [[ColorPalette::PrimaryPale]];
border-left: 1px solid [[ColorPalette::PrimaryPale]];
border-bottom: 1px solid [[ColorPalette::PrimaryPale]];
height: auto;
float: left;
word-wrap: break-word;
top: 0;
padding: 0;
}
#sidebarTabs .tabsetWrapper .tabContents {
background-color: [[ColorPalette::PrimaryPale]];
border: 3px solid [[ColorPalette::PrimaryMid]];
width: 242px;
_width: 238px;
left: -3px;
_left: -5px;
position: relative;
min-height: 34em;
padding: 8px;
font-size: 0.8em;
}
/* ---- Side style --- */
#sidebarTabs .tabsetWrapper .tabset .tab {
font-size: 0.9em;
padding: 0.7em 8px 0.5em;
color: #fff;
background: [[ColorPalette::PrimaryLight]];
border: none;
line-height: 16px;
position: relative;
display: block;
margin: 0;
}
#sidebarTabs .tabsetWrapper .tabset .tabSelected {
color: [[ColorPalette::PrimaryMid]];
background: [[ColorPalette::PrimaryPale]];
border-top: 3px solid [[ColorPalette::PrimaryMid]];
border-bottom: 3px solid [[ColorPalette::PrimaryMid]];
border-left: 3px solid [[ColorPalette::PrimaryMid]];
z-index: 10;
margin-top: -1px;
font-weight: bold;
}
#sidebarTabs .tabContents li {
border: none;
margin-left: 0;
word-wrap: break-word;
}
.tabContents .timeline {
background: [[ColorPalette::PrimaryPale]];
margin-bottom: 8px;
}
#sidebarTabs .timeline li.listTitle {
color: #132E43;
margin-left: 8px 0;
padding: 0.3em 0.11em;
font-size: 1em;
border-bottom: none;
}
#sidebarTabs .tabContents li a {
display: block;
text-align: left;
margin: 0 0 1px 0;
padding: 0.3em 1em;
background: [[ColorPalette::PrimaryPale]];
}
#sidebarTabs .tabsetWrapper .tabset a:hover,
#sidebarTabs .tabContents li a:hover {
color: [[ColorPalette::PrimaryPale]];
background: [[ColorPalette::PrimaryMid]];
}
/* Activity Stream */
#sidebarTabs .tabContents .activityStream .feedItem a {
display: inline-block;
padding: 0;
background: none;
}
/* ---- Tagging box --- */
.tagInfo {
border: 1px solid #cccccc;
padding: 10px 15px;
-moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 2px rgba(0,0,0,0.2);
color: [[ColorPalette::TertiaryMid]];
background: -moz-linear-gradient(100% 100% 90deg, #f4f4f4, #e5e5e5);
background: -webkit-gradient(linear, left top, right top, from(#e5e5e5), to(#f4f4f4));
margin-top: 1em;
font-size: 13px;
margin: 0 0 0 56px;
}
.tagInfo ul {
list-style: none;
padding-left: 2.2em;
}
.tagInfo ul li {
display: inline;
}
.tagInfo ul li.listTitle,
.tagInfo .tagging ul li.listTitle {
color: [[ColorPalette::PrimaryMid]];
font-size: 13px;
}
.tagInfo ul li a {
border: none;
}
.tagInfo .tagging ul li {
float: none;
display: inline-block;
}
.tagInfo .tagging {
padding: 0;
}
.viewRevision .toolbar {
right: 48px;
top: 8px;
}
.viewRevision .modifierIcon img,
.viewRevision .modifierIcon svg {
margin-right: 8px;
}
.viewRevision .toolbar svg {
width: 32px;
height: 32px;
}
/* --- IE hacks from lattice --- */
/* ie hacks */
* html #menuBar {
margin-bottom: 8px;
}
.toolbar .svgIconText {
*display: inline;
}
div.tiddler .toolbar a {
cursor: pointer;
float: left\9;
display: inline\9;
}
* html .toolbar {
right: 8px;
}
* html .followButton a {
margin-top: 0px;
margin-right: 8px;
}
* html #tiddlerDisplay {
margin-top: 0px;
}
/* for printing purposes */
@media print {
#mainMenu,
#sidebar,
#messageArea,
.toolbar,
.followPlaceHolder,
#backstageButton,
#backstageArea,
#sidebarTabs,
#sidebarSearch .txtOptionInput,
#sidebarOptions {
display: none !important;
}
#displayArea {
margin: 1em 1em 0em;
}
noscript {
display:none; /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
#tiddlerDisplay {
margin: 16px 16px;
}
}
@media all and (max-width: 960px){
#tiddlerDisplay,
#searchResults {
margin: 16px 366px 0 16px;
}
#mainMenu {
margin-left: 16px;
}
.headerForeground {
margin-left: 16px;
}
#sidebarSearch {
right: 16px;
}
#sidebarOptions {
margin-right: 16px;
}
#sidebarTabs {
right: 16px;
width: 326px;
}
#sidebarTabs .tabsetWrapper .tabset {
font-size: 0.9em;
width: 77px;
}
#sidebarTabs .tabsetWrapper .tabContents {
width: 226px;
_width: 222px;
}
#sidebarTabs .tabContents li a {
font-size: 0.9em;
}
}
/*}}}*/
[[StyleSheetTiddler]]
(function($) {
var sudo = function(fn) {
if(document.location.protocol.indexOf("file") == 0 && window.Components &&
window.netscape && window.netscape.security) {
window.netscape.security.PrivilegeManager.
enablePrivilege("UniversalBrowserRead");
}
return fn();
};
// hijack ajax function to provide enhanced privileges
var ajax = $.ajax;
$.ajax = function() {
var self = this;
var args = arguments;
return sudo(function() {
return ajax.apply(self, args);
});
};
})(jQuery);
TiddlySpace is a service for creating and curating small [[packets of content|Tiddler]] on The Web. You may [[collaborate with others|Small Trusted Group]], assemble content by [[including spaces|What is space inclusion?]]@faq, add [[cool features|Extensions]]@about using [[plugins|Plugin]]@security and mix your content with other services using the [[API|TiddlySpace API]].
TiddlySpace is [[Open Source|http://en.wikipedia.org/wiki/Open_source]] software from [[Osmosoft]] so you're free to host your own instance on your own domain and are encouraged to contribute to the [[project|http://github.com/TiddlySpace/tiddlyspace]]. TiddlySpace is based on the TiddlyWeb server-side TiddlyWiki implementation.
To set the default text alignment for all tiddlers, put something like this into your [[StyleSheet tiddler]]:
.viewer {
text-align: justify;
}
that CSS rule will fully justify your tiddler text.
/***
|''Name''|TiddlySpaceConfig|
|''Version''|0.7.7|
|''Description''|TiddlySpace configuration|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceConfig.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlyWebConfig ServerSideSavingPlugin TiddlyFileImporter|
!Code
***/
//{{{
(function($) {
var tweb = config.extensions.tiddlyweb;
var recipe = config.defaultCustomFields["server.workspace"].split("recipes/")[1];
var currentSpace; // assigned later
var disabledTabs = [];
var coreBags = ["system", "tiddlyspace"];
var systemSpaces = ["plugins", "info", "images", "theme"];
systemSpaces = $.map(systemSpaces, function(item, i) {
return "system-%0_public".format(item);
});
// hijack search macro to add custom attributes for mobile devices
var _search = config.macros.search.handler;
config.macros.search.handler = function(place, macroName, params) {
_search.apply(this, arguments);
$(".searchField:input", place).
attr({ autocapitalize: "off", autocorrect: "off" });
};
// arg is either a container name or a tiddler object
// if fuzzy is truthy, space may be inferred from workspace (for new tiddlers)
// returns space object or false
var determineSpace = function(arg, fuzzy) {
if(typeof arg == "string") { // container name
var space = split(arg, "_", "r");
return ["public", "private"].contains(space.type) ? space : false;
} else if(arg) { // tiddler
var container = determineContainer(arg, fuzzy);
return container ? determineSpace(container.name, fuzzy) : false;
} else {
return false;
}
};
// if fuzzy is truthy, container may be inferred from workspace for new tiddlers
// returns container object or false
var determineContainer = function(tiddler, fuzzy) { // TODO: expose?
var bag = tiddler.fields["server.bag"];
var recipe = tiddler.fields["server.recipe"]; // XXX: unused/irrelevant/redundant!?
if(bag) {
return { type: "bag", name: bag };
} else if(recipe) {
return { type: "recipe", name: recipe };
} else if(fuzzy) { // new tiddler
var workspace = tiddler.fields["server.workspace"];
if(workspace) {
var container = split(workspace, "/", "l");
return ["bags", "recipes"].contains(container.type) ? container : false;
} else {
return false;
}
} else {
return false;
}
};
// hijack removeTiddlerCallback to restore tiddler from recipe cascade -- TODO: move into TiddlyWebWiki?
var sssp = config.extensions.ServerSideSavingPlugin;
var _removeTiddlerCallback = sssp.removeTiddlerCallback;
sssp.removeTiddlerCallback = function(context, userParams) {
var title = context.tiddler.title;
var recipe = context.tiddler.fields["server.recipe"];
_removeTiddlerCallback.apply(this, arguments);
if(recipe) {
context.workspace = "recipes/" + recipe;
var callback = function(context, userParams) {
if(context.status) {
var dirty = store.isDirty();
store.saveTiddler(context.tiddler).clearChangeCount();
store.setDirty(dirty);
} else {
store.notify(title, true);
}
};
context.adaptor.getTiddler(title, context, null, callback);
}
};
// splits a string once using delimiter
// mode "l" splits at the first, "r" at the last occurrence
// returns an object with members type and name
var split = function(str, sep, mode) {
mode = mode == "r" ? "pop" : "shift"; // TODO: use +/-1 instead of "l"/"r"?
var arr = str.split(sep);
var type = arr.length > 1 ? arr[mode]() : null;
return { type: type, name: arr.join(sep) };
};
var plugin = config.extensions.tiddlyspace = {
currentSpace: determineSpace(recipe),
coreBags: coreBags.concat(systemSpaces),
determineSpace: determineSpace,
isValidSpaceName: function(name) {
return name.match(/^[a-z][0-9a-z\-]*[0-9a-z]$/) ? true : false;
},
getCurrentBag: function(type) {
return "%0_%1".format(currentSpace, type);
},
getCurrentWorkspace: function(type) {
return "bags/" + this.getCurrentBag(type);
},
// returns the URL for a space's avatar (SiteIcon) based on a server_host
// object and an optional space name
// optional nocors argument prevents cross-domain URLs from being generated
getAvatar: function(host, space, nocors) {
if(space && typeof space != "string") { // backwards compatibility -- XXX: deprecated
space = space.name;
}
var subdomain = nocors ? currentSpace : space;
host = host ? this.getHost(host, subdomain) : "";
var bag = space ? "%0_public".format(space) : "tiddlyspace";
return "%0/bags/%1/tiddlers/SiteIcon".format(host, bag);
},
// returns the URL based on a server_host object (scheme, host, port) and an
// optional subdomain
getHost: function(host, subdomain) {
if(host === undefined) { // offline
tweb.status.server_host = {}; // prevents exceptions further down the stack -- XXX: hacky workaround, breaks encapsulation
return null;
}
subdomain = subdomain ? subdomain + "." : "";
var url = "%0://%1%2".format(host.scheme, subdomain, host.host);
var port = host.port;
if(port && !["80", "443"].contains(port)) {
url += ":" + port;
}
return url;
},
disableTab: function(tabTiddler) {
if(typeof(tabTiddler) == "string") {
disabledTabs.push(tabTiddler);
} else {
for(var i = 0; i < tabTiddler.length; i++) {
plugin.disableTab(tabTiddler[i]);
}
}
},
isDisabledTab: function(tabTitle) {
var match = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])", "mg").exec(tabTitle);
var tabIdentifier = match ? match[1] : tabTitle;
return disabledTabs.contains(tabIdentifier);
},
getCSRFToken: window.getCSRFToken || null // this may not have been processed yet
};
currentSpace = plugin.currentSpace.name;
tweb.serverPrefix = tweb.host.split("/")[3] || ""; // XXX: assumes root handler
tweb.getStatus(function(status) {
var url = plugin.getHost(status.server_host);
tweb.status.server_host.url = url;
config.messages.tsVersion = status.version;
});
if(window.location.protocol == "file:") {
// enable AutoSave by default
config.options.chkAutoSave = config.options.chkAutoSave === undefined ?
true : config.options.chkAutoSave;
} else {
// set global read-only mode based on membership heuristics
var indicator = store.getTiddler("SiteTitle") || tiddler;
readOnly = !(recipe.split("_").pop() == "private" ||
tweb.hasPermission("write", indicator));
// replace TiddlyWiki's ImportTiddlers due to cross-domain restrictions
if(config.macros.fileImport) {
$.extend(config.macros.importTiddlers, config.macros.fileImport);
}
}
// hijack saveChanges to ensure SystemSettings is private by default
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
if(tiddlers && tiddlers.length == 1 &&
tiddlers[0] && tiddlers[0].title == "SystemSettings") {
var fields = tiddlers[0].fields;
delete fields["server.recipe"];
fields["server.bag"] = plugin.getCurrentBag("private");
fields["server.workspace"] = plugin.getCurrentWorkspace("private");
}
return _saveChanges.apply(this, arguments);
};
// ensure backstage is always initialized
// required to circumvent TiddlyWiki's read-only based handling
config.macros.backstageInit = {
init: function() {
showBackstage = true;
}
};
// disable evaluated macro parameters for security reasons
config.evaluateMacroParameters = "none";
var _parseParams = String.prototype.parseParams;
String.prototype.parseParams = function(defaultName, defaultValue, allowEval,
noNames, cascadeDefaults) {
if(config.evaluateMacroParameters == "none") {
arguments[2] = false;
}
return _parseParams.apply(this, arguments);
};
var _tabsMacro = config.macros.tabs.handler;
config.macros.tabs.handler = function(place, macroName, params) {
var newParams = [params[0]]; // keep cookie name
for(var i = 1; i < params.length; i += 3) {
var tabTitle = params[i + 2];
if(!plugin.isDisabledTab(tabTitle)){
newParams = newParams.concat(params[i], params[i + 1], tabTitle);
}
}
_tabsMacro.apply(this, [place, macroName, newParams]);
};
// disable ControlView for XHRs by default
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader("X-ControlView", "false");
}
});
// TiddlyWeb adaptor currently still uses httpReq, which needs extra magic -- XXX: obsolete this!
var _httpReq = httpReq;
httpReq = function(type, url, callback, params, headers, data, contentType,
username, password, allowCache) {
headers = headers || {};
headers["X-ControlView"] = "false";
_httpReq.apply(this, arguments);
};
// register style sheet for backstage separately (important)
store.addNotification("StyleSheetBackstage", refreshStyles);
// option for default privacy setting
config.optionsDesc.chkPrivateMode = "Set your default privacy mode to private";
config.optionsSource.chkPrivateMode = "setting";
config.options.chkPrivateMode = config.options.chkPrivateMode || false;
saveSystemSetting("chkPrivateMode", true);
config.defaultCustomFields["server.workspace"] = plugin.
getCurrentWorkspace(config.options.chkPrivateMode ? "private" : "public");
config.paramifiers.follow = {
onstart: function(v) {
if(!readOnly) {
var bag = "%0_public".format(currentSpace);
story.displayTiddler(null, v, DEFAULT_EDIT_TEMPLATE, null, null,
"server.bag:%0 server.workspace:bags/%0".format(bag));
story.setTiddlerTag(v, "follow", 1);
story.focusTiddler(v, "text");
}
}
};
var fImport = config.macros.fileImport;
if(fImport) {
fImport.uploadTo = "Upload to: ";
var _createForm = config.macros.fileImport.createForm;
config.macros.fileImport.createForm = function(place, wizard, iframeName) {
var container = $("<div />").text(fImport.uploadTo).appendTo(place);
var select = $('<select name="mode" />').appendTo(container)[0];
$('<option value="private" selected>private</a>').appendTo(select);
$('<option value="public">public</a>').appendTo(select);
wizard.setValue("importmode", select);
_createForm.apply(this, [place, wizard, iframeName]);
};
var _onGet = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
var type = $(wizard.getValue("importmode")).val();
var ws = plugin.getCurrentWorkspace(type);
wizard.setValue("workspace", ws);
_onGet.apply(this, [context, wizard]);
};
}
})(jQuery);
//}}}
You can use ~BidiX's UploadPlugin to enable editing and saving your TiddlyWiki to your web host.
The plugin and documentation are available from [[BidiX's site|http://tiddlywiki.bidix.info]]; this document is a quick-start to getting it going.
!!!Simple instructions for BidiX's UploadPlugin
''Extracted from [[TiddlyWiki for the rest of us - by Dave Gifford|http://www.giffmex.org/twfortherestofus.html#%5B%5BSimple%20instructions%20for%20BidiX's%20UploadPlugin%5D%5D]]''
#'''Import the plugin and its friends.''' In your TiddlyWiki file, go to the backstage section and import the following tiddlers from http://tiddlywiki.bidix.info/
##PasswordOptionPlugin
##UploadPlugin
##store.php
#'''Save changes''' to your file '''and reload''' / refresh your browser.
#'''Create a store.php file.''' Open the store.php tiddler in your file and copy its contents. In Notepad, or whatever program you use to create webpages, paste the contents you've copied, and save the file as store.php. Be sure your program hasn't added any extensions such as .html, etc. The file should be called 'store' and its extension should be .php.
#'''Set your username and password.''' In the store.php file, add your username(s) and password(s). Do this by going to the line $USERS = array( '~UserName1'=>'Password1', etc) and replacing Username1 with your username, and Password1 with your password. Be sure to leave all the punctuation and code, such as the single quotes, intact. Save your file.
#'''Upload store.php.''' Use your FTP client (the program you use to upload files to your website - I use ~FileZilla) to upload store.php to the directory (folder) where you are going to put your ~TiddlyWiki file. If it's been uploaded correctly, you should be able to open your file from your browser (e.g. http://www.giffmex.org/experiments/store.php) and see ~BidiX's message.
#'''Go to the Upload options panel.''' Now go to your TiddlyWiki file and in the backstage area at the top you should be able to see an 'upload' button. Click it.
#'''Fill in the Upload options panel.'''
##Set the same username and password that you placed in your store.php file
##Add the url of your store.php file (e.g., http://www.giffmex.org/experiments/store.php)
##Leave the Relative directory blank, and it will use default settings
##For filename, add the filename of the ~TiddlyWiki you are uploading
##If you have created a special directory on your site for backups, enter it in the Relative Directory for backups line. You don't add the entire url, just the name of the directory.
##Decide whether you want the ~UploadLog tiddler in your file to display the new logging data every time you save changes to the web, and check the box accordingly.
##Decide how many lines of data you want to appear in UploadLog, or leave it at a default of 10.
#'''Click 'Upload' in the Upload with options panel.''' There will be a delay as your file is uploaded, but a message area should appear saying that your file is saved and about to upload. When done it should say 'Main TiddlyWiki file uploaded'. You are done!
#'''Upload to your heart's content.''' Now, every time you want to upload the changes from your local file to the file on your website, go to the upload section of the backstage area, be sure your username and password are correct, and hit the upload button. That's it!
{{{
!Template
<<view modifier SiteIcon width:24 height:24 preserveAspectRatio:yes label:no>> <<view modifier spaceLink>> on <<view modified date>>
<<<
<<view text wikified>>
<<<
!EndTemplate
}}}
! Metadata
cf. [[DevPluginSpecifications]]
! Code Structure
{{annotation{The samples provided here are merely suggestions, not strictly-enforced regulations.}}}
!! Namespacing
Plugins' functions should be registered in the {{{config.extensions}}} namespace (built in from v2.5):
{{{
config.extensions.SamplePlugin = {
sampleFunction: function() {
/* ... */
}
};
}}}
Similarly, functions specific to a certain [[macros|DevMacros]] or [[toolbar|DevToolbarCommands]] should be attached to the {{{config.macros}}} or {{{config.commands}}} object, respectively:
{{{
config.macros.SampleMacro = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
/* ... */
}
};
config.commands.sampleCommand = {
handler: function(event, src, title) {
/* ... */
}
};
}}}
Overview of common TiddlyWiki namespaces:
* {{{config.extensions}}}: [[DevPlugins]]
* {{{config.macros}}}: [[DevMacros]]
* {{{config.commands}}}: [[DevToolbarCommands]]
* {{{config.paramifiers}}}: [[DevParamifiers]]
* {{{config.formatters}}}: [[DevFormatters]]
* {{{config.adaptors}}}: [[DevAdaptors]]
!! Documentation
Well-structured code simplifies readability and maintainability. Commenting is an important part of structuring code.
There are two basic levels of comments:
* block comments ({{{/* [...] */}}})
* inline comments ({{{// [...]}}})
This distinction can be used to create a semantic and visual distinction between headers and annotations:
{{{
/*
** [section]
*/
// [function description]
function foo() {
// [procedure description]
var foo = bar; // [explanatory comment]
}
/* [sub-section] */
function bar() {
var foo = bar;
}
}}}
{{annotation{While CSS only provides syntax for block comments, the same principle can be applied to [[StyleSheets]].}}}
! Extending Core Functionality
Instead of ''overwriting'' core functions, [[hijacking|DevHijacking]] should be used whenever possible to add the desired functionality either before or after invoking the hijacked code (via the {{{apply(this,arguments);}}} method). This allows other plugins relying on these functions to continue to operate.
However, hijacking the function is not always possible, given the nature of the specific core function or the desired changes. In that case, it is important to clearly note in the respective plugin's documentation that installing the plugin may have adverse affects on other plugins installed in the same document.
! Declaring Global Functions
Function statements should be avoided within plugins. Function statements are of the form:
{{{
function foo() {
// ...
}
}}}
Because plugins' code is processed using {{{eval()}}}, certain browsers (e.g. IE7 and Safari 3) leave the function in {{{eval()}}}'s local scope.
The way around this is to use expressions to declare such functions as variables, ideally adding an explicit {{{window}}} prefix:
{{{
window.foo = function() {
// ...
}
}}}
This is especially relevant when overriding core functions that are declared using function statements, such as {{{displayMessage()}}}, event handlers, etc.
! Dependency Handling
While TiddlyWiki recognizes a ''Requires'' slice in plugins, this is only used to determine plugins' loading order and will not result in an error if the respective dependencies are not found in the document.
Strict dependency checking has to be implemented by the respective plugin itself. However, rather than checking for the respective plugin's name, object detection should be employed for maximum flexibility:
{{{
if(!window.foo) { //# "window" only required to prevent ReferenceError if "foo" is a global variable
throw "Missing dependency: Foo";
}
}}}
({{{foo}}} might be a property of TiddlyWiki's ''config'' namespace, e.g {{{config.extensions.SamplePlugin}}}
{{annotation{The {{{pluginInfo.log}}} array can be extended to add a message without stopping execution of the plugin:}}}
{{{
pluginInfo.log.push("lorem ipsum");
}}}
! Creating Aliases
Sometimes variable names can become very long - especially when using namespaces.
A closure (anonymous wrapper function) can be used to create a local scope in which local variables can be used as [[aliases|http://docs.jquery.com/Plugins/Authoring#Custom_Alias]], essentially providing "shortcuts" for accessing variables from the parent scope:
{{{
(function($) { //# set up local scope and jQuery alias
var plugin; //# alias
plugin = config.extensions.SamplePlugin = {
sampleMessage: "lorem ipsum",
sampleFunction: function() {
/* ... */
}
};
displayMessage(plugin.sampleMessage);
plugin.sampleFunction();
})(jQuery); //# end of local scope, passing in jQuery object
}}}
Here {{{$}}} is used as a local alias for {{{jQuery}}}. Similarly, {{{plugin}}} works as an alias for {{{config.extensions.SamplePlugin}}}.
! See Also
* DevPluginSpecifications
TiddlyWiki will have problems displaying special characters unless it is set to use UTF-8.
If you are serving your TW from a web server you might need to add an <nowiki>{{{.htaccess}}} </nowiki>file with this in it:
<nowiki>{{{
AddCharset utf-8 .html
}}}</nowiki>
If you edit your TW file with a text editor that doesn't handle UTF-8 then it may have saved as plain ascii and broken the special characters such as the » char after "options"
The global function {{{wikifyStatic}}} works the same way as that the [[wikify()]] method does, but instead of rendering directly into an DOM element, it returns HTML source code as a string. It takes three parameters:
* the source code to render
* the regular expression to highlight
* the [[Tiddler]] to use as a reference point for rendering
Note this should not be confused with [[wikifyPlainText]] which outputs text (ie. no html)
[[UnaMesa|http://unamesa.org]] acts as the custodian of the [[open source]] license for [[TiddlyWiki]]'s source code.
[[Jeremy Ruston]] transferred the full copyright to UnaMesa before [[Osmosoft]]'s acquisition by [[BT]].
A non-profit, world-wide association of individuals from industry, academia, and ~NGOs, UnaMesa, provides free software tools and web services for schools, clinics, and other community organizations.
It acts as an R&D organization to meet its goal; "for every student, educator, patient, and caregiver to have access to the information they need when they need it." http://about.unamesa.org
For UnaMesa, the TiddlyWiki project is part of a greater endeavor "to improve the interoperability of digital records, especially educational materials" http://tiddlywiki.projects.unamesa.org
UnaMesa operates at the intersection between open source, fair trade and social networks so that it can develop new models of trust and hold information for public benefit. http://www.unamesa.org/about/overview.pdf
!External Resources
[[UnaMesa videos|http://vimeo.com/tag:unamesa]]
!!References
<<tagging stakeholders>>
Currently this just redirects to TiddlyWiki.com
To access the underlying space and give it another purpose request access from @jon and visit:
http://tiddlywiki.tiddlyspace.com/?select=title:!MarkupPreHead
The [[TiddlySpace API]] is built on top of the TiddlyWeb HTTP API, which is described in the [[tiddlyweb documentation|http://tiddlyweb.peermore.com/wiki/#%5B%5BHTTP%20API%5D%5D]].
Edit your PageTemplate tiddler. Also see http://tiddlythemes.com/
(to be expanded)
See [[Commonly used functions]]
!Top Level Functions
<<list filter [tag[globalfunction]][sort[title]]>>
!Tiddler ([[class information|Tiddler Class]])
<<list filter [startsWith[title,Tiddler.]][sort[title]]>>
!~TiddlyWiki ([[class information|TiddlyWiki Class]])
<<list filter [startsWith[title,TiddlyWiki.]][sort[title]]>>
!Story ([[class information|Story Class]])
<<list filter [startsWith[title,Story.]][sort[title]]>>
!Wikifier ([[class information|Wikifier Class]])
<<list filter [startsWith[title,Wikifier.]][sort[title]]>>
Extensions to primitive types:
!Date
<<list filter [startsWith[title,Date.]][sort[title]]>>
iVBORw0KGgoAAAANSUhEUgAAAGUAAABACAIAAACMfy4dAAAXVGlDQ1BJQ0MgUHJvZmlsZQAAeAHVWWdYFM2y7pnNy+6Sc1pyzjlnkCRRopJzZslBBAQkKAgoIqAoqIioIEqUJAqK+CGioGIiiARRMSAoKHfQL5z7nHP+3T+3n2d636mqrq6Z6u6pqgWAc9k7KioMZgAgPCKWZm9mSHVxdaPiJgEBUJCLETB7+8ZEGdjaWoH/2r5OAGib+VBmW9d/FfvPDEY//xhfACBbhO3jF+MbjuBrAMCGvlG0WABQ6wh9NCE2CsHoOwhmoSEGIvj5Ng78jVe2sc8vjEH/knG0NwIAwwEAnuTtTQsEgCyM0KnxvoGIHrIxAFimCL/gCACYXRCs6xvk7QcAZzkiIx0eHrmNbyFY3Odf9AT+C/b29vlbp7d34N/497MgI5GJjYNjosK8k37d/F924WFxyPv61ZiQnhQRtnPbN2zIteDnbWyJ/PIg18+osF8+Q2QgLv+IXQ4IbRtLR/jstPkT6wbQTO0RjIyFbKNiDbcx8s6ggKhYW8c/6WnJQUY7EUxC6Ef8Y0z+0nMqxNti22cUhN5Mi7PfhWBhBPfFxDuYIBhZUdDr5CBH5z9lvvj5G/9Jh+GAYFPz3zIwU3Cs+fZcLIjPBUMjLbdtQOaCVYElCAP+IA7QkD4CyAArYASM/+xlQADwRjjxCC8GhII3CA5HRkQiYyIRTP1TzujfKKa/xgUi4/63RirwRWTj/p7z92xUZM6/dAYDPwT/RfdG5tjmbVsX4xmc+c+cf0ls6/tljXyD/KL85l82oUXRimgVtCFaB62L1gBUNBuaC8igldHqaAO0HloL4WkAU/Aa0Rz4l43b+sObA+LLI5M0nYIQ7vaz+/zFBU6/pIP/vv83C0DwyHLb8l8WABDrn4jsAwCMIqOSaMGBQbFUA2Tn+ktTzSN8ZaWpivIK8tvs/zdt+8z6bexn+19nEcR2/x9apAIAGttnzP5/aF7vAWgLQbYp0z800TYA6BUBGDrmG0eL/60Pvf2DAURAj6xQTsAHhIA48p4VgSrQAvrABFgAG+AIXIEHsn6CkDVIAwkgFWSAHFAADoOjoAJUg1pwHlwCzaANdIEbYBAMg1EwDp6BKTAH3oIV8BVsQBCEg8gQM8QJ8UMikBSkCKlDupAJZAXZQ66QFxQIRUBxUCq0HyqASqAK6DRUD12BOqAb0BD0AHoKTUOL0CfoO4yCSTALzAuLwnKwOmwAW8KO8B44EI6Gk+EsuBAuh2vgi3ArfAMehsfhKfgtvIoCKDoUG0oAJYNSRxmhbFBuqAAUDZWGykeVoWpQl1GdqNuoh6gp1DLqGxqLZkZT0TLIOt2B3oX2RUej09AH0RXo8+hW9C30Q/Q0egX9E0PG8GCkMJoYc4wLJhCTgMnBlGHOYVowA5hxzBzmKxaLZcOKYdWwO7Cu2BBsCvYg9gS2EduHfYCdxa7icDhOnBROB2eD88bF4nJwx3EXcb24Mdwcbh1Ph+fHK+JN8W74CHwmvgx/Ad+DH8PP4zcIDAQRgibBhuBHSCIUEc4QOgn3CXOEDSIjUYyoQ3QkhhAziOXEy8QB4nPiZzo6OkE6DTo7umC6dLpyuia6O3TTdN9ITCRJkhFpNymOVEiqI/WRnpI+k8lkUbI+2Y0cSy4k15Nvkl+S1ynMFFmKOcWPso9SSWmljFHe0xPoRegN6D3ok+nL6K/S36dfZiAwiDIYMXgzpDFUMnQwPGZYZWRmVGC0YQxnPMh4gXGIcYEJxyTKZMLkx5TFVMt0k2mWGcUsxGzE7Mu8n/kM8wDzHAuWRYzFnCWEpYDlEssIyworE6syqxNrImslazfrFBuKTZTNnC2MrYitmW2C7Ts7L7sBuz97Hvtl9jH2NQ5uDn0Of458jkaOcY7vnFROE85QzmLONs4XXGguSS47rgSuk1wDXMvcLNxa3L7c+dzN3JM8MI8kjz1PCk8tzz2eVV4+XjPeKN7jvDd5l/nY+PT5QviO8PXwLfIz8+vyB/Mf4e/lX6KyUg2oYdRy6i3qigCPwA6BOIHTAiMCG4JigrsEMwUbBV8IEYXUhQKEjgj1C60I8wtbC6cKNwhPihBE1EWCRI6J3BZZExUTdRY9INomuiDGIWYulizWIPZcnCyuJx4tXiP+SAIroS4RKnFCYlQSllSRDJKslLwvBUupSgVLnZB6II2R1pCOkK6RfixDkjGQiZdpkJmWZZO1ks2UbZN9Lycs5yZXLHdb7qe8inyY/Bn5ZwpMChYKmQqdCp8UJRV9FSsVHymRlUyV9im1K31UllL2Vz6p/ESFWcVa5YBKv8oPVTVVmupl1UU1YTUvtSq1x+os6rbqB9XvaGA0DDX2aXRpfNNU1YzVbNb8oCWjFap1QWtBW0zbX/uM9qyOoI63zmmdKV2qrpfuKd0pPQE9b70avRl9IX0//XP68wYSBiEGFw3eG8ob0gxbDNeMNI32GvUZo4zNjPONR0yYTHaZVJi8NBU0DTRtMF0xUzFLMevbgdlhuaN4x2NzXnNf83rzFQs1i70WtyxJlg6WFZYzVpJWNKtOa9jawrrU+vlOkZ0RO9tsgI25TanNC1sx22jb63ZYO1u7Srs39gr2qfa3HZgdPB0uOHx1NHQscny2S3xX3K5+J3qn3U71TmvOxs4lzlMuci57XYZduVyDXdvdcG5ObufcVt1N3I+6z+1W2Z2ze2KP2J7EPUMeXB5hHt2e9J7enle9MF7OXhe8Nr1tvGu8V33Mfap8VnyNfI/5vvXT9zvit+iv41/iPx+gE1ASsBCoE1gauBikF1QWtBxsFFwR/DFkR0h1yFqoTWhd6FaYc1hjOD7cK7wjgikiNOJWJF9kYuSDKKmonKipaM3oo9ErNEvauRgoZk9MeywLEhzeixOPy46bjteNr4xfT3BKuJrImBiReC9JMikvaT7ZNPlsCjrFN6U/VSA1I3V6r8He02lQmk9a/z6hfVn75tLN0s9nEDNCM/7IlM8syfyy33l/ZxZvVnrWbLZZdkMOJYeW8/iA1oHqXHRucO5InlLe8byf+X75dwvkC8oKNg/6Hrx7SOFQ+aGtwoDCkSLVopOHsYcjDk8U6xWfL2EsSS6ZLbUubT1CPZJ/5MtRz6NDZcpl1ceIx+KOTZVblbcfFz5++PhmRVDFeKVhZWMVT1Ve1doJvxNjJ/VPXq7mrS6o/n4q+NST02anW2tEa8pqsbXxtW/OOJ25fVb9bP05rnMF537URdRNnbc/f6terb7+As+Foga4Ia5h8eLui6OXjC+1X5a5fLqRrbGgCTTFNS1d8boy0WzZ3H9V/erlayLXqlqYW/Jbodak1pW2oLapdtf2Bx0WHf2dWp0t12Wv13UJdFV2s3YX9RB7snq2epN7V/ui+pZvBN6Y7ffsf3bT5eajW3a3RgYsB+4Mmg7evG1wu/eOzp2uIc2hjrvqd9uGVYdb76nca/lD5Y+WEdWR1vtq99tHNUY7H2g/6BnTG7vx0Pjh4CPzR8PjO8cfTOyaePJ49+OpJ35PFp6GPf04GT+58Sz9OeZ5/guGF2UveV7WvJJ41TilOtU9bTx9b8Zh5tms7+zb1zGvN+ey3pDflM3zz9cvKC50LZouji65L829jXq7sZzzjvFd1Xvx99c+6H+4t+KyMveR9nHr08HPnJ/rvih/6V+1XX35Nfzrxlr+Ouf6+W/q325/d/4+v5Gwidss/yHxo/On5c/nW+FbW1HeNO9fsQAK6eGAAAA+1SE5hCuSO4wCQOz7nVP8kkDSFQiRQTAOiRQskAhgFpJEvtt9MCccC0+izFE30WboR5hwLCO2H5eK1yXgCC+IHXRVpCJyHeU5AwOjJVMe8xArI9tu9oucaC5v7m5eKt9B/nUBP8FJ4Z0iQ2Jy4oUSb6XMpatlvsoZyR9SGFUiKxuqxKhWqfWpT2n80GLXltLR0DXRs9f3NYgxzDI6Ztxg0mv60Gxxx5YFq6W0lZG1+85gm3jbbLsS+2qHBsc2ZNcPO4+5PHV95TbrvrD73Z4Fj+eeI1693o0+J30P+SX7BwTYBWoFCQdTgr+GvAodDKsPPxQRFekQpRbNFb1JexnTF1sblx0fkGCeKJVETFpKvpfSlFq+NystYV90Oi0jOTN//+ms7uxXBwi52nlR+bUFE4eIhdpF4YdPFo+U/DgifdS9LP9Ya/lUBV2lSpXnibyTzdXPTqNrZGqdzuw7e/7cg7r1euoFq4bUi82XPjZqNhVd+XDV/dr9Vpu2Rx3anbHX67ue99D1KvU53Yjuz75ZfKtsoGyw+Hbunf1DB+4eGj50L/uP2BHn+7L3N0b7HqSMqY59ffj4Ucd4xcTex55PDJ+KTBIm3z178LzlRcXLva+8poynJWYYZr7Nvnk9MTf05sb89YWOxY6ls28Ll+Pfebw3+SC1wrCy+nHyU8/n01+yV4O+Wq7JrTOvr317/r1vo2Yz64f/T+Mtwa0txP9YwIVEh4lgAInorKDD0CtYCYm9PqM8URNI1PQCE4WlYNtw/ngu/CShihhIZ0jSITtSgujTGU4x3mBaZGFlNWZLYm/k+MAly03j6eKj43eiXhDYEjIQzhDpFd0UV5MIkTwhNSz9SZZVTkl+h4K7YqBStHKSyl7VZLUQdXcNK00dLXltQR1WXbzud713+tMG44Z3jXqMr5rUmZab5e5IMA+ycLXcYaVuLbaT1QZt88V2xu6BfZ9Dk+PJXblOMc4eLuauSm687lj398hJ3+1R65nvFent6KPsS/Kd8evwLwoICNQOYgx6E3w9pDjUP0wznD58NqItMjfKNVoKWRcjMadiaXFG8azx8wkdiQeTPJLlU+CUx6mNewvSwvftSjfO0MzU2K+TtSPbJSfiwIHcs3k386cLfh7iKdQocjocU3y45GLp0JE3ZfAxnnLV43YV4ZUFVRdPjJ78ekrwtG3N/tqOMx/PydZFn79Wv9agcTH1Uk8jaDK4sr954Bqmxaw1t+12B67T5HpmV3f3l17RPocbKf0nb16/NT6wOLh2Bz3EfFdgWO6ezh9WI273g0YTHuSMHX1Y86hxvGti6PHEk7mnX56hnrO8EHmp/spqKnC6dmbxtdic25uc+QsLtxenl9aXKe9E3ut9cF9J/zj6WelL6ernNfv1a985NrI3138m/PI/GqmcSIKdIB30IXG9JhQLtcEwbA2fgjdQHqi7aG10K0Yd04+1xc7iUvDc+NuEQ0RfOm0SN+kneYYyTN/CcJaxnKmQOZclmzWHrYC9lKOas4Grnbubp5u3h6+Xv4d6XaBFsEHohHCBSJzobjF9cUEJIPFMsk2qQNpJhiqzJNsily5vqcCmMK3YoBSnrKdCUHmoekItSF1ZfV2jRzNby1KbSXtSp0Y3RE9Rb1N/0KDYcI+RpNGa8U2TIlN3MzGzTzt6zPMtnCwFLN9atVqn77SyYbOZtm2wi7HXcoAd7jqW7HJzojrNO192iXPVcoPdhtyLdjvsYdvz1KPSc48Xr9cL7xM+e3x5fCf9yv2dApgD7gcWBJkEA2S9xIcqhC6H1YX7RPBEPI4sjdoZjY++QUuOUYpZjj0b5xHPHn8/4UCiXuJ6UlNycAo15Wnqkb2OaZxpc/va049kJGUG7N+d5ZrtnuN/IC43O68s/1xB68HBQ+OFc0VfilElzKWCR+SPapYZHbMotzvuWuFTGVm170TpyYvVw6c+1IjUJp0ZPSdWl3Z+4oJMQ9bFZ5cVGnObXjarXi249qpVqe1A+/NOpev5XTM92r3lfV/7HW+2DIgNnrkjMzQwHPqH8Mjy6O2xK4/qJ5qe3Jh88QK8kp+ue50zn7/U9p7+Y+4qx3rLpvO2/3/Xlra/CVhVAM7OAuB0GgA7dwDqpAAQqUTKJki9w5YMgKMGgA2LAPT0OIDMLv/9/SADMSTLDwAHkMxxCLyFKJACtAtKhk5AXdAzaBPJ7/RgHzgHvgDfh7+guFEGqCDUYVQHagZNh9QPvJCMrB39GsOE0cNEYE5jxrFErAE2EduMXcaJ4wJxdbhFvCw+Dt9LoCO4ES4SIaILsZmOQhdBN0ZSJ50i48k08kuKBaWDXpy+goHMkMGwxhiJ5Cu+TK+YfZjnWcJZvrJmsFHYTrDLsd/kcOdY5SzmUuB6yJ3Aw8szynuAz5Af8N+gZgtYC3IKLghdFy4WCRE1FRMRJ4mvSsxIjkndku6UuSrbJNco36zQrtinNKz8UuWjGlqdVUNIU0ZLQVteR1KXqsekD+t/MHhm2GtUY5xrEmnqYma4Q86cz4LeEmW5brVivbRzzmbGdtrutf1bh8+OP5wIzuwuYq4abtbuvrtT9hz1aEK+Y+98KL5Kfq7++wJqAweCZoN/hDKFCYRLRshGykRJRAvS2GIIMd9jF+O5EqwTs5J6k3+mmuwtTXubbp1xfb9yVkeO+YHZvAMFAgcvF+oXTRUXl7oc1TlmfjyhcuAk9ylKDVz77eynuvf1yw3Llz40rl75cQ3fyt0u12nc5doT3Bffn3YrfXDvnfi7Yfe8RgpG28eWxgUe73la/ezNS4WpjJnxOan53MX5ZbP3Fz4yfE5Zfbce8H3+R9Sv84MeyAI7pBpVAXrBa4gOqQa4Q1lIxj8MfUCye03YC86Fm+CnKBSSs7uislFXUK/QZORUCUVXov9A8m8FjB+mCvE7PdYKm4e9gyPirHEluEm8CJ6G7yewEcIIg0QhYiZxjs6CrpMkRaoms5IPUrCUTHpAn8GAYshlpDAeYxJkamTWZx5nCWfFstawGbDNsOdwyHBMcGZwyXNNcZfy7OBF8/bz7ec3pZKoEwI1gjFCpsJ8wusiE6JtYqfEj0kUSxZKFUqXyFTInpNrkb+j8FJxTZlVRVPVV61QvVvjg5aItqdOpe4zfT4DP8NGow0TE9MCs2FzjIWapY9VjvW5nTdsJm1X7NEObI6Su/SdXJ1jXIpcL7uNuH/cw+ah4xngVezd4/PeT8jfJaAocDDoR4hyaHDYyfAHkXCUYrQXrTDmeuxCPH2CWqJXUkFye8r8XvY0831705szlvYLZe3Jrsh5ksue55p/suD1IZnCxKLBYo6SyNJ7R+XLKsspx/MqSVVHT4pV3z4dXEs603zO7Ty6vqnB8xLD5ZtNic1yVxda6tqCO2Q6P3V19mT2WfWz35wdaLqdOmQxzHlvdGTX/dkHyQ/5Ho1MFDxxmBR9Dr2YeTU43TBbNEebd1jkXqpeFnt35YPuysgnz88fVtPX6NePf+fbqP7B9bPol//ZgQGIQipH98EW4vsA6Dg0AH2GBWF7pIbTBi8jtRoXZL8PoVFIDTEZ3YZexahg4jHdWAzWBluJXcJp4Q7jFvDG+DMEPCGK8JxoReyjU0M8bUi6R3YlL1HS6FnpmxhsGD4yljHpMi0yn2BxYCWz3mXLY7fiYOKY5DzLReM24GHmecs7yHeGP4caKuAoaCCkKCwmwi/KLcYlTpWQktSQspT2lkmVrZDrln+tSFHSVqapXFb9oK6ikaE5pi2uk6X7Rt/KoM1IyviMqYBZrbmERYuVsfUTmyg7kn2TozuyX7td492Vd6979Hkd8vHwUw0gBT4Nrgg1D1uMSIrcjI6lzcXaxl1NYEykJT1K0Uw9nUa3LzF9PtNl/71sw5zOXOW81gKdg0OFrkVvi9NKGY/UlMkd6ziuW9FbpX2itRpzyur00ZpXZyTPJpwbOM9aH3Ch8yLlkt/lribWK1HNw9fEkcznXbtdR9t1vq6c7ve9zn03+qVuHr21NRhy+9GQ/t2Ge2x/xIzcHeV+EDR28eHSuNCE8+PMJ+ef3p2ce7b5guEl/yupKZVpzRndWf3X+nO6bzTn1RYUFiWXBN9S3i4ud7xLeK/yfvnD2RXXj8SPXZ8CPjN8bv+yexWs1nw1/Dqztm+dZ73j265vK98Pboht9G96bK7/KP0p93Noy2/b/zEBSkgdEmkQyRApP77c2vosiiQVJQD8KN7a2qjZ2vpRiyQbyH8gfWG//6/YFsYiNfcqhP6f2/8A3sF+76IcnXEAAAAJcEhZcwAACxMAAAsTAQCanBgAABQsSURBVHgB7ZtbjCXXVYZ31a7rOadPT/f0TPe0Z9qZ8SWOjYJD7DhEeQBGjpEcyQgjCAH5BZEIiYdIIMwDQkRERIYXPyDlybJEgrCCZQmhWAETLk4cMsmI+I4dT2Y8Y7vn0tP3c6uqXXvzrV3dQx6I6B53Ox2pa06fU5ddu2r/tda//rV2TeCcU/vLlhEIt9xyv6EgEF2D4dfu/dC19b2wUn3iCypwgVLyt7EELKzyZ5VqRSqLYxcEeEjtbFXbWulABUEo/3QQ0CDRoQpCq6x1ytigtHUYhUkQ0iduRbNQemQ1UGFYW2nGuuxioWc69Jdn9bGH7ubY/+K1cUt750czeCcDkVvaxKwBTCnNPkaoQlowzpIGQSwwhEBg0xg0wyzWDLp0qqpVCWYu1JFWoa2sQAJSNNUA6hGxjsOa5yDgcdD5a0u3/vJs+2Xv4qV5ttxl4DAlFg+UQMdKoGygNH+VCiym5XTIqGSUKopUJ0mSWHZUTg2NK2uGDjQ61gHYALM0Dyyb/gJyIi3kyQg6dN6syAbGiRH6i+55vBiiv1W5axmJXzxqDMGPCticrIrPSROXxWErjthVWov34aEYDafTAQYjFrXx54CP7pt+fcDzFuXREj/0DklzzhHrEwA3bmDv2pcwEHe6+U/GtnnTnnFksxm/R1LpSIY1NOJSNWuW1ngYyEgfLJ4NZdiggEda8UqeiBiX/PjHIq7puxWvrSoV0QEPLt6wrr3MX8IuDUAyRgbEPz8YgefaERkcS7Oj5tcFLhR207EfuJwjlO97wOeavhoT8j06YTyPV9OTIFZXo+LMf/Xm30iyLJuaHU8iO/sBueyexosn7l1G6IcBbxoVN82QmsHJiP0/XNIvQMyvSyOxHIivBjzZ03x5B5QzfTOJfLLBUaF3NjCl4WDx7Mt1Mbxy+uvh2vyR2SOJXR8Yc2ByWnrZy3jJY/d4SaDyFNVIaxliYybN2obJsCFsI0PCf6IQVkIdcNBZwR0TwqcaoKXRJlRgtOFrrJlq+e0fXHj524PB4NzLL4amXF5fv2n5UmfqSLlwTs7ay3hp9ITHgrtkxDJWT8V+rHLr/ijMLescY1v+wtCFxEyMS0IbVhZGG7jKiX6RhhwTzLxjCnahqtVbr5x+7bmn33n+O8PhehxHdW3fcXa6m5mF+d63nlQPf46z9y7foww8Rn5cHgphJhmr0HODmlCcl2AeCWnpqSo0tFN1g5O4mYdOzsGaGh0KXrJIOxY2Vi6dO3v6395+6VSWqNmp2StLS/3hqF8Wz59bONRJTswekHZ7GS8CG09dHBE53twsXM6KpzWGyWEUlGgG9jeAyXeDb6AdpC9MxSEPK8iIewpmvrcGLbHhQPUXL1148T+XLvwgT9JbZqcOdtva2Uv1omi/2gLcmARfWfaufaEPkFIITzwL/wIHLAt5Lt/QkRYQSWDwWkSW1woyHgHE/4CqQCELPiviBLQaBqSJNyuxLlqZYrh68Xy1eHF98UoWK8QuWmNu6kAS2N6gmBlLlgbmympfet8mXuP3fvbhk7cfMcaMevPf/+evfO25N5peduM7jWWYcosu4OmKBYkIF8/02AljeRwEEr/PA+W3hNM24RJNLzuboz5EgjR2KzpVaLEcDdbmz59/7eVi1GvrDszX6/dDZ+g9GuuqTuuGbh0504xx6/Y1/ulHHj85l25CM3v81rs+dOKRL3z52c09O/ybRTgcwxPTQjT6ZFKGjhaVDInxi1mJ5BI4GsD8inC8N0YPEesCuseLSOkPEAeQXahWyRBs5/DBY7d9cPH86/2lq3FbDaLllZWeUmmgq8lOtFgOjnYnV69eboYneG9lmbzvYQ/W0tf/+nO/85u/+8SpC5x1/OQnZ7dy8nW1GUuDbqK6SdhJyJwVlYgEZ6EmEalWrNpx0E4lqW6RA0VBK6YaEeQ6iCMVa/kkkUZVxOLUbAaAH+kw5sPOMIgQHX4PzbIkHTs4ub5w2ZrR2uraufMXV9fLG7vTwUjbUXG8lc+Nt3MyeL9s1b7GJ8Zo/9Y//NXfex985tEv3fN3Xzx+XUBs8aSJDMaRzAbSEUYXixJjwzEhI0wMIhPb21jxcQHTE5oSaxJPk8X7sPB+Y4Kbpifs59s5LDdUeXbP/Q98428XlubPv29qOg90HNTHxieUMlPjk1OHxg8daDW3vVW8Vs9876VX1988c7U5Lb/rFzYEb7O9C98Zt0zpwQk0CE8PDOMWHmPsDFe8ciP1A5Xa4wnlSUMPToMw0Ana7G5CoXdM34KzRZzQj2nNTs/O/crls6+/8M1qYmZ27eKblxYvhSqx2o5XnZmpubnpber7pdN/8+hprjD+6c8/fvdMu9tts/HWN56c52d3FqpbkdcPhD9D9Qq+8VrAlwQFBUYLm3iAwE/sqLE+sUap+PArnI+FstDCo4zah+QFOtnJF502DyMMPnb/g6uX56/On03jpEVlyEU210sjf/FNf9wqf/mL8tXOO+02zOGX2bvuP755YDd+CYtJSDJo5RNakRC+vsIQqT5QzDGWoihJooABgpGuM+1yuIwP5oHUl0qZHBS0pA36gULYBseJwhMuowwbpKq+6f03f/bzX5yavQWITByOIturqlHlzl1ae+G/zzcD3C5e84/9wa9/5rcf+P2/+PLFQunDdz1w364xvrcAhotX+hKNAxc+VEoLq0rnCuWKIBi4oF+rNSOflUotVW65dIulXTWub1VfUV91haMAS/mQgjVpjxs51XwovZIJEDVJBeRJqDputX/jD//49l/85OWVAbR/Za03qstXfrjw0vIGf20Rr9mHHvnqY195/N5DG2Y0fOmJf3l9lY2sPbUblkWfIxcNqflZN7KsM2yyHCBzlXIV7oaKxQM9iWE7EhnkE5og4Ch1VyrUFR4ppidOSy5uQl2GyoTSwPiPbx9WLqDPgQ3WrV6zKpmZ/egDD37ioc90Jw9NtvPIBPnhm/XYhllsEa95QyagD3/45Ac30Rm/aUYoTKnh5p4d/nWurIIa0wAmfM7bgQ21+GYWOeRFqIltlAldFLMZpZqg5mJsRNWJwp9qtAW+hqRINCoklA8JQ6RSvI+QGAaZtvhv4vtMN4QIz8EePHb0ow9+au7EjWNxfuT9H+HPtbrN8LYaH//91JmTc3fc8sCf/9nRZ5+/HN/58Z8/1o1Uffbpp3ZL4qPvZfIBDseIhMmtTGwwDeRMUY6UKV1VuqJXlwN0U1BXZW+9GK5rdLlzEYmBMFOqwjhN0zDO0lYnyrtRezzsjOuso+MsjPjAiF78Chi1l7EqiAxP4V+/9o/rC6Ppn7sv7M7gsUKcftkqXvNP/dETc1/61D1zxz78S8eaU/sXnvrLP3mxWd+F77XX/gN0bFnYclgMerYq63JkTVWVrMBduJQj2Sa/9LMd4qvEUGPrOAjTOBaah+FduB7W0HqKQpV0gWmPBJKKOhNR+0AyMZ1PHc2mjuo8F4VGxAiD9eX+qWdfuHju4sydH6+CDJNG6/oMVga5Vbxo+syjv/fM3Ec+9oGjiVK9xTOnT+8eVnJnr3/rq37mh8yaaTHsimHLoJhDC1Ukkp3M0rqhqSTLEb7G+8K6cqOqHIRFmugEV1S2V1RFWUdh2kk15jocVGkStBOYUdM+z+MkH88Ozri8OzYxXSfj33txeWFhkOcTw6rm2nkaVlUt025+2QZe0v7Cd7994bvNmbv9Pahltiysa8kRWYTdfYEB1gpFkTUilHgHRviVaAUjU7PYCTtNHdd1maUJuRTnQvTgBv8TcPtGQuRqbxSlgVtzhXnbvfGKLW23FZfdu012O9Hk1HP/dOPxOw/fcMyaOnSWIkgz3m3itdsg/Uj/vdEKdkPGJ5bjSzaiuQwJjUgMsSlmaANmNWAcZiFFy8qcrPA1h+zIBHilKQuwgn/ohbprURNAfMrAY8h4EFr8N8bhrEtsGSd67GdMac6+emp1uZfd0TErV5OpG6KEEsmex8vgDqKJmOxB2StDxiPFP1GqXpgLQRlHdK4DK/UeNrWOJCQw6R9qpFZpq4TYyblVXZnaGJemRAKGTjeEVpQEaNY2HBVVRbE/zH+2FWTD3oWivzJ7ZEavnouP3Ba0xp0ZUt7Z6/aVJFKi8rOHGEwY6Qjz8e8B8JKDKHWBiDoW2gpr0z5+GimIGoqIHMSq4qQokVY2y+Mso6oTWWcIm7xowWL4ASTCBJllTBmja7Pbh+sLK8tXDrXTbHh1/XJRDMPOoOhOH0tbjXjaDt//iK+8F6tSg8AUMBdfjcBGsLMYWeWlKgaF4TCNLbELW5KMHFOxwEocrIo6TjWMBX6wPtiUpg6iUYOOTzploiRSoWHGDTbHL5ObrZ6Yf+2bQbEavX326qV5Wxlo8SpTtgcOtm68Vf3pbzHsvctfUkWGnCiuknk7MkWCvSsN4qsmkcRMuHugMRgbDSWjVsREZBlsRymwLAzkDuK1k5km+MuWjimfiIqYn7OWZmK3mCePZFyN3VOR/awujfUW+29fwPXpnH8wm1u6sra8US/cu3hRjsa2ZMCKJ02eJ2TuPUhB1rA2KOGZGBdWAyQM28/+SC5IQznKyWRUpFQAKOhIfl2TS1eFr/ojrXSNjCMOrHUD0+8j9K5cSK+8I6FY7NV7vLAlqMomy97Fq9cbScmKGSDeP5LbdeglYwBNdmN8EBf4ARxftRX5SiNG55VF6OdqARQVK5DB82EEoAyZsKBADZwwIXIoa1qLb7y2Ov/D9rETyerVssZkxeiauAIl4JXXlr2Ll9MUIwhm1jL/igRzQVEWAptkLrzi4IHBtoTfpDKGh4poIChItilGJ+5Gds0u5wivGBchUsr5hE/vwrYKypXu6tV05dKCLtf1my+6knKGjzOCrAQUPJLtdBMyrwCvoffjV7b79uGTz3z/x3e2pSMnf3UWVYWCF/MBACZyqpoXu0iYuXlEP5V4SRPxKkfmrSpQNSZFxIudYV5eNqjAlHWaQ215r4+moCQRkjDFCULYrp+phxcruiL7NMUIqhIG8BhxizyipkLZzvLshsNPv/QqO3fFvt49WNzZoA8CwrYiGKAijAU+wo9ktiiirIOf4oQwERmmqCrcJgI1GjFUxqoRYtA1h4ohghY1BsoSG0iD5BEMVO+tPnvQZsZQ++EtAjEqfBYbxVRxbLpM8yw6cTy4YY5DLDuP146AxZ0hLQ2BMSCcNTNrIsyFvCT4V8zc+ldSEfwCATSVxRFWw4pnHzADaeo8BA0cmb3y2gmmivwnw6lrN7oIzs7GztsrdIajbjqh6Dss1+Vj3fjWW/TkbCvdZj3Hg/v/f+0UWHIlTX05LtBQQlEYlrzSxVNHjjJy2ad0h9qzvL8K00Hq4rSyCdsFgampz2Bm0jZPefUmwhxxURzOBrYcVXXm0gk1WKN6KCkW3WFevm4tASMC7Syt33fiwLHblDFxd7IZ/E7a106CJcig2SnmQS84CCVjQMO4EAS8wCuUTYyvCsZCAqhhHji84o1ARww1JIJEUnk3EH8m0YGIlCVhoLgIFVYVNBcFRyJ3OHav9MsrZFqCBtSFpUoewMPqjqnZo9HEobxz2JQjNM0O47WzYHFz3LToCFJdDMkFLeoMMmrntOgDU9lCZuw1wl2sBiFW8F6FQ8z7mCBvMUl4EwKn2C+xEvRphzuLmAilB/wvmklHqwN5iZpOSN/zjrwGzBTu0eNR52Ca5mGcx+m4ra7n/YkG4v/je8fB4hrYSu2oW0npCUZGVkgyZEwYxVHE6zNAgblZytBQPp6EU8okJCtC5myInwpMAeHP8i5ETd2fWn1AkODdLtR/WBmbTkTRHW030KaaSsYPT85Ml6OC0/K0G/CyC1NJ4JekWG8z7B3wx90Ai5tLwniEDckbOKFOkhFlVYvtxH5mFkrKKbhSnq8MNXs8VeoYBY6F1zIbJFhKfCgp64jc5MPEG9EAr8RoKRWGpUhfkVpBK2hNTXUP/TK+SINoDDvGkjVvDuPyaA9uRvMWgl/eLV67BBb3VjkDeZEIISExNEgYV4STISCDLotLL+1xLigdtHAmhAIpDx4oxVjKrnIC6SGvl5cULoS+vddp3jM3Tg+G5KHYIGe73mCp44o4OaBEwgi6VLDBmXMD3quSF4R2wr52Dyx5pOhxZqK5d+yg0qMRQsyKG/FfWnDM0lKjr2RDU5khxUGYm7oaDFDwTmpBPjRijvgdFCRpprWJFJfFdMqyyjLqFggU0RHokbIaRtkU4oxqZHOuuLaIOeySe3jXfL+rYIEXRgWVI/EleWGymufN/3vxdStcDZMiTqZMIrGCFEWS1RTmk1ZeFyUzceJ0cUoCJEl7kjCJDcELJ1ICY+i8p4N+cFIE0+QFsZTxu16NiKbg4rRhjQXvZpM8wrvj9erV3QaLm4NeMBFfSOAFtqKVawrp/fV6OKwPjEcRszwZMKJFqcVL6ojL9Adl5id64H4kBTkmZkGsYKoEFYYyoyqE4PBBowicpv6DP0pgQYeACLYIx4mOASL+YZP0G0ukxeP9cj389R6Axb0tLY3yViKMDtHzAgDmgXd69zSFjSjyRApTIjsiEsj/o/Ivb5oR/iMZk+gvMoSqjoWARElQ7rcl6UCdkA+RdLLG6wCclUKBAEb/XuFyDa4CQHyTioEl6g83vT683huwuDekF+aBcmJaNmkhF3SeRFMTcZWLBkXD93soekIZM/ziLkCTJTH8NSpNq51QshoNS2siEC8gKszPiUz1NSAiLXaHo0kgoTFzmnySHOeV3OCaO4rWRfKiTvivcNeB13sGFvf2/HcWmlvcU98bNLaVe3ovwdrK/fxE2ohr/0Qu/FN60W3Y10/pCHf2tvfx2h6e+3jt47U9BLbXet++9vHaHgLba71vX/t4bQ+B7bXet699vLaHwPZa79vX9vD6H+q+L/E7WiAaAAAAAElFTkSuQmCC
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TiddlyWeb Commander</title>
<link rel="stylesheet" href="layout.css">
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="widgets.css">
<!--[if lte IE 8]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<header class="pane">
<h1>TiddlyWeb Commander</h1>
</header>
<nav class="pane"></nav>
<section class="pane">
<a href="javascript:;" id="btnFullscreen" class="button">fullscreen</a>
<a href="javascript:;" id="btnSave" class="button">save</a>
<article></article>
</section>
<footer class="pane">
<p class="status">
<span class="host"></span>
<span class="username"></span>
</p>
<p class="notification"></p>
</footer>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
// use local jQuery if CDN is not available
if(!window.jQuery) {
document.write('<script src="jquery.js"><\/script>');
}
// request enhanced privileges on file URIs
if(window.location.protocol == "file:") {
document.write('<script src="sudo.js"><\/script>');
}
// optionally activate dev mode
if(document.location.hash.indexOf("devmode:true") != -1) {
document.write('<script src="dev.js"><\/script>');
}
</script>
<script src="jquery-json.js"></script>
<script src="chrjs.js"></script>
<script src="chrjs.ui.js"></script>
<script src="main.js"></script>
</body>
</html>
Extended HTML syntax is used in the [[Shadow Tiddlers|http://shadowtiddlers.tiddlyspace.com]] that define the structure and layout of a TW. The main shadow tiddlers are PageTemplate, EditTemplate, ViewTemplate.
It allows users to use TW macros and plugins within their TW document and not just in their tiddlers. An example from the ViewTemplate would be:
{{{
<div class='title' macro='view title text'></div>
}}}
More generically:
{{{
<... macro='macroName param param' ..>>
}}}
When encountered it is often interpreted by the [[wikify()]] method. When [[wikify()]] recognizes the embedded macro syntax, it calls on [[invokeMacro()]], which automatically sets a ''global'' window.tiddler variable to point to the current tiddler object that is being rendered. This enables the macro's parameter processing to use "evaluated parameters" that reference values within that tiddler object, like this:
{{{
<... someMacro ... {{tiddler.title}} ...>
}}}
@@Note: prior to TW2.4.3, you needed TiddlyTools' CoreTweaks #444, which added the global window.tiddler (and window.place) variables to the invokeMacro() function. Starting with TW2.4.3, this functionality was added to the core.@@
@@Note: for security reasons evaluated parameters were turned off in TiddlySpace@@
If and when the calculation and substitution of evaluated parameters is complete, invokeMacro then passes the parameter values onward for further rendering by the appropriate [[macro handler function|Macro Handler]]:
{{{
config.macros.someMacro.handler(place,tiddler,params,wikifier,paramString,tiddler)
}}}
For example in the view title example this would be:
{{{
config.macros.view.handler(place,tiddler,params,wikifier,paramString,tiddler)
}}}
Note: Typically, the tiddler parameter passed to the macro handler function is the same as the 'current tiddler' that is being rendered. However, when you use the "<<tiddler TiddlerName>>" macro to [[transclude]] content from other tiddlers, the //tiddler// param that is passed to any macros ''within the transcluded tiddler'' will reference that transcluded tiddler, rather than the outer //current// tiddler that is being rendered.
!Simple Tables
{{{
|North West|North|North East|
|West|Here|East|
|South West|South|South East|
}}}
Displays as:
|North West|North|North East|
|West|Here|East|
|South West|South|South East|
!Cell Formatting
*Insert a space before cell content to right justify cell
*Insert a space after cell content to left justify cell
*Insert spaces before and after cell content to centre justify cell
*Insert an exclamation mark ({{{!}}}) as the first non-space character of a cell to turn it into a header cell
For example:
{{{
|!First column|!Second column|!Third column|
|left | centre | right|
}}}
Displays as:
|!First column|!Second column|!Third column|
|left | centre | right|
!Table Headers and Footers
* Mark a table row as a header by adding an 'h' to the end
* Mark a table row as a footer by adding an 'f' to the end
For example:
{{{
|North West|North|North East|h
|West|Here|East|
|South West|South|South East|f
}}}
Displays as:
|North West|North|North East|h
|West|Here|East|
|South West|South|South East|f
!Table Caption
A caption can be added above or below a table by adding a special row marked with a 'c':
{{{
|A caption above the table|c
|North West|North|North East|
|West|Here|East|
|South West|South|South East|
}}}
{{{
|North West|North|North East|
|West|Here|East|
|South West|South|South East|
|A caption below the table|c
}}}
Displays as:
|A caption above the table|c
|North West|North|North East|h
|West|Here|East|
|South West|South|South East|f
|North West|North|North East|h
|West|Here|East|
|South West|South|South East|f
|A caption below the table|c
!Mergine Table Cells
A cell can be merged horizontally with the cell to its right by giving it the text {{{>}}}:
{{{
|North West|North|North East|
|>|>|West and Here and East|
|South West|South|South East|
}}}
Displays as:
|North West|North|North East|
|>|>|West and Here and East|
|South West|South|South East|
A cell can be merged vertically with the cell in the row above by giving it the text {{{~}}}:
{{{
|Westerly|North|North East|
|~|Here|East|
|~|South|South East|
}}}
Displays as:
|Westerly|North|North East|
|~|Here|East|
|~|South|South East|
!Table CSS Formatting
A CSS class can be added to an entire table by adding a special row tagged with a 'k':
{{{
|myClass|k
|North West|North|North East|
|West|Here|East|
|South West|South|South East|
}}}
CSS properties can be added to a table cell by preceding the cell content with CSS name/value pairs. There are two alternative forms of syntax:
{{{
|color:red; North West|opacity:0.5;North|North East|
|color(green):West|Here|East|
|South West|South|South East|
}}}
Displays as:
|color:red; North West|opacity:0.5;North|North East|
|color(green):West|Here|East|
|South West|South|South East|
!Alternating Rows
TiddlyWiki automatically assigns the classes {{{oddRow}}} and {{{evenRow}}} to table rows {{{<TR>}}} elements. These can then be styled via the StyleSheet:
{{{
.viewer tr.oddRow { background-color: #fff; }
.viewer tr.evenRow { background-color: #ffc; }
}}}
|''ViewTemplate''|##TWDocViewTemplate|
|''EditTemplate''|##EditTemplate|
|''StyleSheet''|##StyleSheet|
!ViewTemplate
[[TWDocViewTemplate]]
!EditTemplate
[[EditTemplate]]
!StyleSheet
[[StyleSheet]]
''iTW Beta by Bidix''
BidiX has a iPhone optimized version of TiddlyWiki available here: http://itw.bidix.info/
''TW on iPhone using a data url bookmark''
I believe it's possible if you sync the bookmark from safari via iTunes. But you can't save. (Though save to url should be possible. Anyone thought about this?)
''Saving using virtual disk''
It is possible to store TiddlyWiki documents on a [http://groups.google.com/group/TiddlyWiki/browse_thread/thread/35d17fdd24c43391 virtual disk] on the iPhone or iPod Touch.
''Notes from Jeremy''
{{Quote
|[http://groups.google.com/group/TiddlyWiki/browse_thread/thread/e7aa4c89cbb8c84f/3f79cea1ca1b52a7?#3f79cea1ca1b52a7 Jeremy]
|
I've had the chance to play with TiddlyWiki on an iPhone. It works as a pretty perfect clone of the desktop Safari experience, with iPhone pinch-zoom goodness to make it navigable on the tiny display. The problems are:
* it takes ages to load; over EDGE it's excruciating, but even over wifi you have to be pretty patient
* even once it's loaded, JavaScript intensive actions can be painfully slow. For example, clicking on a tiddler link can take more than a second to open the target tiddler
* it doesn't seem possible to load the TW file from a file:// URL; therefore there is no obvious avenue to explore for saving changes locally
* the desktop UI although usable doesn't really work well on the tiny screen; built in iPhone apps like Mail show a more iPhone-native way of accomplishing some of the same things
The planned stripping back of the core code should improve the performance situation. It's possible that a solution to the saving problem will come in the form of a native iPhone app that wraps WebKit to provide a custom host for TiddlyWiki.
In the short term, I've started investigating a plugin to attack the last problem, optimising the TiddlyWiki UI for the iPhone. (Inspired by http://www.joehewitt.com/iui/)
Cheers
Jeremy
}}
''Notes from Phil''
{{Quote
|[http://philhaigh.blogspot.com Phil]
|
Jeremy mentions that it isn't possible to load the TW file from a file:// URL. This is because the iPhone (and iPod Touch) do not have a 'publicly accessible' file system and therefore the browser does not support the file:// protocol on these platforms.
Cheers
Phil
}}
''Notes from Tim''
{{Quote
|Tim
|
It is possible to load a TW file from a file:// URL on jailbroken iPhones. There is a package on ModMyi.com that contains the [[http://modmyi.com/cydia/package.php?id=1387 file schema]]. With jailbroken iPhones, the full filesystem is accessible, through programs such as [[http://www.appleiphoneschool.com/openssh/ SSH]] or [[http://iphone.heinelt.eu/?Applications:iFile iFile]]. If you do use SSH, make sure you change the root password!
Tim
}}
''Notes from Poul''
Some of us would argue that the iPhone is intended as a terminal for telephony and web access. You would store your notes on a server or 'in the cloud' using either of [[hosted|Server-Side Solutions]] solutions like TiddlyWeb or giewiki. That way, the sync problem is not a problem. I admit that with giewiki, I still need to focus on reducing the # of web requests.
Anyway, the biggest problem seems to be that since you don't have cursor keys, you can't scroll in edit boxes (or can you..yes: use 2 fingers & lors of patience).
[[Category:FAQ]]
[[Category:Using TiddlyWiki]]
[[Category:Platforms]]
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 40 40"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs><linearGradient id="lG3826" x1="7.0996" gradientUnits="userSpaceOnUse" y1="18.829" gradientTransform="matrix(1.5858347,0,0,1.8078238,1098.1851,351.13716)" x2="1.5461" y2="-0.95166"><stop stop-color="#000" offset="0"/><stop stop-color="#9c9b99" offset="1"/></linearGradient><linearGradient id="lG3828" y2="372.44" gradientUnits="userSpaceOnUse" y1="375.7" x2="1111.7" x1="1097.7"><stop style="stop-color:#ac9393;" offset="0"/><stop style="stop-color:#c8b7b7;" offset="1"/></linearGradient></defs><g transform="translate(-1080.9375,-357.3329)"><path style="stroke-width:0;stroke-miterlimit:4;fill:url(#lG3826);" d="m1080.9,357.32,39.996-0.0426-0.01,40.008c-15.507-25.519-15.36-25.95-39.988-39.965z"/><path style="stroke-dashoffset:0;stroke:#7aa3be;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.49999988;fill:#c1e6fd;" d="m1091.9,363.55c6.5716-6.4925,16.576-7.3925,23.147-0.90003,6.5717,6.4925,6.5717,17.019,0,23.511-4.4424-8.6113-12.288-15.713-23.147-22.611z"/><path style="stroke-dashoffset:0;stroke:#ce81b0;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.5;fill:#f4c4e2;" d="m1110.2,367.62c3.217,3.2168,3.217,8.4323,0,11.649-3.8194-4.2357-8.3307-8.1824-11.649-11.649,3.217-3.2168,8.4325-3.2168,11.649-0.00002z"/><path style="stroke-linejoin:bevel;stroke:#000000;stroke-linecap:round;stroke-dasharray:none;stroke-miterlimit:4;stroke-width:0.80000001;fill:url(#lG3828);" d="m1081,357.34c18.79,6.4752,32.53,16.56,39.894,39.892-11.19-17.028-14.878-19.19-27.352-14.96,6.2984-12.098,3.9371-13.19-12.542-24.932z"/></g></svg>
The global function setStylesheet adds a custom stylesheet to the document. This replaces any stylesheet already set with the same DOM id with this function. There are two parameters to this function:
* a string containing CSS source code
* a DOM id to assign to the new stylesheet
This function does not return any value.
TiddlyHome is a package design as an infrastructure for multi-user and multi-site TiddlyWiki hosting service based on UploadPlugin.
TiddlyHome 0.1.4 is in beta stage and use TiddlyWiki 2.4.1
[[TiddlyHome|http://tiddlyhome.bidix.info/]]
Edit the ViewTemplate tiddler.
This is a special tiddler(a [[Shadow Tiddler]]) which allows you to control the layout and functionality used for displaying a [[Tiddler]] in TiddlyWiki. See [[here|http://tiddlywiki.org/wiki/ViewTemplate]].
Read more about the [[ViewTemplate Shadow tiddler|Shadow - ViewTemplate]]@shadowtiddlers
The tagging macro lists all the tiddlers that have a given tag. You set the tag you are looking for as the first parameter. E.g. to look for all tiddlers tagged with ''transclude'' you need to do the following:
{{{
<<tagging transclude>>
}}}
Displays as:
<<tagging transclude>>
This macro also accepts a 2nd parameter which allows you to define a separator.
{{{
<<tagging transclude sep:____>> e.g. <<tagging transclude sep:---------->>
}}}
Displays as:
<<tagging transclude sep:---------->>
/***
|''Name''|TiddlySpaceFollowingPlugin|
|''Version''|0.7.1|
|''Description''|Provides a following macro|
|''Author''|Jon Robson|
|''Requires''|TiddlySpaceConfig TiddlySpaceTiddlerIconsPlugin ErrorHandler|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
Tag a tiddler with "follow" to express a list of followers.
Using the {{{<<followTiddlers X>>}}}
will reveal the number of tiddlers with name X in the set of spaces the *current* user viewing your space follows.
{{{<<following jon>>}}} will list all the users following Jon.
{{{<<followers jon>>}}} will list all the followers of jon.
{{{<linkedTiddlers>>}}} will list all tiddlers across TiddlySpace linked to the current tiddler
{{{<linkedTiddlers follow:yes>>}}} will list all tiddlers across TiddlySpace that come from your list of followers
adds spaceLink view type {{{<<view server.bag spaceLink>>}}} creates a link to the space described in server.bag
{{{<<view server.bag spaceLink title>>}}} makes a link to the tiddler with title expressed in the field title in space server.bag
If no name is given eg. {{{<<following>>}}} or {{{<<follow>>}}} it will default the current user.
!StyleSheet
.followTiddlersList li {
list-style:none;
}
.followButton {
width: 2em;
}
.followTiddlersList li .siteIcon {
height:48px;
width: 48px;
}
#sidebarTabs .followers li a,
.followers .siteIcon,
.followers .siteIcon div {
display: inline;
}
.followTiddlersList li .externalImage, .followTiddlersList li .image {
display: inline;
}
.scanResults li {
list-style: none;
}
!Code
***/
//{{{
(function($) {
var LIMIT_FOLLOWING = 100;
var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
var shadows = config.shadowTiddlers;
config.annotations.ScanTemplate = "This tiddler is the default template used in the display of tiddlers founding using the tsScan macro. To access attributes use the view macro e.g. {{{<<view title text>>}}}";
shadows.ScanTemplate = "<<view modifier SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title link>>";
shadows.FollowersTemplate = "<<view server.bag SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view server.bag spaceLink>>";
shadows.FollowingTemplate = "<<view title SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title spaceLink>>";
shadows.FollowTiddlersBlackList = "";
shadows.FollowTiddlersHeading = "There are tiddlers in spaces you follow using the follow tag which use the title <<view title text>>";
shadows.FollowTiddlersTemplate = ["* <<view server.space SiteIcon width:24 height:24 spaceLink:yes label:no>> ",
"<<view server.space spaceLink title external:no>> modified by <<view modifier spaceLink>> ",
"in the <<view server.space spaceLink>> space (<<view modified date>> @ <<view modified date 0hh:0mm>>).\n"].join("");
var name = "StyleSheetFollowing";
shadows[name] = "/*{{{*/\n%0\n/*}}}*/".
format(store.getTiddlerText(tiddler.title + "##StyleSheet"));
store.addNotification(name, refreshStyles);
// provide support for sucking in tiddlers from the server
tiddlyspace.displayServerTiddler = function(src, title, workspace, callback) {
var adaptor = store.getTiddlers()[0].getAdaptor();
var localTitle = tiddlyspace.getLocalTitle(title, workspace);
var tiddler = new Tiddler(localTitle);
tiddler.text = "Please wait while this tiddler is retrieved...";
tiddler.fields.doNotSave = "true";
store.addTiddler(tiddler);
src = story.displayTiddler(src || null, tiddler.title);
tweb.getStatus(function(status) {
var context = {
host: tweb.host, // TODO: inherit from source tiddler?
workspace: workspace,
headers: { "X-ControlView": "false" }
};
var getCallback = function(context, userParams) {
var tiddler = context.tiddler;
tiddler.title = localTitle;
store.addTiddler(tiddler);
story.refreshTiddler(localTitle, null, true); // overriding existing allows updating
if(callback) {
callback(src, tiddler);
}
};
adaptor.getTiddler(title, context, null, getCallback);
});
};
tiddlyspace.scroller = {
runHandler: function(title, top, bottom, height) {
var i;
var handlers = tiddlyspace.scroller.handlers;
var tidEl = story.getTiddler(title);
if(tidEl) {
var topEl = $(tidEl).offset().top + 20;
if(top === false || (topEl > top && topEl < bottom)) {
var h = handlers[title];
for(i = 0; i < h.length; i++) {
h[i]();
}
tiddlyspace.scroller.clearHandlers(title);
}
} else {
tiddlyspace.scroller.clearHandlers(title);
}
},
clearHandlers: function(title) {
tiddlyspace.scroller.handlers[title] = [];
},
registerIsVisibleEvent: function(title, handler) {
tiddlyspace.scroller.handlers[title] = tiddlyspace.scroller.handlers[title] || [];
tiddlyspace.scroller.handlers[title].push(handler);
},
init: function() {
this.handlers = {};
this.interval = window.setInterval(function() {
var top = $(window).scrollTop();
var height = $(window).height();
var bottom = top + height;
var title;
for(title in tiddlyspace.scroller.handlers) {
if(title) {
tiddlyspace.scroller.runHandler(title, top, bottom, height);
}
}
}, 2000); // every 2 seconds check scroll position
}
};
tiddlyspace.scroller.init();
var followMacro = config.macros.followTiddlers = {
locale: {
followListHeader: "Here are tiddlers from spaces you follow using the follow tag which use this title.",
noTiddlersFromFollowers: "None of the spaces you follow contain a tiddler with this name.",
errorMessage: "There was a problem retrieving tiddlers from the server. Please try again later."
},
init: function() {
followMacro.lookup = {};
},
followTag: "follow",
getHosts: function(callback) {
tweb.getStatus(function(status) {
callback(tweb.host, tiddlyspace.getHost(status.server_host, "%0"));
});
},
getBlacklist: function() {
return store.getTiddlerText("FollowTiddlersBlackList").split("\n");
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var args = paramString.parseParams("anon")[0];
var containingTiddler = story.findContainingTiddler(place).getAttribute('tiddler');
var title = (args.anon && args.anon[0]) || tiddler.fields["server.title"] || tiddler.title;
var tid = store.getTiddler(title);
var user = params[1] || false;
if(tid) {
followMacro.makeButton(place, {
url: "/search?q=title:%22"
+ encodeURIComponent(title) + "%22",
containingTiddler: containingTiddler,
blacklisted: followMacro.getBlacklist(), title: title, user: user,
consultFollowRelationship: (args.follow &&
args.follow[0] === 'false') ? false : true });
}
},
makeButton: function(place, options) { // this is essentially the same code in TiddlySpaceFollowingPlugin
var title = options.title;
var blacklisted = options.blacklisted;
var tiddler = store.getTiddler(title);
var btn = $('<div class="followButton" />').addClass("notLoaded").appendTo(place)[0];
if(blacklisted.contains(title)) {
$(btn).remove();
return;
} else {
var user = options.user;
window.setTimeout(function() { // prevent multiple calls due to refresh
tiddlyspace.scroller.registerIsVisibleEvent(options.containingTiddler, function() {
var mkButton = function(followers, ignore) {
if(!followers && !ignore) {
$(btn).remove();
} else {
$("<a />").appendTo(btn);
var scanOptions = { url: options.url,
spaceField: options.spaceField || "bag", template: null, sort: "-modified",
callback: function(tiddlers) {
$(btn).removeClass("notLoaded");
followMacro.constructInterface(btn, tiddlers);
}
};
if(!ignore) {
scanOptions.showBags = followMacro._getFollowerBags(followers);
}
scanOptions.hideBags = [tiddler.fields["server.bag"]];
scanMacro.scan(null, scanOptions, user);
}
};
if(options.consultFollowRelationship) {
followMacro.getFollowers(mkButton);
} else {
mkButton([], true);
}
});
}, 1000);
}
},
constructInterface: function(container, tiddlers) {
var txt = tiddlers.length;
var className = txt > 0 ? "hasReplies" : "noReplies";
var el = $(story.findContainingTiddler(container));
$(container).empty().addClass(className);
var btn = $("<a />").addClass("followedTiddlers").text(txt).
click(function(ev) {
followMacro.followingOnClick(ev);
}).appendTo('<div class="followedTiddlers" />').appendTo(container)[0];
$.data(btn, "tiddlers", tiddlers);
},
followingOnClick: function(ev) {
var target = ev.target;
var locale = followMacro.locale;
var el = $('<div class="followTiddlersList" />')[0];
var popup = Popup.create(target,"div");
$(popup).addClass("taggedTiddlerList followList").click(function(ev) { // make it so only clicking on the document outside the popup removes the popup
if(ev.target.parentNode != document) {
ev.stopPropagation();
}
}).append(el);
var tiddlers = $.data(target, "tiddlers") || [];
scanMacro.template(el, tiddlers.slice(0,1), "FollowTiddlersHeading");
scanMacro.template(el, tiddlers, "FollowTiddlersTemplate");
if(tiddlers.length === 0) {
$("<li />").text(locale.noTiddlersFromFollowers).appendTo(el);
}
Popup.show();
ev.stopPropagation();
return popup;
},
_getFollowerBags: function(followers) { // XXX: private or not?
return $.map(followers, function(name, i) {
return name != currentSpace ? "%0_public".format(name) : null;
});
},
getFollowers: function(callback, username) {
// returns a list of spaces being followed by the existing space
var followersCallback = function(user) {
if(!user.anon) {
scanMacro.scan(null, {
url: "/search?q=bag:%0_public tag:%1 _limit:%2".format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
spaceField: "title", template: null, cache: true,
callback: function(tiddlers) {
var followers = [];
for(var i = 0; i < tiddlers.length; i++) {
followers.push(tiddlyspace.resolveSpaceName(tiddlers[i].title));
}
callback(followers);
}
});
} else {
callback(false);
}
};
return !username ? tweb.getUserInfo(followersCallback) : followersCallback({ name: username });
}
};
var scanMacro = config.macros.tsScan = {
init: function () {
this.scanned = {};
},
_tiddlerfy: function(jsontiddlers, options) {
var tiddlers = [];
var spaceField = options.spaceField || "bag"; // TODO: phase out use view types instead
$.each(jsontiddlers, function(i, t) {
var use = false;
if(!options.showBags || (options.showBags && options.showBags.contains(t.bag))) {
use = true;
}
if(options.hideBags && options.hideBags.contains(t.bag)) {
use = false;
}
if(use) {
var spaceName = t[spaceField];
var tiddler = config.adaptors.tiddlyweb.toTiddler(t, tweb.host);
tiddler.fields["server.space"] = tiddlyspace.resolveSpaceName(spaceName);
tiddlers.push(tiddler);
}
});
return tiddlers;
},
_scanCallback: function(place, jsontiddlers, options) {
var locale = followersMacro.locale;
var tiddlers = scanMacro._tiddlerfy(jsontiddlers, options);
if(options.sort) {
tiddlers = store.sortTiddlers(tiddlers, options.sort);
}
if(options.filter) {
var _store = new TiddlyWiki();
config.lastStore = _store;
for(var i = 0; i < tiddlers.length; i++) {
var clone = tiddlers[i];
clone.title = tiddlyspace.getLocalTitle(clone.title, clone.fields['server.workspace']);
_store.addTiddler(clone);
}
tiddlers = _store.filterTiddlers(options.filter);
}
if(place) {
$(place).empty();
var list = $("<ul />").appendTo(place)[0];
scanMacro.template(list, tiddlers, options.template);
if(tiddlers.length === 0) {
$("<li />").text(options.emptyMessage || locale.noone).appendTo(list);
$(list).addClass("emptyList");
}
}
if(options.callback) {
options.callback(tiddlers);
}
},
constructSearchUrl: function(host, options) {
if(options.url) {
return options.url;
}
var inputs = options.searchValues;
var tag = options.tag;
var searchField = options.searchField || "title";
var searchQuery = [];
for(var i = 0; i < inputs.length; i++) {
searchQuery.push('%0:"%1"'.format(searchField, inputs[i]));
}
var query = searchQuery.join(" OR ");
query = tag ? "(%0) AND tag:%1".format(query, tag) : query;
query = options.query ? "%0;%1;".format(query, options.query) : query;
query = options.fat ? "%0&fat=1".format(query) : query;
return '%0/search?q=%1'.format(host, query);
},
scan: function(place, options) { // TODO: make use of list macro with url filter
var locale = followersMacro.locale;
options.template = options.template ? options.template : "ScanTemplate";
followMacro.getHosts(function(host, tsHost) {
$(place).text(followersMacro.locale.pleaseWait);
options = options ? options: {};
var url = scanMacro.constructSearchUrl(host, options);
if(options.cache && scanMacro.scanned[url]) {
var tiddlers = scanMacro.scanned[url].tiddlers;
var run = function(tiddlers) {
scanMacro._scanCallback(place, tiddlers, options);
};
if(tiddlers) {
run(tiddlers);
} else {
scanMacro.scanned[url].callbacks.push(run);
}
} else {
var callback = function(tiddlers) {
scanMacro._scanCallback(place, tiddlers, options);
};
if(scanMacro.scanned[url] && scanMacro.scanned[url].callbacks) {
scanMacro.scanned[url].callbacks.push(callback)
} else {
scanMacro.scanned[url] = {
callbacks: [callback]
};
}
ajaxReq({
url: url,
dataType: "json",
success: function(tiddlers) {
scanMacro.scanned[url].tiddlers = tiddlers;
var callbacks = scanMacro.scanned[url].callbacks;
while(callbacks.length > 0) {
callbacks.pop()(tiddlers);
}
},
error: function(xhr) {
$(place).empty();
$("<span />").addClass("annotation error").text(locale.error.format(xhr.status)).appendTo(place);
}
});
}
});
},
template: function(place, tiddlers, template) { // TODO: make use of list macro.
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var item = $('<li class="spaceName" />').appendTo(place)[0];
var spaceName = tiddler.fields["server.space"] || "";
var templateText = store.getTiddlerText(template).replace(/\$1/mg, spaceName);
wikify(templateText, item, null, tiddler);
}
},
getOptions: function(paramString, tiddler) {
var args = paramString.parseParams("name", null, true, false, true)[0];
var options = { query: false, sort: false, tag: false, template: false, showBags: args.show || false,
hideBags: args.hide || false, filter: false, spaceField: "bag", searchField: "title", fat: false,
emptyMessage: false };
for(var name in args) {
if(name != "name") {
if(name == "fat") {
options[name] = true;
} else {
options[name] = args[name][0];
}
}
}
// if user has set searchField to modifier, then use the modifiers value if available otherwise use searchValues.
var searchField = options.searchField;
var searchValues = args[searchField] ? args[searchField] : args.searchValues;
// if neither of those were used use the first parameter
var defaultValues = tiddler ? [ tiddler.title ] : [];
options.searchValues = searchValues ? searchValues : ( args.name ? [args.name[0]] : defaultValues);
return options;
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var container = $("<div />").addClass("scanResults resultsArea").appendTo(place)[0];
var options = scanMacro.getOptions(paramString, tiddler);
scanMacro.scan(container, options);
}
};
var followersMacro = config.macros.followers = {
locale: {
loggedOut: "Please login to see the list of followers",
noSupport: "We were unable to retrieve followers as your browser does not support following.",
pleaseWait: "Please wait while we look this up...",
error: "Error %0 occurred whilst retrieving data from server",
noone: "None."
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var locale = followersMacro.locale;
var args = paramString.parseParams("name", null, true, false, true)[0];
var username = args.name ? args.name[0] : false;
var container = $('<div class="followers" />').text(locale.pleaseWait).
appendTo(place)[0];
var followersCallback = function(user) {
if(user.anon) {
$("<span />").text(locale.loggedOut).appendTo(container);
} else {
var options = scanMacro.getOptions(paramString);
$.extend(options, {
url: "/search?q=title:@%0 OR title:%0 tag:%1 _limit:%2".
format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
spaceField: "bag",
template: options.template ? options.template : "FollowersTemplate"
});
scanMacro.scan(container, options);
}
};
return !username ? followersCallback({ name: currentSpace }) : followersCallback({ name: username });
}
};
var followingMacro = config.macros.following = {
locale: {
pleaseWait: followersMacro.locale.pleaseWait,
loggedOut: "Please login to see who you are following",
noSupport: followersMacro.locale.noSupport,
error: followersMacro.locale.error,
noone: followersMacro.locale.noone
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var locale = followingMacro.locale;
var args = paramString.parseParams("name", null, true, false, true)[0];
var fat = args.fat ? true : false;
var username = args.name ? args.name[0] : false;
var container = $('<div class="following" />').text(locale.pleaseWait).
appendTo(place)[0];
var followingCallback = function(user) {
if(user.anon) {
$("<span />").text(locale.loggedOut).appendTo(container);
} else {
var options = scanMacro.getOptions(paramString);
$.extend(options, {
url: "/search?q=bag:%0_public tag:%1 _limit:%2".format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
spaceField: "title",
template: options.template ? options.template : "FollowingTemplate"
});
scanMacro.scan(container, options);
}
};
return !username ? followingCallback({ name: currentSpace }) : followingCallback({ name: username });
}
};
var linkedMacro = config.macros.linkedTiddlers = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var args = paramString.parseParams("anon")[0];
var title = params[0] || tiddler.fields["server.title"] || tiddler.title;
var tid = store.getTiddler(title);
var containingTiddler = story.findContainingTiddler(place).getAttribute('tiddler');
if(tid) {
followMacro.makeButton(place, {
spaceField: "recipe",
url: "/bags/%0/tiddlers/%1/backlinks".format(tid.fields['server.bag'],
encodeURIComponent(tid.title)),
blacklisted: followMacro.getBlacklist(),
title: title,
containingTiddler: containingTiddler,
user: params[1] || false,
consultFollowRelationship: args.follow ? true : false });
}
}
}
if(config.options.chkFollowTiddlersIsLinkedTiddlers) {
merge(config.macros.followTiddlers, config.macros.linkedTiddlers);
config.shadowTiddlers.FollowTiddlersHeading = "These are the other tiddlers that link to this tiddler.";
}
})(jQuery);
//}}}
|Name|HideWhenPlugin|
|Author|[[SimonBaird]]|
|URL|http://mptw.tiddlyspot.com/|
|Description|Allows conditional inclusion/exclusion in templates.|
The StyleSheet tiddler allows you to customise the look and feel of your TiddlyWiki using CSS
You can put simple one line tweaks in, like:
{{{
.mainMenu { color: red; }
}}}
Or you can put in full ~StyleSheets, like that seen in TiddlySpace in the StyleSheetTiddlySpace
{{{
/*{{{*/
[[StyleSheetTiddlySpace]]
/*}}}*/
}}}
/*!
* jQuery JavaScript Library v1.4.4
* http://jquery.com/
*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* Includes Sizzle.js
* http://sizzlejs.com/
* Copyright 2010, The Dojo Foundation
* Released under the MIT, BSD, and GPL Licenses.
*
* Date: Thu Nov 11 19:04:53 2010 -0500
*/
(function(E,B){function ka(a,b,d){if(d===B&&a.nodeType===1){d=a.getAttribute("data-"+b);if(typeof d==="string"){try{d=d==="true"?true:d==="false"?false:d==="null"?null:!c.isNaN(d)?parseFloat(d):Ja.test(d)?c.parseJSON(d):d}catch(e){}c.data(a,b,d)}else d=B}return d}function U(){return false}function ca(){return true}function la(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function Ka(a){var b,d,e,f,h,l,k,o,x,r,A,C=[];f=[];h=c.data(this,this.nodeType?"events":"__events__");if(typeof h==="function")h=
h.events;if(!(a.liveFired===this||!h||!h.live||a.button&&a.type==="click")){if(a.namespace)A=RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)");a.liveFired=this;var J=h.live.slice(0);for(k=0;k<J.length;k++){h=J[k];h.origType.replace(X,"")===a.type?f.push(h.selector):J.splice(k--,1)}f=c(a.target).closest(f,a.currentTarget);o=0;for(x=f.length;o<x;o++){r=f[o];for(k=0;k<J.length;k++){h=J[k];if(r.selector===h.selector&&(!A||A.test(h.namespace))){l=r.elem;e=null;if(h.preType==="mouseenter"||
h.preType==="mouseleave"){a.type=h.preType;e=c(a.relatedTarget).closest(h.selector)[0]}if(!e||e!==l)C.push({elem:l,handleObj:h,level:r.level})}}}o=0;for(x=C.length;o<x;o++){f=C[o];if(d&&f.level>d)break;a.currentTarget=f.elem;a.data=f.handleObj.data;a.handleObj=f.handleObj;A=f.handleObj.origHandler.apply(f.elem,arguments);if(A===false||a.isPropagationStopped()){d=f.level;if(A===false)b=false;if(a.isImmediatePropagationStopped())break}}return b}}function Y(a,b){return(a&&a!=="*"?a+".":"")+b.replace(La,
"`").replace(Ma,"&")}function ma(a,b,d){if(c.isFunction(b))return c.grep(a,function(f,h){return!!b.call(f,h,f)===d});else if(b.nodeType)return c.grep(a,function(f){return f===b===d});else if(typeof b==="string"){var e=c.grep(a,function(f){return f.nodeType===1});if(Na.test(b))return c.filter(b,e,!d);else b=c.filter(b,e)}return c.grep(a,function(f){return c.inArray(f,b)>=0===d})}function na(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var e=c.data(a[d++]),f=c.data(this,
e);if(e=e&&e.events){delete f.handle;f.events={};for(var h in e)for(var l in e[h])c.event.add(this,h,e[h][l],e[h][l].data)}}})}function Oa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function oa(a,b,d){var e=b==="width"?a.offsetWidth:a.offsetHeight;if(d==="border")return e;c.each(b==="width"?Pa:Qa,function(){d||(e-=parseFloat(c.css(a,"padding"+this))||0);if(d==="margin")e+=parseFloat(c.css(a,
"margin"+this))||0;else e-=parseFloat(c.css(a,"border"+this+"Width"))||0});return e}function da(a,b,d,e){if(c.isArray(b)&&b.length)c.each(b,function(f,h){d||Ra.test(a)?e(a,h):da(a+"["+(typeof h==="object"||c.isArray(h)?f:"")+"]",h,d,e)});else if(!d&&b!=null&&typeof b==="object")c.isEmptyObject(b)?e(a,""):c.each(b,function(f,h){da(a+"["+f+"]",h,d,e)});else e(a,b)}function S(a,b){var d={};c.each(pa.concat.apply([],pa.slice(0,b)),function(){d[this]=a});return d}function qa(a){if(!ea[a]){var b=c("<"+
a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d==="")d="block";ea[a]=d}return ea[a]}function fa(a){return c.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var t=E.document,c=function(){function a(){if(!b.isReady){try{t.documentElement.doScroll("left")}catch(j){setTimeout(a,1);return}b.ready()}}var b=function(j,s){return new b.fn.init(j,s)},d=E.jQuery,e=E.$,f,h=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,l=/\S/,k=/^\s+/,o=/\s+$/,x=/\W/,r=/\d/,A=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,
C=/^[\],:{}\s]*$/,J=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,w=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,I=/(?:^|:|,)(?:\s*\[)+/g,L=/(webkit)[ \/]([\w.]+)/,g=/(opera)(?:.*version)?[ \/]([\w.]+)/,i=/(msie) ([\w.]+)/,n=/(mozilla)(?:.*? rv:([\w.]+))?/,m=navigator.userAgent,p=false,q=[],u,y=Object.prototype.toString,F=Object.prototype.hasOwnProperty,M=Array.prototype.push,N=Array.prototype.slice,O=String.prototype.trim,D=Array.prototype.indexOf,R={};b.fn=b.prototype={init:function(j,
s){var v,z,H;if(!j)return this;if(j.nodeType){this.context=this[0]=j;this.length=1;return this}if(j==="body"&&!s&&t.body){this.context=t;this[0]=t.body;this.selector="body";this.length=1;return this}if(typeof j==="string")if((v=h.exec(j))&&(v[1]||!s))if(v[1]){H=s?s.ownerDocument||s:t;if(z=A.exec(j))if(b.isPlainObject(s)){j=[t.createElement(z[1])];b.fn.attr.call(j,s,true)}else j=[H.createElement(z[1])];else{z=b.buildFragment([v[1]],[H]);j=(z.cacheable?z.fragment.cloneNode(true):z.fragment).childNodes}return b.merge(this,
j)}else{if((z=t.getElementById(v[2]))&&z.parentNode){if(z.id!==v[2])return f.find(j);this.length=1;this[0]=z}this.context=t;this.selector=j;return this}else if(!s&&!x.test(j)){this.selector=j;this.context=t;j=t.getElementsByTagName(j);return b.merge(this,j)}else return!s||s.jquery?(s||f).find(j):b(s).find(j);else if(b.isFunction(j))return f.ready(j);if(j.selector!==B){this.selector=j.selector;this.context=j.context}return b.makeArray(j,this)},selector:"",jquery:"1.4.4",length:0,size:function(){return this.length},
toArray:function(){return N.call(this,0)},get:function(j){return j==null?this.toArray():j<0?this.slice(j)[0]:this[j]},pushStack:function(j,s,v){var z=b();b.isArray(j)?M.apply(z,j):b.merge(z,j);z.prevObject=this;z.context=this.context;if(s==="find")z.selector=this.selector+(this.selector?" ":"")+v;else if(s)z.selector=this.selector+"."+s+"("+v+")";return z},each:function(j,s){return b.each(this,j,s)},ready:function(j){b.bindReady();if(b.isReady)j.call(t,b);else q&&q.push(j);return this},eq:function(j){return j===
-1?this.slice(j):this.slice(j,+j+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(N.apply(this,arguments),"slice",N.call(arguments).join(","))},map:function(j){return this.pushStack(b.map(this,function(s,v){return j.call(s,v,s)}))},end:function(){return this.prevObject||b(null)},push:M,sort:[].sort,splice:[].splice};b.fn.init.prototype=b.fn;b.extend=b.fn.extend=function(){var j,s,v,z,H,G=arguments[0]||{},K=1,Q=arguments.length,ga=false;
if(typeof G==="boolean"){ga=G;G=arguments[1]||{};K=2}if(typeof G!=="object"&&!b.isFunction(G))G={};if(Q===K){G=this;--K}for(;K<Q;K++)if((j=arguments[K])!=null)for(s in j){v=G[s];z=j[s];if(G!==z)if(ga&&z&&(b.isPlainObject(z)||(H=b.isArray(z)))){if(H){H=false;v=v&&b.isArray(v)?v:[]}else v=v&&b.isPlainObject(v)?v:{};G[s]=b.extend(ga,v,z)}else if(z!==B)G[s]=z}return G};b.extend({noConflict:function(j){E.$=e;if(j)E.jQuery=d;return b},isReady:false,readyWait:1,ready:function(j){j===true&&b.readyWait--;
if(!b.readyWait||j!==true&&!b.isReady){if(!t.body)return setTimeout(b.ready,1);b.isReady=true;if(!(j!==true&&--b.readyWait>0))if(q){var s=0,v=q;for(q=null;j=v[s++];)j.call(t,b);b.fn.trigger&&b(t).trigger("ready").unbind("ready")}}},bindReady:function(){if(!p){p=true;if(t.readyState==="complete")return setTimeout(b.ready,1);if(t.addEventListener){t.addEventListener("DOMContentLoaded",u,false);E.addEventListener("load",b.ready,false)}else if(t.attachEvent){t.attachEvent("onreadystatechange",u);E.attachEvent("onload",
b.ready);var j=false;try{j=E.frameElement==null}catch(s){}t.documentElement.doScroll&&j&&a()}}},isFunction:function(j){return b.type(j)==="function"},isArray:Array.isArray||function(j){return b.type(j)==="array"},isWindow:function(j){return j&&typeof j==="object"&&"setInterval"in j},isNaN:function(j){return j==null||!r.test(j)||isNaN(j)},type:function(j){return j==null?String(j):R[y.call(j)]||"object"},isPlainObject:function(j){if(!j||b.type(j)!=="object"||j.nodeType||b.isWindow(j))return false;if(j.constructor&&
!F.call(j,"constructor")&&!F.call(j.constructor.prototype,"isPrototypeOf"))return false;for(var s in j);return s===B||F.call(j,s)},isEmptyObject:function(j){for(var s in j)return false;return true},error:function(j){throw j;},parseJSON:function(j){if(typeof j!=="string"||!j)return null;j=b.trim(j);if(C.test(j.replace(J,"@").replace(w,"]").replace(I,"")))return E.JSON&&E.JSON.parse?E.JSON.parse(j):(new Function("return "+j))();else b.error("Invalid JSON: "+j)},noop:function(){},globalEval:function(j){if(j&&
l.test(j)){var s=t.getElementsByTagName("head")[0]||t.documentElement,v=t.createElement("script");v.type="text/javascript";if(b.support.scriptEval)v.appendChild(t.createTextNode(j));else v.text=j;s.insertBefore(v,s.firstChild);s.removeChild(v)}},nodeName:function(j,s){return j.nodeName&&j.nodeName.toUpperCase()===s.toUpperCase()},each:function(j,s,v){var z,H=0,G=j.length,K=G===B||b.isFunction(j);if(v)if(K)for(z in j){if(s.apply(j[z],v)===false)break}else for(;H<G;){if(s.apply(j[H++],v)===false)break}else if(K)for(z in j){if(s.call(j[z],
z,j[z])===false)break}else for(v=j[0];H<G&&s.call(v,H,v)!==false;v=j[++H]);return j},trim:O?function(j){return j==null?"":O.call(j)}:function(j){return j==null?"":j.toString().replace(k,"").replace(o,"")},makeArray:function(j,s){var v=s||[];if(j!=null){var z=b.type(j);j.length==null||z==="string"||z==="function"||z==="regexp"||b.isWindow(j)?M.call(v,j):b.merge(v,j)}return v},inArray:function(j,s){if(s.indexOf)return s.indexOf(j);for(var v=0,z=s.length;v<z;v++)if(s[v]===j)return v;return-1},merge:function(j,
s){var v=j.length,z=0;if(typeof s.length==="number")for(var H=s.length;z<H;z++)j[v++]=s[z];else for(;s[z]!==B;)j[v++]=s[z++];j.length=v;return j},grep:function(j,s,v){var z=[],H;v=!!v;for(var G=0,K=j.length;G<K;G++){H=!!s(j[G],G);v!==H&&z.push(j[G])}return z},map:function(j,s,v){for(var z=[],H,G=0,K=j.length;G<K;G++){H=s(j[G],G,v);if(H!=null)z[z.length]=H}return z.concat.apply([],z)},guid:1,proxy:function(j,s,v){if(arguments.length===2)if(typeof s==="string"){v=j;j=v[s];s=B}else if(s&&!b.isFunction(s)){v=
s;s=B}if(!s&&j)s=function(){return j.apply(v||this,arguments)};if(j)s.guid=j.guid=j.guid||s.guid||b.guid++;return s},access:function(j,s,v,z,H,G){var K=j.length;if(typeof s==="object"){for(var Q in s)b.access(j,Q,s[Q],z,H,v);return j}if(v!==B){z=!G&&z&&b.isFunction(v);for(Q=0;Q<K;Q++)H(j[Q],s,z?v.call(j[Q],Q,H(j[Q],s)):v,G);return j}return K?H(j[0],s):B},now:function(){return(new Date).getTime()},uaMatch:function(j){j=j.toLowerCase();j=L.exec(j)||g.exec(j)||i.exec(j)||j.indexOf("compatible")<0&&n.exec(j)||
[];return{browser:j[1]||"",version:j[2]||"0"}},browser:{}});b.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(j,s){R["[object "+s+"]"]=s.toLowerCase()});m=b.uaMatch(m);if(m.browser){b.browser[m.browser]=true;b.browser.version=m.version}if(b.browser.webkit)b.browser.safari=true;if(D)b.inArray=function(j,s){return D.call(s,j)};if(!/\s/.test("\u00a0")){k=/^[\s\xA0]+/;o=/[\s\xA0]+$/}f=b(t);if(t.addEventListener)u=function(){t.removeEventListener("DOMContentLoaded",u,
false);b.ready()};else if(t.attachEvent)u=function(){if(t.readyState==="complete"){t.detachEvent("onreadystatechange",u);b.ready()}};return E.jQuery=E.$=b}();(function(){c.support={};var a=t.documentElement,b=t.createElement("script"),d=t.createElement("div"),e="script"+c.now();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var f=d.getElementsByTagName("*"),h=d.getElementsByTagName("a")[0],l=t.createElement("select"),
k=l.appendChild(t.createElement("option"));if(!(!f||!f.length||!h)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(h.getAttribute("style")),hrefNormalized:h.getAttribute("href")==="/a",opacity:/^0.55$/.test(h.style.opacity),cssFloat:!!h.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:k.selected,deleteExpando:true,optDisabled:false,checkClone:false,
scriptEval:false,noCloneEvent:true,boxModel:null,inlineBlockNeedsLayout:false,shrinkWrapBlocks:false,reliableHiddenOffsets:true};l.disabled=true;c.support.optDisabled=!k.disabled;b.type="text/javascript";try{b.appendChild(t.createTextNode("window."+e+"=1;"))}catch(o){}a.insertBefore(b,a.firstChild);if(E[e]){c.support.scriptEval=true;delete E[e]}try{delete b.test}catch(x){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function r(){c.support.noCloneEvent=
false;d.detachEvent("onclick",r)});d.cloneNode(true).fireEvent("onclick")}d=t.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=t.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var r=t.createElement("div");r.style.width=r.style.paddingLeft="1px";t.body.appendChild(r);c.boxModel=c.support.boxModel=r.offsetWidth===2;if("zoom"in r.style){r.style.display="inline";r.style.zoom=
1;c.support.inlineBlockNeedsLayout=r.offsetWidth===2;r.style.display="";r.innerHTML="<div style='width:4px;'></div>";c.support.shrinkWrapBlocks=r.offsetWidth!==2}r.innerHTML="<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";var A=r.getElementsByTagName("td");c.support.reliableHiddenOffsets=A[0].offsetHeight===0;A[0].style.display="";A[1].style.display="none";c.support.reliableHiddenOffsets=c.support.reliableHiddenOffsets&&A[0].offsetHeight===0;r.innerHTML="";t.body.removeChild(r).style.display=
"none"});a=function(r){var A=t.createElement("div");r="on"+r;var C=r in A;if(!C){A.setAttribute(r,"return;");C=typeof A[r]==="function"}return C};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=f=h=null}})();var ra={},Ja=/^(?:\{.*\}|\[.*\])$/;c.extend({cache:{},uuid:0,expando:"jQuery"+c.now(),noData:{embed:true,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:true},data:function(a,b,d){if(c.acceptData(a)){a=a==E?ra:a;var e=a.nodeType,f=e?a[c.expando]:null,h=
c.cache;if(!(e&&!f&&typeof b==="string"&&d===B)){if(e)f||(a[c.expando]=f=++c.uuid);else h=a;if(typeof b==="object")if(e)h[f]=c.extend(h[f],b);else c.extend(h,b);else if(e&&!h[f])h[f]={};a=e?h[f]:h;if(d!==B)a[b]=d;return typeof b==="string"?a[b]:a}}},removeData:function(a,b){if(c.acceptData(a)){a=a==E?ra:a;var d=a.nodeType,e=d?a[c.expando]:a,f=c.cache,h=d?f[e]:e;if(b){if(h){delete h[b];d&&c.isEmptyObject(h)&&c.removeData(a)}}else if(d&&c.support.deleteExpando)delete a[c.expando];else if(a.removeAttribute)a.removeAttribute(c.expando);
else if(d)delete f[e];else for(var l in a)delete a[l]}},acceptData:function(a){if(a.nodeName){var b=c.noData[a.nodeName.toLowerCase()];if(b)return!(b===true||a.getAttribute("classid")!==b)}return true}});c.fn.extend({data:function(a,b){var d=null;if(typeof a==="undefined"){if(this.length){var e=this[0].attributes,f;d=c.data(this[0]);for(var h=0,l=e.length;h<l;h++){f=e[h].name;if(f.indexOf("data-")===0){f=f.substr(5);ka(this[0],f,d[f])}}}return d}else if(typeof a==="object")return this.each(function(){c.data(this,
a)});var k=a.split(".");k[1]=k[1]?"."+k[1]:"";if(b===B){d=this.triggerHandler("getData"+k[1]+"!",[k[0]]);if(d===B&&this.length){d=c.data(this[0],a);d=ka(this[0],a,d)}return d===B&&k[1]?this.data(k[0]):d}else return this.each(function(){var o=c(this),x=[k[0],b];o.triggerHandler("setData"+k[1]+"!",x);c.data(this,a,b);o.triggerHandler("changeData"+k[1]+"!",x)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var e=
c.data(a,b);if(!d)return e||[];if(!e||c.isArray(d))e=c.data(a,b,c.makeArray(d));else e.push(d);return e}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),e=d.shift();if(e==="inprogress")e=d.shift();if(e){b==="fx"&&d.unshift("inprogress");e.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===B)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,
a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var sa=/[\n\t]/g,ha=/\s+/,Sa=/\r/g,Ta=/^(?:href|src|style)$/,Ua=/^(?:button|input)$/i,Va=/^(?:button|input|object|select|textarea)$/i,Wa=/^a(?:rea)?$/i,ta=/^(?:radio|checkbox)$/i;c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",
colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};c.fn.extend({attr:function(a,b){return c.access(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(x){var r=c(this);r.addClass(a.call(this,x,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===
1)if(f.className){for(var h=" "+f.className+" ",l=f.className,k=0,o=b.length;k<o;k++)if(h.indexOf(" "+b[k]+" ")<0)l+=" "+b[k];f.className=c.trim(l)}else f.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var x=c(this);x.removeClass(a.call(this,o,x.attr("class")))});if(a&&typeof a==="string"||a===B)for(var b=(a||"").split(ha),d=0,e=this.length;d<e;d++){var f=this[d];if(f.nodeType===1&&f.className)if(a){for(var h=(" "+f.className+" ").replace(sa," "),
l=0,k=b.length;l<k;l++)h=h.replace(" "+b[l]+" "," ");f.className=c.trim(h)}else f.className=""}return this},toggleClass:function(a,b){var d=typeof a,e=typeof b==="boolean";if(c.isFunction(a))return this.each(function(f){var h=c(this);h.toggleClass(a.call(this,f,h.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var f,h=0,l=c(this),k=b,o=a.split(ha);f=o[h++];){k=e?k:!l.hasClass(f);l[k?"addClass":"removeClass"](f)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,
"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(sa," ").indexOf(a)>-1)return true;return false},val:function(a){if(!arguments.length){var b=this[0];if(b){if(c.nodeName(b,"option")){var d=b.attributes.value;return!d||d.specified?b.value:b.text}if(c.nodeName(b,"select")){var e=b.selectedIndex;d=[];var f=b.options;b=b.type==="select-one";
if(e<0)return null;var h=b?e:0;for(e=b?e+1:f.length;h<e;h++){var l=f[h];if(l.selected&&(c.support.optDisabled?!l.disabled:l.getAttribute("disabled")===null)&&(!l.parentNode.disabled||!c.nodeName(l.parentNode,"optgroup"))){a=c(l).val();if(b)return a;d.push(a)}}return d}if(ta.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Sa,"")}return B}var k=c.isFunction(a);return this.each(function(o){var x=c(this),r=a;if(this.nodeType===1){if(k)r=
a.call(this,o,x.val());if(r==null)r="";else if(typeof r==="number")r+="";else if(c.isArray(r))r=c.map(r,function(C){return C==null?"":C+""});if(c.isArray(r)&&ta.test(this.type))this.checked=c.inArray(x.val(),r)>=0;else if(c.nodeName(this,"select")){var A=c.makeArray(r);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),A)>=0});if(!A.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},
attr:function(a,b,d,e){if(!a||a.nodeType===3||a.nodeType===8)return B;if(e&&b in c.attrFn)return c(a)[b](d);e=a.nodeType!==1||!c.isXMLDoc(a);var f=d!==B;b=e&&c.props[b]||b;var h=Ta.test(b);if((b in a||a[b]!==B)&&e&&!h){if(f){b==="type"&&Ua.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");if(d===null)a.nodeType===1&&a.removeAttribute(b);else a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&
b.specified?b.value:Va.test(a.nodeName)||Wa.test(a.nodeName)&&a.href?0:B;return a[b]}if(!c.support.style&&e&&b==="style"){if(f)a.style.cssText=""+d;return a.style.cssText}f&&a.setAttribute(b,""+d);if(!a.attributes[b]&&a.hasAttribute&&!a.hasAttribute(b))return B;a=!c.support.hrefNormalized&&e&&h?a.getAttribute(b,2):a.getAttribute(b);return a===null?B:a}});var X=/\.(.*)$/,ia=/^(?:textarea|input|select)$/i,La=/\./g,Ma=/ /g,Xa=/[^\w\s.|`]/g,Ya=function(a){return a.replace(Xa,"\\$&")},ua={focusin:0,focusout:0};
c.event={add:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(c.isWindow(a)&&a!==E&&!a.frameElement)a=E;if(d===false)d=U;else if(!d)return;var f,h;if(d.handler){f=d;d=f.handler}if(!d.guid)d.guid=c.guid++;if(h=c.data(a)){var l=a.nodeType?"events":"__events__",k=h[l],o=h.handle;if(typeof k==="function"){o=k.handle;k=k.events}else if(!k){a.nodeType||(h[l]=h=function(){});h.events=k={}}if(!o)h.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,
arguments):B};o.elem=a;b=b.split(" ");for(var x=0,r;l=b[x++];){h=f?c.extend({},f):{handler:d,data:e};if(l.indexOf(".")>-1){r=l.split(".");l=r.shift();h.namespace=r.slice(0).sort().join(".")}else{r=[];h.namespace=""}h.type=l;if(!h.guid)h.guid=d.guid;var A=k[l],C=c.event.special[l]||{};if(!A){A=k[l]=[];if(!C.setup||C.setup.call(a,e,r,o)===false)if(a.addEventListener)a.addEventListener(l,o,false);else a.attachEvent&&a.attachEvent("on"+l,o)}if(C.add){C.add.call(a,h);if(!h.handler.guid)h.handler.guid=
d.guid}A.push(h);c.event.global[l]=true}a=null}}},global:{},remove:function(a,b,d,e){if(!(a.nodeType===3||a.nodeType===8)){if(d===false)d=U;var f,h,l=0,k,o,x,r,A,C,J=a.nodeType?"events":"__events__",w=c.data(a),I=w&&w[J];if(w&&I){if(typeof I==="function"){w=I;I=I.events}if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(f in I)c.event.remove(a,f+b)}else{for(b=b.split(" ");f=b[l++];){r=f;k=f.indexOf(".")<0;o=[];if(!k){o=f.split(".");f=o.shift();x=RegExp("(^|\\.)"+
c.map(o.slice(0).sort(),Ya).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(A=I[f])if(d){r=c.event.special[f]||{};for(h=e||0;h<A.length;h++){C=A[h];if(d.guid===C.guid){if(k||x.test(C.namespace)){e==null&&A.splice(h--,1);r.remove&&r.remove.call(a,C)}if(e!=null)break}}if(A.length===0||e!=null&&A.length===1){if(!r.teardown||r.teardown.call(a,o)===false)c.removeEvent(a,f,w.handle);delete I[f]}}else for(h=0;h<A.length;h++){C=A[h];if(k||x.test(C.namespace)){c.event.remove(a,r,C.handler,h);A.splice(h--,1)}}}if(c.isEmptyObject(I)){if(b=
w.handle)b.elem=null;delete w.events;delete w.handle;if(typeof w==="function")c.removeData(a,J);else c.isEmptyObject(w)&&c.removeData(a)}}}}},trigger:function(a,b,d,e){var f=a.type||a;if(!e){a=typeof a==="object"?a[c.expando]?a:c.extend(c.Event(f),a):c.Event(f);if(f.indexOf("!")>=0){a.type=f=f.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[f]&&c.each(c.cache,function(){this.events&&this.events[f]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===
8)return B;a.result=B;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(e=d.nodeType?c.data(d,"handle"):(c.data(d,"__events__")||{}).handle)&&e.apply(d,b);e=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+f]&&d["on"+f].apply(d,b)===false){a.result=false;a.preventDefault()}}catch(h){}if(!a.isPropagationStopped()&&e)c.event.trigger(a,b,e,true);else if(!a.isDefaultPrevented()){var l;e=a.target;var k=f.replace(X,""),o=c.nodeName(e,"a")&&k===
"click",x=c.event.special[k]||{};if((!x._default||x._default.call(d,a)===false)&&!o&&!(e&&e.nodeName&&c.noData[e.nodeName.toLowerCase()])){try{if(e[k]){if(l=e["on"+k])e["on"+k]=null;c.event.triggered=true;e[k]()}}catch(r){}if(l)e["on"+k]=l;c.event.triggered=false}}},handle:function(a){var b,d,e,f;d=[];var h=c.makeArray(arguments);a=h[0]=c.event.fix(a||E.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;if(!b){e=a.type.split(".");a.type=e.shift();d=e.slice(0).sort();e=RegExp("(^|\\.)"+
d.join("\\.(?:.*\\.)?")+"(\\.|$)")}a.namespace=a.namespace||d.join(".");f=c.data(this,this.nodeType?"events":"__events__");if(typeof f==="function")f=f.events;d=(f||{})[a.type];if(f&&d){d=d.slice(0);f=0;for(var l=d.length;f<l;f++){var k=d[f];if(b||e.test(k.namespace)){a.handler=k.handler;a.data=k.data;a.handleObj=k;k=k.handler.apply(this,h);if(k!==B){a.result=k;if(k===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[c.expando])return a;var b=a;a=c.Event(b);for(var d=this.props.length,e;d;){e=this.props[--d];a[e]=b[e]}if(!a.target)a.target=a.srcElement||t;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=t.documentElement;d=t.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(a.which==null&&(a.charCode!=null||a.keyCode!=null))a.which=a.charCode!=null?a.charCode:a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==B)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,Y(a.origType,a.selector),c.extend({},a,{handler:Ka,guid:a.handler.guid}))},remove:function(a){c.event.remove(this,
Y(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,d){if(c.isWindow(this))this.onbeforeunload=d},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.removeEvent=t.removeEventListener?function(a,b,d){a.removeEventListener&&a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent&&a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=
c.now();this[c.expando]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ca;var a=this.originalEvent;if(a)if(a.preventDefault)a.preventDefault();else a.returnValue=false},stopPropagation:function(){this.isPropagationStopped=ca;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ca;this.stopPropagation()},isDefaultPrevented:U,isPropagationStopped:U,isImmediatePropagationStopped:U};
var va=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},wa=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?wa:va,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?wa:va)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(){if(this.nodeName.toLowerCase()!==
"form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length){a.liveFired=B;return la("submit",this,arguments)}});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13){a.liveFired=B;return la("submit",this,arguments)}})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};if(!c.support.changeBubbles){var V,
xa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(e){return e.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},Z=function(a,b){var d=a.target,e,f;if(!(!ia.test(d.nodeName)||d.readOnly)){e=c.data(d,"_change_data");f=xa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",f);if(!(e===B||f===e))if(e!=null||f){a.type="change";a.liveFired=
B;return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:Z,beforedeactivate:Z,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return Z.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return Z.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,"_change_data",xa(a))}},setup:function(){if(this.type===
"file")return false;for(var a in V)c.event.add(this,a+".specialChange",V[a]);return ia.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return ia.test(this.nodeName)}};V=c.event.special.change.filters;V.focus=V.beforeactivate}t.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(e){e=c.event.fix(e);e.type=b;return c.event.trigger(e,null,e.target)}c.event.special[b]={setup:function(){ua[b]++===0&&t.addEventListener(a,d,true)},teardown:function(){--ua[b]===
0&&t.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,e,f){if(typeof d==="object"){for(var h in d)this[b](h,e,d[h],f);return this}if(c.isFunction(e)||e===false){f=e;e=B}var l=b==="one"?c.proxy(f,function(o){c(this).unbind(o,l);return f.apply(this,arguments)}):f;if(d==="unload"&&b!=="one")this.one(d,e,f);else{h=0;for(var k=this.length;h<k;h++)c.event.add(this[h],d,l,e)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault)for(var d in a)this.unbind(d,
a[d]);else{d=0;for(var e=this.length;d<e;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,e){return this.live(b,d,e,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){var d=c.Event(a);d.preventDefault();d.stopPropagation();c.event.trigger(d,b,this[0]);return d.result}},toggle:function(a){for(var b=arguments,d=
1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(e){var f=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,f+1);e.preventDefault();return b[f].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var ya={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,e,f,h){var l,k=0,o,x,r=h||this.selector;h=h?this:c(this.context);if(typeof d===
"object"&&!d.preventDefault){for(l in d)h[b](l,e,d[l],r);return this}if(c.isFunction(e)){f=e;e=B}for(d=(d||"").split(" ");(l=d[k++])!=null;){o=X.exec(l);x="";if(o){x=o[0];l=l.replace(X,"")}if(l==="hover")d.push("mouseenter"+x,"mouseleave"+x);else{o=l;if(l==="focus"||l==="blur"){d.push(ya[l]+x);l+=x}else l=(ya[l]||l)+x;if(b==="live"){x=0;for(var A=h.length;x<A;x++)c.event.add(h[x],"live."+Y(l,r),{data:e,selector:r,handler:f,origType:l,origHandler:f,preType:o})}else h.unbind("live."+Y(l,r),f)}}return this}});
c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d,e){if(e==null){e=d;d=null}return arguments.length>0?this.bind(b,d,e):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});E.attachEvent&&!E.addEventListener&&c(E).bind("unload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
(function(){function a(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1&&!q){y.sizcache=n;y.sizset=p}if(y.nodeName.toLowerCase()===i){F=y;break}y=y[g]}m[p]=F}}}function b(g,i,n,m,p,q){p=0;for(var u=m.length;p<u;p++){var y=m[p];if(y){var F=false;for(y=y[g];y;){if(y.sizcache===n){F=m[y.sizset];break}if(y.nodeType===1){if(!q){y.sizcache=n;y.sizset=p}if(typeof i!=="string"){if(y===i){F=true;break}}else if(k.filter(i,
[y]).length>0){F=y;break}}y=y[g]}m[p]=F}}}var d=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,f=Object.prototype.toString,h=false,l=true;[0,0].sort(function(){l=false;return 0});var k=function(g,i,n,m){n=n||[];var p=i=i||t;if(i.nodeType!==1&&i.nodeType!==9)return[];if(!g||typeof g!=="string")return n;var q,u,y,F,M,N=true,O=k.isXML(i),D=[],R=g;do{d.exec("");if(q=d.exec(R)){R=q[3];D.push(q[1]);if(q[2]){F=q[3];
break}}}while(q);if(D.length>1&&x.exec(g))if(D.length===2&&o.relative[D[0]])u=L(D[0]+D[1],i);else for(u=o.relative[D[0]]?[i]:k(D.shift(),i);D.length;){g=D.shift();if(o.relative[g])g+=D.shift();u=L(g,u)}else{if(!m&&D.length>1&&i.nodeType===9&&!O&&o.match.ID.test(D[0])&&!o.match.ID.test(D[D.length-1])){q=k.find(D.shift(),i,O);i=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]}if(i){q=m?{expr:D.pop(),set:C(m)}:k.find(D.pop(),D.length===1&&(D[0]==="~"||D[0]==="+")&&i.parentNode?i.parentNode:i,O);u=q.expr?k.filter(q.expr,
q.set):q.set;if(D.length>0)y=C(u);else N=false;for(;D.length;){q=M=D.pop();if(o.relative[M])q=D.pop();else M="";if(q==null)q=i;o.relative[M](y,q,O)}}else y=[]}y||(y=u);y||k.error(M||g);if(f.call(y)==="[object Array]")if(N)if(i&&i.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&k.contains(i,y[g])))n.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&n.push(u[g]);else n.push.apply(n,y);else C(y,n);if(F){k(F,p,n,m);k.uniqueSort(n)}return n};k.uniqueSort=function(g){if(w){h=
l;g.sort(w);if(h)for(var i=1;i<g.length;i++)g[i]===g[i-1]&&g.splice(i--,1)}return g};k.matches=function(g,i){return k(g,null,null,i)};k.matchesSelector=function(g,i){return k(i,null,null,[g]).length>0};k.find=function(g,i,n){var m;if(!g)return[];for(var p=0,q=o.order.length;p<q;p++){var u,y=o.order[p];if(u=o.leftMatch[y].exec(g)){var F=u[1];u.splice(1,1);if(F.substr(F.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");m=o.find[y](u,i,n);if(m!=null){g=g.replace(o.match[y],"");break}}}}m||(m=i.getElementsByTagName("*"));
return{set:m,expr:g}};k.filter=function(g,i,n,m){for(var p,q,u=g,y=[],F=i,M=i&&i[0]&&k.isXML(i[0]);g&&i.length;){for(var N in o.filter)if((p=o.leftMatch[N].exec(g))!=null&&p[2]){var O,D,R=o.filter[N];D=p[1];q=false;p.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(F===y)y=[];if(o.preFilter[N])if(p=o.preFilter[N](p,F,n,y,m,M)){if(p===true)continue}else q=O=true;if(p)for(var j=0;(D=F[j])!=null;j++)if(D){O=R(D,p,j,F);var s=m^!!O;if(n&&O!=null)if(s)q=true;else F[j]=false;else if(s){y.push(D);q=true}}if(O!==
B){n||(F=y);g=g.replace(o.match[N],"");if(!q)return[];break}}}if(g===u)if(q==null)k.error(g);else break;u=g}return F};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var o=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,i){var n=typeof i==="string",m=n&&!/\W/.test(i);n=n&&!m;if(m)i=i.toLowerCase();m=0;for(var p=g.length,q;m<p;m++)if(q=g[m]){for(;(q=q.previousSibling)&&q.nodeType!==1;);g[m]=n||q&&q.nodeName.toLowerCase()===
i?q||false:q===i}n&&k.filter(i,g,true)},">":function(g,i){var n,m=typeof i==="string",p=0,q=g.length;if(m&&!/\W/.test(i))for(i=i.toLowerCase();p<q;p++){if(n=g[p]){n=n.parentNode;g[p]=n.nodeName.toLowerCase()===i?n:false}}else{for(;p<q;p++)if(n=g[p])g[p]=m?n.parentNode:n.parentNode===i;m&&k.filter(i,g,true)}},"":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=i=i.toLowerCase();q=a}q("parentNode",i,p,g,m,n)},"~":function(g,i,n){var m,p=e++,q=b;if(typeof i==="string"&&!/\W/.test(i)){m=
i=i.toLowerCase();q=a}q("previousSibling",i,p,g,m,n)}},find:{ID:function(g,i,n){if(typeof i.getElementById!=="undefined"&&!n)return(g=i.getElementById(g[1]))&&g.parentNode?[g]:[]},NAME:function(g,i){if(typeof i.getElementsByName!=="undefined"){for(var n=[],m=i.getElementsByName(g[1]),p=0,q=m.length;p<q;p++)m[p].getAttribute("name")===g[1]&&n.push(m[p]);return n.length===0?null:n}},TAG:function(g,i){return i.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,i,n,m,p,q){g=" "+g[1].replace(/\\/g,
"")+" ";if(q)return g;q=0;for(var u;(u=i[q])!=null;q++)if(u)if(p^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))n||m.push(u);else if(n)i[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var i=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=i[1]+(i[2]||1)-0;g[3]=i[3]-0}g[0]=e++;return g},ATTR:function(g,i,n,
m,p,q){i=g[1].replace(/\\/g,"");if(!q&&o.attrMap[i])g[1]=o.attrMap[i];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,i,n,m,p){if(g[1]==="not")if((d.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,i);else{g=k.filter(g[3],i,n,true^p);n||m.push.apply(m,g);return false}else if(o.match.POS.test(g[0])||o.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===
true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,i,n){return!!k(n[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===
g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,i){return i===0},last:function(g,i,n,m){return i===m.length-1},even:function(g,i){return i%2===0},odd:function(g,i){return i%2===1},lt:function(g,i,n){return i<n[3]-0},gt:function(g,i,n){return i>n[3]-0},nth:function(g,i,n){return n[3]-
0===i},eq:function(g,i,n){return n[3]-0===i}},filter:{PSEUDO:function(g,i,n,m){var p=i[1],q=o.filters[p];if(q)return q(g,n,i,m);else if(p==="contains")return(g.textContent||g.innerText||k.getText([g])||"").indexOf(i[3])>=0;else if(p==="not"){i=i[3];n=0;for(m=i.length;n<m;n++)if(i[n]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+p)},CHILD:function(g,i){var n=i[1],m=g;switch(n){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(n===
"first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":n=i[2];var p=i[3];if(n===1&&p===0)return true;var q=i[0],u=g.parentNode;if(u&&(u.sizcache!==q||!g.nodeIndex)){var y=0;for(m=u.firstChild;m;m=m.nextSibling)if(m.nodeType===1)m.nodeIndex=++y;u.sizcache=q}m=g.nodeIndex-p;return n===0?m===0:m%n===0&&m/n>=0}},ID:function(g,i){return g.nodeType===1&&g.getAttribute("id")===i},TAG:function(g,i){return i==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===
i},CLASS:function(g,i){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(i)>-1},ATTR:function(g,i){var n=i[1];n=o.attrHandle[n]?o.attrHandle[n](g):g[n]!=null?g[n]:g.getAttribute(n);var m=n+"",p=i[2],q=i[4];return n==null?p==="!=":p==="="?m===q:p==="*="?m.indexOf(q)>=0:p==="~="?(" "+m+" ").indexOf(q)>=0:!q?m&&n!==false:p==="!="?m!==q:p==="^="?m.indexOf(q)===0:p==="$="?m.substr(m.length-q.length)===q:p==="|="?m===q||m.substr(0,q.length+1)===q+"-":false},POS:function(g,i,n,m){var p=o.setFilters[i[2]];
if(p)return p(g,n,i,m)}}},x=o.match.POS,r=function(g,i){return"\\"+(i-0+1)},A;for(A in o.match){o.match[A]=RegExp(o.match[A].source+/(?![^\[]*\])(?![^\(]*\))/.source);o.leftMatch[A]=RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[A].source.replace(/\\(\d+)/g,r))}var C=function(g,i){g=Array.prototype.slice.call(g,0);if(i){i.push.apply(i,g);return i}return g};try{Array.prototype.slice.call(t.documentElement.childNodes,0)}catch(J){C=function(g,i){var n=0,m=i||[];if(f.call(g)==="[object Array]")Array.prototype.push.apply(m,
g);else if(typeof g.length==="number")for(var p=g.length;n<p;n++)m.push(g[n]);else for(;g[n];n++)m.push(g[n]);return m}}var w,I;if(t.documentElement.compareDocumentPosition)w=function(g,i){if(g===i){h=true;return 0}if(!g.compareDocumentPosition||!i.compareDocumentPosition)return g.compareDocumentPosition?-1:1;return g.compareDocumentPosition(i)&4?-1:1};else{w=function(g,i){var n,m,p=[],q=[];n=g.parentNode;m=i.parentNode;var u=n;if(g===i){h=true;return 0}else if(n===m)return I(g,i);else if(n){if(!m)return 1}else return-1;
for(;u;){p.unshift(u);u=u.parentNode}for(u=m;u;){q.unshift(u);u=u.parentNode}n=p.length;m=q.length;for(u=0;u<n&&u<m;u++)if(p[u]!==q[u])return I(p[u],q[u]);return u===n?I(g,q[u],-1):I(p[u],i,1)};I=function(g,i,n){if(g===i)return n;for(g=g.nextSibling;g;){if(g===i)return-1;g=g.nextSibling}return 1}}k.getText=function(g){for(var i="",n,m=0;g[m];m++){n=g[m];if(n.nodeType===3||n.nodeType===4)i+=n.nodeValue;else if(n.nodeType!==8)i+=k.getText(n.childNodes)}return i};(function(){var g=t.createElement("div"),
i="script"+(new Date).getTime(),n=t.documentElement;g.innerHTML="<a name='"+i+"'/>";n.insertBefore(g,n.firstChild);if(t.getElementById(i)){o.find.ID=function(m,p,q){if(typeof p.getElementById!=="undefined"&&!q)return(p=p.getElementById(m[1]))?p.id===m[1]||typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id").nodeValue===m[1]?[p]:B:[]};o.filter.ID=function(m,p){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===p}}n.removeChild(g);
n=g=null})();(function(){var g=t.createElement("div");g.appendChild(t.createComment(""));if(g.getElementsByTagName("*").length>0)o.find.TAG=function(i,n){var m=n.getElementsByTagName(i[1]);if(i[1]==="*"){for(var p=[],q=0;m[q];q++)m[q].nodeType===1&&p.push(m[q]);m=p}return m};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")o.attrHandle.href=function(i){return i.getAttribute("href",2)};g=null})();t.querySelectorAll&&
function(){var g=k,i=t.createElement("div");i.innerHTML="<p class='TEST'></p>";if(!(i.querySelectorAll&&i.querySelectorAll(".TEST").length===0)){k=function(m,p,q,u){p=p||t;m=m.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!u&&!k.isXML(p))if(p.nodeType===9)try{return C(p.querySelectorAll(m),q)}catch(y){}else if(p.nodeType===1&&p.nodeName.toLowerCase()!=="object"){var F=p.getAttribute("id"),M=F||"__sizzle__";F||p.setAttribute("id",M);try{return C(p.querySelectorAll("#"+M+" "+m),q)}catch(N){}finally{F||
p.removeAttribute("id")}}return g(m,p,q,u)};for(var n in g)k[n]=g[n];i=null}}();(function(){var g=t.documentElement,i=g.matchesSelector||g.mozMatchesSelector||g.webkitMatchesSelector||g.msMatchesSelector,n=false;try{i.call(t.documentElement,"[test!='']:sizzle")}catch(m){n=true}if(i)k.matchesSelector=function(p,q){q=q.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(p))try{if(n||!o.match.PSEUDO.test(q)&&!/!=/.test(q))return i.call(p,q)}catch(u){}return k(q,null,null,[p]).length>0}})();(function(){var g=
t.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){o.order.splice(1,0,"CLASS");o.find.CLASS=function(i,n,m){if(typeof n.getElementsByClassName!=="undefined"&&!m)return n.getElementsByClassName(i[1])};g=null}}})();k.contains=t.documentElement.contains?function(g,i){return g!==i&&(g.contains?g.contains(i):true)}:t.documentElement.compareDocumentPosition?
function(g,i){return!!(g.compareDocumentPosition(i)&16)}:function(){return false};k.isXML=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false};var L=function(g,i){for(var n,m=[],p="",q=i.nodeType?[i]:i;n=o.match.PSEUDO.exec(g);){p+=n[0];g=g.replace(o.match.PSEUDO,"")}g=o.relative[g]?g+"*":g;n=0;for(var u=q.length;n<u;n++)k(g,q[n],m);return k.filter(p,m)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=k.getText;c.isXMLDoc=k.isXML;
c.contains=k.contains})();var Za=/Until$/,$a=/^(?:parents|prevUntil|prevAll)/,ab=/,/,Na=/^.[^:#\[\.,]*$/,bb=Array.prototype.slice,cb=c.expr.match.POS;c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,e=0,f=this.length;e<f;e++){d=b.length;c.find(a,this[e],b);if(e>0)for(var h=d;h<b.length;h++)for(var l=0;l<d;l++)if(b[l]===b[h]){b.splice(h--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,e=b.length;d<e;d++)if(c.contains(this,b[d]))return true})},
not:function(a){return this.pushStack(ma(this,a,false),"not",a)},filter:function(a){return this.pushStack(ma(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){var d=[],e,f,h=this[0];if(c.isArray(a)){var l,k={},o=1;if(h&&a.length){e=0;for(f=a.length;e<f;e++){l=a[e];k[l]||(k[l]=c.expr.match.POS.test(l)?c(l,b||this.context):l)}for(;h&&h.ownerDocument&&h!==b;){for(l in k){e=k[l];if(e.jquery?e.index(h)>-1:c(h).is(e))d.push({selector:l,elem:h,level:o})}h=
h.parentNode;o++}}return d}l=cb.test(a)?c(a,b||this.context):null;e=0;for(f=this.length;e<f;e++)for(h=this[e];h;)if(l?l.index(h)>-1:c.find.matchesSelector(h,a)){d.push(h);break}else{h=h.parentNode;if(!h||!h.ownerDocument||h===b)break}d=d.length>1?c.unique(d):d;return this.pushStack(d,"closest",a)},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var d=typeof a==="string"?c(a,b||this.context):
c.makeArray(a),e=c.merge(this.get(),d);return this.pushStack(!d[0]||!d[0].parentNode||d[0].parentNode.nodeType===11||!e[0]||!e[0].parentNode||e[0].parentNode.nodeType===11?e:c.unique(e))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,
2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,
b){c.fn[a]=function(d,e){var f=c.map(this,b,d);Za.test(a)||(e=d);if(e&&typeof e==="string")f=c.filter(e,f);f=this.length>1?c.unique(f):f;if((this.length>1||ab.test(e))&&$a.test(a))f=f.reverse();return this.pushStack(f,a,bb.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return b.length===1?c.find.matchesSelector(b[0],a)?[b[0]]:[]:c.find.matches(a,b)},dir:function(a,b,d){var e=[];for(a=a[b];a&&a.nodeType!==9&&(d===B||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&
e.push(a);a=a[b]}return e},nth:function(a,b,d){b=b||1;for(var e=0;a;a=a[d])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var za=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,Aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Ba=/<([\w:]+)/,db=/<tbody/i,eb=/<|&#?\w+;/,Ca=/<(?:script|object|embed|option|style)/i,Da=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/\=([^="'>\s]+\/)>/g,P={option:[1,
"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};P.optgroup=P.option;P.tbody=P.tfoot=P.colgroup=P.caption=P.thead;P.th=P.td;if(!c.support.htmlSerialize)P._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==B)return this.empty().append((this[0]&&this[0].ownerDocument||t).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,e;(e=this[d])!=null;d++)if(!a||c.filter(a,[e]).length){if(!b&&e.nodeType===1){c.cleanData(e.getElementsByTagName("*"));c.cleanData([e])}e.parentNode&&e.parentNode.removeChild(e)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,e=this.ownerDocument;if(!d){d=e.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(za,"").replace(fb,'="$1">').replace($,"")],e)[0]}else return this.cloneNode(true)});if(a===true){na(this,b);na(this.find("*"),b.find("*"))}return b},html:function(a){if(a===B)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(za,""):null;
else if(typeof a==="string"&&!Ca.test(a)&&(c.support.leadingWhitespace||!$.test(a))&&!P[(Ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Aa,"<$1></$2>");try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(e){this.empty().append(a)}}else c.isFunction(a)?this.each(function(f){var h=c(this);h.html(a.call(this,f,h.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=
c(this),e=d.html();d.replaceWith(a.call(this,b,e))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){var e,f,h,l=a[0],k=[];if(!c.support.checkClone&&arguments.length===3&&typeof l==="string"&&Da.test(l))return this.each(function(){c(this).domManip(a,
b,d,true)});if(c.isFunction(l))return this.each(function(x){var r=c(this);a[0]=l.call(this,x,b?r.html():B);r.domManip(a,b,d)});if(this[0]){e=l&&l.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:c.buildFragment(a,this,k);h=e.fragment;if(f=h.childNodes.length===1?h=h.firstChild:h.firstChild){b=b&&c.nodeName(f,"tr");f=0;for(var o=this.length;f<o;f++)d.call(b?c.nodeName(this[f],"table")?this[f].getElementsByTagName("tbody")[0]||this[f].appendChild(this[f].ownerDocument.createElement("tbody")):
this[f]:this[f],f>0||e.cacheable||this.length>1?h.cloneNode(true):h)}k.length&&c.each(k,Oa)}return this}});c.buildFragment=function(a,b,d){var e,f,h;b=b&&b[0]?b[0].ownerDocument||b[0]:t;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===t&&!Ca.test(a[0])&&(c.support.checkClone||!Da.test(a[0]))){f=true;if(h=c.fragments[a[0]])if(h!==1)e=h}if(!e){e=b.createDocumentFragment();c.clean(a,b,e,d)}if(f)c.fragments[a[0]]=h?e:1;return{fragment:e,cacheable:f}};c.fragments={};c.each({appendTo:"append",
prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var e=[];d=c(d);var f=this.length===1&&this[0].parentNode;if(f&&f.nodeType===11&&f.childNodes.length===1&&d.length===1){d[b](this[0]);return this}else{f=0;for(var h=d.length;f<h;f++){var l=(f>0?this.clone(true):this).get();c(d[f])[b](l);e=e.concat(l)}return this.pushStack(e,a,d.selector)}}});c.extend({clean:function(a,b,d,e){b=b||t;if(typeof b.createElement==="undefined")b=b.ownerDocument||
b[0]&&b[0].ownerDocument||t;for(var f=[],h=0,l;(l=a[h])!=null;h++){if(typeof l==="number")l+="";if(l){if(typeof l==="string"&&!eb.test(l))l=b.createTextNode(l);else if(typeof l==="string"){l=l.replace(Aa,"<$1></$2>");var k=(Ba.exec(l)||["",""])[1].toLowerCase(),o=P[k]||P._default,x=o[0],r=b.createElement("div");for(r.innerHTML=o[1]+l+o[2];x--;)r=r.lastChild;if(!c.support.tbody){x=db.test(l);k=k==="table"&&!x?r.firstChild&&r.firstChild.childNodes:o[1]==="<table>"&&!x?r.childNodes:[];for(o=k.length-
1;o>=0;--o)c.nodeName(k[o],"tbody")&&!k[o].childNodes.length&&k[o].parentNode.removeChild(k[o])}!c.support.leadingWhitespace&&$.test(l)&&r.insertBefore(b.createTextNode($.exec(l)[0]),r.firstChild);l=r.childNodes}if(l.nodeType)f.push(l);else f=c.merge(f,l)}}if(d)for(h=0;f[h];h++)if(e&&c.nodeName(f[h],"script")&&(!f[h].type||f[h].type.toLowerCase()==="text/javascript"))e.push(f[h].parentNode?f[h].parentNode.removeChild(f[h]):f[h]);else{f[h].nodeType===1&&f.splice.apply(f,[h+1,0].concat(c.makeArray(f[h].getElementsByTagName("script"))));
d.appendChild(f[h])}return f},cleanData:function(a){for(var b,d,e=c.cache,f=c.event.special,h=c.support.deleteExpando,l=0,k;(k=a[l])!=null;l++)if(!(k.nodeName&&c.noData[k.nodeName.toLowerCase()]))if(d=k[c.expando]){if((b=e[d])&&b.events)for(var o in b.events)f[o]?c.event.remove(k,o):c.removeEvent(k,o,b.handle);if(h)delete k[c.expando];else k.removeAttribute&&k.removeAttribute(c.expando);delete e[d]}}});var Ea=/alpha\([^)]*\)/i,gb=/opacity=([^)]*)/,hb=/-([a-z])/ig,ib=/([A-Z])/g,Fa=/^-?\d+(?:px)?$/i,
jb=/^-?\d/,kb={position:"absolute",visibility:"hidden",display:"block"},Pa=["Left","Right"],Qa=["Top","Bottom"],W,Ga,aa,lb=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){if(arguments.length===2&&b===B)return this;return c.access(this,a,b,true,function(d,e,f){return f!==B?c.style(d,e,f):c.css(d,e)})};c.extend({cssHooks:{opacity:{get:function(a,b){if(b){var d=W(a,"opacity","opacity");return d===""?"1":d}else return a.style.opacity}}},cssNumber:{zIndex:true,fontWeight:true,opacity:true,
zoom:true,lineHeight:true},cssProps:{"float":c.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,d,e){if(!(!a||a.nodeType===3||a.nodeType===8||!a.style)){var f,h=c.camelCase(b),l=a.style,k=c.cssHooks[h];b=c.cssProps[h]||h;if(d!==B){if(!(typeof d==="number"&&isNaN(d)||d==null)){if(typeof d==="number"&&!c.cssNumber[h])d+="px";if(!k||!("set"in k)||(d=k.set(a,d))!==B)try{l[b]=d}catch(o){}}}else{if(k&&"get"in k&&(f=k.get(a,false,e))!==B)return f;return l[b]}}},css:function(a,b,d){var e,f=c.camelCase(b),
h=c.cssHooks[f];b=c.cssProps[f]||f;if(h&&"get"in h&&(e=h.get(a,true,d))!==B)return e;else if(W)return W(a,b,f)},swap:function(a,b,d){var e={},f;for(f in b){e[f]=a.style[f];a.style[f]=b[f]}d.call(a);for(f in b)a.style[f]=e[f]},camelCase:function(a){return a.replace(hb,lb)}});c.curCSS=c.css;c.each(["height","width"],function(a,b){c.cssHooks[b]={get:function(d,e,f){var h;if(e){if(d.offsetWidth!==0)h=oa(d,b,f);else c.swap(d,kb,function(){h=oa(d,b,f)});if(h<=0){h=W(d,b,b);if(h==="0px"&&aa)h=aa(d,b,b);
if(h!=null)return h===""||h==="auto"?"0px":h}if(h<0||h==null){h=d.style[b];return h===""||h==="auto"?"0px":h}return typeof h==="string"?h:h+"px"}},set:function(d,e){if(Fa.test(e)){e=parseFloat(e);if(e>=0)return e+"px"}else return e}}});if(!c.support.opacity)c.cssHooks.opacity={get:function(a,b){return gb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var d=a.style;d.zoom=1;var e=c.isNaN(b)?"":"alpha(opacity="+b*100+")",f=
d.filter||"";d.filter=Ea.test(f)?f.replace(Ea,e):d.filter+" "+e}};if(t.defaultView&&t.defaultView.getComputedStyle)Ga=function(a,b,d){var e;d=d.replace(ib,"-$1").toLowerCase();if(!(b=a.ownerDocument.defaultView))return B;if(b=b.getComputedStyle(a,null)){e=b.getPropertyValue(d);if(e===""&&!c.contains(a.ownerDocument.documentElement,a))e=c.style(a,d)}return e};if(t.documentElement.currentStyle)aa=function(a,b){var d,e,f=a.currentStyle&&a.currentStyle[b],h=a.style;if(!Fa.test(f)&&jb.test(f)){d=h.left;
e=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;h.left=b==="fontSize"?"1em":f||0;f=h.pixelLeft+"px";h.left=d;a.runtimeStyle.left=e}return f===""?"auto":f};W=Ga||aa;if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetHeight;return a.offsetWidth===0&&b===0||!c.support.reliableHiddenOffsets&&(a.style.display||c.css(a,"display"))==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var mb=c.now(),nb=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
ob=/^(?:select|textarea)/i,pb=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,qb=/^(?:GET|HEAD)$/,Ra=/\[\]$/,T=/\=\?(&|$)/,ja=/\?/,rb=/([?&])_=[^&]*/,sb=/^(\w+:)?\/\/([^\/?#]+)/,tb=/%20/g,ub=/#.*$/,Ha=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!=="string"&&Ha)return Ha.apply(this,arguments);else if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var f=a.slice(e,a.length);a=a.slice(0,e)}e="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b===
"object"){b=c.param(b,c.ajaxSettings.traditional);e="POST"}var h=this;c.ajax({url:a,type:e,dataType:"html",data:b,complete:function(l,k){if(k==="success"||k==="notmodified")h.html(f?c("<div>").append(l.responseText.replace(nb,"")).find(f):l.responseText);d&&h.each(d,[l.responseText,k,l])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&
!this.disabled&&(this.checked||ob.test(this.nodeName)||pb.test(this.type))}).map(function(a,b){var d=c(this).val();return d==null?null:c.isArray(d)?c.map(d,function(e){return{name:b.name,value:e}}):{name:b.name,value:d}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:e})},
getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,e){if(c.isFunction(b)){e=e||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:e})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return new E.XMLHttpRequest},accepts:{xml:"application/xml, text/xml",html:"text/html",
script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},ajax:function(a){var b=c.extend(true,{},c.ajaxSettings,a),d,e,f,h=b.type.toUpperCase(),l=qb.test(h);b.url=b.url.replace(ub,"");b.context=a&&a.context!=null?a.context:b;if(b.data&&b.processData&&typeof b.data!=="string")b.data=c.param(b.data,b.traditional);if(b.dataType==="jsonp"){if(h==="GET")T.test(b.url)||(b.url+=(ja.test(b.url)?"&":"?")+(b.jsonp||"callback")+"=?");else if(!b.data||
!T.test(b.data))b.data=(b.data?b.data+"&":"")+(b.jsonp||"callback")+"=?";b.dataType="json"}if(b.dataType==="json"&&(b.data&&T.test(b.data)||T.test(b.url))){d=b.jsonpCallback||"jsonp"+mb++;if(b.data)b.data=(b.data+"").replace(T,"="+d+"$1");b.url=b.url.replace(T,"="+d+"$1");b.dataType="script";var k=E[d];E[d]=function(m){if(c.isFunction(k))k(m);else{E[d]=B;try{delete E[d]}catch(p){}}f=m;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);r&&r.removeChild(A)}}if(b.dataType==="script"&&b.cache===null)b.cache=
false;if(b.cache===false&&l){var o=c.now(),x=b.url.replace(rb,"$1_="+o);b.url=x+(x===b.url?(ja.test(b.url)?"&":"?")+"_="+o:"")}if(b.data&&l)b.url+=(ja.test(b.url)?"&":"?")+b.data;b.global&&c.active++===0&&c.event.trigger("ajaxStart");o=(o=sb.exec(b.url))&&(o[1]&&o[1].toLowerCase()!==location.protocol||o[2].toLowerCase()!==location.host);if(b.dataType==="script"&&h==="GET"&&o){var r=t.getElementsByTagName("head")[0]||t.documentElement,A=t.createElement("script");if(b.scriptCharset)A.charset=b.scriptCharset;
A.src=b.url;if(!d){var C=false;A.onload=A.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;c.handleSuccess(b,w,e,f);c.handleComplete(b,w,e,f);A.onload=A.onreadystatechange=null;r&&A.parentNode&&r.removeChild(A)}}}r.insertBefore(A,r.firstChild);return B}var J=false,w=b.xhr();if(w){b.username?w.open(h,b.url,b.async,b.username,b.password):w.open(h,b.url,b.async);try{if(b.data!=null&&!l||a&&a.contentType)w.setRequestHeader("Content-Type",
b.contentType);if(b.ifModified){c.lastModified[b.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[b.url]);c.etag[b.url]&&w.setRequestHeader("If-None-Match",c.etag[b.url])}o||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",b.dataType&&b.accepts[b.dataType]?b.accepts[b.dataType]+", */*; q=0.01":b.accepts._default)}catch(I){}if(b.beforeSend&&b.beforeSend.call(b.context,w,b)===false){b.global&&c.active--===1&&c.event.trigger("ajaxStop");w.abort();return false}b.global&&
c.triggerGlobal(b,"ajaxSend",[w,b]);var L=w.onreadystatechange=function(m){if(!w||w.readyState===0||m==="abort"){J||c.handleComplete(b,w,e,f);J=true;if(w)w.onreadystatechange=c.noop}else if(!J&&w&&(w.readyState===4||m==="timeout")){J=true;w.onreadystatechange=c.noop;e=m==="timeout"?"timeout":!c.httpSuccess(w)?"error":b.ifModified&&c.httpNotModified(w,b.url)?"notmodified":"success";var p;if(e==="success")try{f=c.httpData(w,b.dataType,b)}catch(q){e="parsererror";p=q}if(e==="success"||e==="notmodified")d||
c.handleSuccess(b,w,e,f);else c.handleError(b,w,e,p);d||c.handleComplete(b,w,e,f);m==="timeout"&&w.abort();if(b.async)w=null}};try{var g=w.abort;w.abort=function(){w&&Function.prototype.call.call(g,w);L("abort")}}catch(i){}b.async&&b.timeout>0&&setTimeout(function(){w&&!J&&L("timeout")},b.timeout);try{w.send(l||b.data==null?null:b.data)}catch(n){c.handleError(b,w,null,n);c.handleComplete(b,w,e,f)}b.async||L();return w}},param:function(a,b){var d=[],e=function(h,l){l=c.isFunction(l)?l():l;d[d.length]=
encodeURIComponent(h)+"="+encodeURIComponent(l)};if(b===B)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){e(this.name,this.value)});else for(var f in a)da(f,a[f],b,e);return d.join("&").replace(tb,"+")}});c.extend({active:0,lastModified:{},etag:{},handleError:function(a,b,d,e){a.error&&a.error.call(a.context,b,d,e);a.global&&c.triggerGlobal(a,"ajaxError",[b,a,e])},handleSuccess:function(a,b,d,e){a.success&&a.success.call(a.context,e,d,b);a.global&&c.triggerGlobal(a,"ajaxSuccess",
[b,a])},handleComplete:function(a,b,d){a.complete&&a.complete.call(a.context,b,d);a.global&&c.triggerGlobal(a,"ajaxComplete",[b,a]);a.global&&c.active--===1&&c.event.trigger("ajaxStop")},triggerGlobal:function(a,b,d){(a.context&&a.context.url==null?c(a.context):c.event).trigger(b,d)},httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),
e=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(e)c.etag[b]=e;return a.status===304},httpData:function(a,b,d){var e=a.getResponseHeader("content-type")||"",f=b==="xml"||!b&&e.indexOf("xml")>=0;a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&e.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&e.indexOf("javascript")>=0)c.globalEval(a);return a}});
if(E.ActiveXObject)c.ajaxSettings.xhr=function(){if(E.location.protocol!=="file:")try{return new E.XMLHttpRequest}catch(a){}try{return new E.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}};c.support.ajax=!!c.ajaxSettings.xhr();var ea={},vb=/^(?:toggle|show|hide)$/,wb=/^([+\-]=)?([\d+.\-]+)(.*)$/,ba,pa=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b,d){if(a||a===0)return this.animate(S("show",
3),a,b,d);else{d=0;for(var e=this.length;d<e;d++){a=this[d];b=a.style.display;if(!c.data(a,"olddisplay")&&b==="none")b=a.style.display="";b===""&&c.css(a,"display")==="none"&&c.data(a,"olddisplay",qa(a.nodeName))}for(d=0;d<e;d++){a=this[d];b=a.style.display;if(b===""||b==="none")a.style.display=c.data(a,"olddisplay")||""}return this}},hide:function(a,b,d){if(a||a===0)return this.animate(S("hide",3),a,b,d);else{a=0;for(b=this.length;a<b;a++){d=c.css(this[a],"display");d!=="none"&&c.data(this[a],"olddisplay",
d)}for(a=0;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b,d){var e=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||e?this.each(function(){var f=e?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(S("toggle",3),a,b,d);return this},fadeTo:function(a,b,d,e){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d,e)},animate:function(a,b,d,e){var f=c.speed(b,
d,e);if(c.isEmptyObject(a))return this.each(f.complete);return this[f.queue===false?"each":"queue"](function(){var h=c.extend({},f),l,k=this.nodeType===1,o=k&&c(this).is(":hidden"),x=this;for(l in a){var r=c.camelCase(l);if(l!==r){a[r]=a[l];delete a[l];l=r}if(a[l]==="hide"&&o||a[l]==="show"&&!o)return h.complete.call(this);if(k&&(l==="height"||l==="width")){h.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY];if(c.css(this,"display")==="inline"&&c.css(this,"float")==="none")if(c.support.inlineBlockNeedsLayout)if(qa(this.nodeName)===
"inline")this.style.display="inline-block";else{this.style.display="inline";this.style.zoom=1}else this.style.display="inline-block"}if(c.isArray(a[l])){(h.specialEasing=h.specialEasing||{})[l]=a[l][1];a[l]=a[l][0]}}if(h.overflow!=null)this.style.overflow="hidden";h.curAnim=c.extend({},a);c.each(a,function(A,C){var J=new c.fx(x,h,A);if(vb.test(C))J[C==="toggle"?o?"show":"hide":C](a);else{var w=wb.exec(C),I=J.cur()||0;if(w){var L=parseFloat(w[2]),g=w[3]||"px";if(g!=="px"){c.style(x,A,(L||1)+g);I=(L||
1)/J.cur()*I;c.style(x,A,I+g)}if(w[1])L=(w[1]==="-="?-1:1)*L+I;J.custom(I,L,g)}else J.custom(I,C,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var e=d.length-1;e>=0;e--)if(d[e].elem===this){b&&d[e](true);d.splice(e,1)}});b||this.dequeue();return this}});c.each({slideDown:S("show",1),slideUp:S("hide",1),slideToggle:S("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){c.fn[a]=function(d,e,f){return this.animate(b,
d,e,f)}});c.extend({speed:function(a,b,d){var e=a&&typeof a==="object"?c.extend({},a):{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};e.duration=c.fx.off?0:typeof e.duration==="number"?e.duration:e.duration in c.fx.speeds?c.fx.speeds[e.duration]:c.fx.speeds._default;e.old=e.complete;e.complete=function(){e.queue!==false&&c(this).dequeue();c.isFunction(e.old)&&e.old.call(this)};return e},easing:{linear:function(a,b,d,e){return d+e*a},swing:function(a,b,d,e){return(-Math.cos(a*
Math.PI)/2+0.5)*e+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a=parseFloat(c.css(this.elem,this.prop));return a&&a>-1E4?a:0},custom:function(a,b,d){function e(l){return f.step(l)}
var f=this,h=c.fx;this.startTime=c.now();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;e.elem=this.elem;if(e()&&c.timers.push(e)&&!ba)ba=setInterval(h.tick,h.interval)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;
this.custom(this.cur(),0)},step:function(a){var b=c.now(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var e in this.options.curAnim)if(this.options.curAnim[e]!==true)d=false;if(d){if(this.options.overflow!=null&&!c.support.shrinkWrapBlocks){var f=this.elem,h=this.options;c.each(["","X","Y"],function(k,o){f.style["overflow"+o]=h.overflow[k]})}this.options.hide&&c(this.elem).hide();if(this.options.hide||
this.options.show)for(var l in this.options.curAnim)c.style(this.elem,l,this.options.orig[l]);this.options.complete.call(this.elem)}return false}else{a=b-this.startTime;this.state=a/this.options.duration;b=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||b](this.state,a,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=
c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},interval:13,stop:function(){clearInterval(ba);ba=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===
b.elem}).length};var xb=/^t(?:able|d|h)$/i,Ia=/^(?:body|html)$/i;c.fn.offset="getBoundingClientRect"in t.documentElement?function(a){var b=this[0],d;if(a)return this.each(function(l){c.offset.setOffset(this,a,l)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);try{d=b.getBoundingClientRect()}catch(e){}var f=b.ownerDocument,h=f.documentElement;if(!d||!c.contains(h,b))return d||{top:0,left:0};b=f.body;f=fa(f);return{top:d.top+(f.pageYOffset||c.support.boxModel&&
h.scrollTop||b.scrollTop)-(h.clientTop||b.clientTop||0),left:d.left+(f.pageXOffset||c.support.boxModel&&h.scrollLeft||b.scrollLeft)-(h.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(x){c.offset.setOffset(this,a,x)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d,e=b.offsetParent,f=b.ownerDocument,h=f.documentElement,l=f.body;d=(f=f.defaultView)?f.getComputedStyle(b,null):b.currentStyle;
for(var k=b.offsetTop,o=b.offsetLeft;(b=b.parentNode)&&b!==l&&b!==h;){if(c.offset.supportsFixedPosition&&d.position==="fixed")break;d=f?f.getComputedStyle(b,null):b.currentStyle;k-=b.scrollTop;o-=b.scrollLeft;if(b===e){k+=b.offsetTop;o+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&xb.test(b.nodeName))){k+=parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}e=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"){k+=
parseFloat(d.borderTopWidth)||0;o+=parseFloat(d.borderLeftWidth)||0}d=d}if(d.position==="relative"||d.position==="static"){k+=l.offsetTop;o+=l.offsetLeft}if(c.offset.supportsFixedPosition&&d.position==="fixed"){k+=Math.max(h.scrollTop,l.scrollTop);o+=Math.max(h.scrollLeft,l.scrollLeft)}return{top:k,left:o}};c.offset={initialize:function(){var a=t.body,b=t.createElement("div"),d,e,f,h=parseFloat(c.css(a,"marginTop"))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",
height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);d=b.firstChild;e=d.firstChild;f=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=e.offsetTop!==5;this.doesAddBorderForTableAndCells=
f.offsetTop===5;e.style.position="fixed";e.style.top="20px";this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15;e.style.position=e.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==h;a.removeChild(b);c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.css(a,
"marginTop"))||0;d+=parseFloat(c.css(a,"marginLeft"))||0}return{top:b,left:d}},setOffset:function(a,b,d){var e=c.css(a,"position");if(e==="static")a.style.position="relative";var f=c(a),h=f.offset(),l=c.css(a,"top"),k=c.css(a,"left"),o=e==="absolute"&&c.inArray("auto",[l,k])>-1;e={};var x={};if(o)x=f.position();l=o?x.top:parseInt(l,10)||0;k=o?x.left:parseInt(k,10)||0;if(c.isFunction(b))b=b.call(a,d,h);if(b.top!=null)e.top=b.top-h.top+l;if(b.left!=null)e.left=b.left-h.left+k;"using"in b?b.using.call(a,
e):f.css(e)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),e=Ia.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.css(a,"marginTop"))||0;d.left-=parseFloat(c.css(a,"marginLeft"))||0;e.top+=parseFloat(c.css(b[0],"borderTopWidth"))||0;e.left+=parseFloat(c.css(b[0],"borderLeftWidth"))||0;return{top:d.top-e.top,left:d.left-e.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||t.body;a&&!Ia.test(a.nodeName)&&
c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(e){var f=this[0],h;if(!f)return null;if(e!==B)return this.each(function(){if(h=fa(this))h.scrollTo(!a?e:c(h).scrollLeft(),a?e:c(h).scrollTop());else this[d]=e});else return(h=fa(f))?"pageXOffset"in h?h[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&h.document.documentElement[d]||h.document.body[d]:f[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();
c.fn["inner"+b]=function(){return this[0]?parseFloat(c.css(this[0],d,"padding")):null};c.fn["outer"+b]=function(e){return this[0]?parseFloat(c.css(this[0],d,e?"margin":"border")):null};c.fn[d]=function(e){var f=this[0];if(!f)return e==null?null:this;if(c.isFunction(e))return this.each(function(l){var k=c(this);k[d](e.call(this,l,k[d]()))});if(c.isWindow(f))return f.document.compatMode==="CSS1Compat"&&f.document.documentElement["client"+b]||f.document.body["client"+b];else if(f.nodeType===9)return Math.max(f.documentElement["client"+
b],f.body["scroll"+b],f.documentElement["scroll"+b],f.body["offset"+b],f.documentElement["offset"+b]);else if(e===B){f=c.css(f,d);var h=parseFloat(f);return c.isNaN(h)?f:h}else return this.css(d,typeof e==="string"?e:e+"px")}})})(window);
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="434 218 68 68"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<g>
<path d="M 478.39694 232.53705 L 478.39694 232.53705
C 477.1145 231.85132 475.77875 231.30147 474.41058 230.88734 L 474.41058 218.24994 L 461.58942 218.24994
L 461.58942 230.88734 C 460.22125 231.30147 458.8855 231.85132 457.60306 232.53705 L 448.66824 223.60214
L 439.6022 232.66814 L 448.53717 241.60304 C 447.8515 242.8854 447.30157 244.22116 446.88745 245.58936
L 434.25 245.58936 L 434.25 258.41052 L 446.88745 258.41052
C 447.30157 259.77869 447.8515 261.11447 448.53717 262.39688 L 439.6022 271.33173 L 448.66824 280.3978
L 457.60306 271.46283 C 458.8855 272.14862 460.22125 272.69846 461.58942 273.11252 L 461.58942 285.74988
L 474.41058 285.74988 L 474.41058 273.11252 C 475.77875 272.69846 477.1145 272.14862 478.39694 271.46283
L 487.33176 280.3978 L 496.39767 271.33173 L 487.46286 262.39688
C 488.14853 261.11447 488.69836 259.77869 489.11255 258.41052 L 501.74988 258.41052 L 501.74988 245.58936
L 489.11255 245.58936 C 488.69836 244.22116 488.14853 242.8854 487.46286 241.60304 L 496.39767 232.66814
L 487.33176 223.60214 Z M 475.3328 244.66714 C 479.3825 248.71698 479.3825 255.2829 475.3328 259.33273
C 471.28296 263.3826 464.71704 263.3826 460.66724 259.33273
C 456.61737 255.2829 456.61737 248.71698 460.66724 244.66714
C 464.71704 240.61734 471.28296 240.61734 475.3328 244.66714" fill="#111"
class="glyph"/>
</g>
</g>
</svg>
[[Tiddlers|Tiddler]] can have attributes known as custom fields. A field can be anything that describes or extends the data in the tiddler. For instance fields describing geo data can be associated with a tiddler.
This tiddler has a custom field "color" which could potentially be used to set a background colour, a tiddler title or express a favourite colour.
You can view fields on a tiddler by clicking on the more button in your toolbar and selecting the fields option or via the [[TiddlySpace API]]. For example see [[the txt serialization for this tiddler|http://glossary.tiddlyspace.com/bags/glossary_public/tiddlers/custom fields.txt]].
By default it is not possible to edit custom fields with a basic TiddlySpace. You will need to include a space that exposes the editing of them (for instance the @first-class-fields space).
''As posted to the mailling list by John Scully''
As for Q #2, you can add the following to your StyleSheet tiddly:
.viewer td { vertical-align: bottom; }
Or
.viewer td { vertical-align: top; }
If all the cells are the same height (ie.e no wrap-around text), you
can also add the following to help show the effect:
.viewer td { vertical-align: top; height: 3em; }
Otherwise, there doesn't seem to be any other applicable tweaks,
related to vertical justification (e.g. adding a class to specific
table cells).
Serializations are explained in http://tiddlyweb.peermore.com/wiki/bags/docs/tiddlers/serialization
Read more about the [[TiddlySpace API]]
An OpenID allows you to use an existing account to sign in to multiple websites, without needing to create new passwords. In TiddlySpace you can associate your account with an OpenID
You probably have an openid already. Find out here: http://openid.net/get-an-openid/
Is it possible to have two kinds of tiddlers?
Quote:Eric
Try this:
[[TaggedTemplateTweak|http://www.TiddlyTools.com/#TaggedTemplateTweak]]
To use it, create an alternative template called ~WhateverViewTemplate that includes the desired customizations you want. Then, any tiddlers you tag with "whatever" (or "Whatever") will use the alternative template. The same mechanism can be used to create alternative edit templates (i.e., "~WhateverEditTemplate").
For your purposes, you could define ~InstructionsViewTemplate, and then tag all your text tiddlers with "instructions" to trigger the alternative tiddler display layout.
A [[tiddler|Tiddler]] is the name given to a unit of [[micro-content]] in [[TiddlyWiki]].
Tiddlers are primarily created and rendered in the content panes at the center of the TiddlyWiki page.
Tiddlers are pervasive in TiddlyWiki. The MainMenu is defined by a tiddler, plugins are delivered in tiddlers, there are special StyleSheet tiddlers, and so on.
Other systems have analogous concepts with more prosaic names (e.g. "items", "entries", "entities").
According to [[Jeremy Ruston]], even though "tiddler" is undoubtedly a silly name, it at least has the virtue of being confusingly distinctive rather than confusingly generic.
!! Structure
Each tiddler includes a basic set of [[fields|Tiddler Fields]]:
* ''Title'': unique title of the tiddler
* ''Modifier'': author/editor (corresponds to the current [[username]])
* ''Modified'': last-modified date/time (12-digit number with the [[format|Timestamps]] {{{YYYY0MM0DD0hh0mm}}})
* ''Created'': date/time the tiddler was created (12-digit number with the [[format|Timestamps]] {{{YYYY0MM0DD0hh0mm}}})
* ''Tags'': a set of space-separated keywords ([[tags]]), enclosed in square brackets ({{{[[...]]}}}) if the tag contains a space
* ''Tiddler Body'': contains textual content
The title field is a tiddler's unique identifier, so there cannot be two tiddlers with identical titles.
!! Shadow Tiddlers
Shadow tiddlers are "preloaded" with default contents.
See [[Shadow Tiddlers]].
!! Tiddler ~IDs
Every tiddler element has a unique identifier.
This ID is composed of the string "tiddler" and the tiddler's name (e.g. {{{tiddlerGettingStarted}}}).
Also see [[ticket #472|http://trac.tiddlywiki.org/ticket/472]].
!! See Also
* [[Shadow Tiddlers]]
* [[Tiddler Toolbar]]
* [[Tiddler-Specific Styles]]
[[Category:Basics]]
The addNotification method of a [[TiddlyWiki class|TiddlyWiki]] object ties an external function (called a callback here) to a tiddler. Whenever that tiddler is changed by the author, the callback function is invoked. TheTiddlyWiki code only passes the title of the changed tiddler to the callback function; it's up to the callback to dig up what it needs to act appropriately based on the change. This method takes two parameters:
* the title of the tiddler
* a reference to the callback function
It is possible to call this method with a null value for the first parameter. You must specify null, not an empty string. The callback function then is invoked for every tiddler, but only if either:
* notifications are running via the [[notifyAll|TiddlyWiki.prototype.notifyAll]] method
* the notify method is called with the second parameter set to true
<<closeAll>><<permaview>><<newTiddler>><<newTiddler label:"new doc note" fields:"theme:TWDocTheme">>
This function is the main entry point for wikification.
It chooses between [[Wikifier.prototype.subWikifyTerm()]] and [[Wikifier.prototype.subWikifyUnterm()]] depending upon whether a terminator was passed into the function or not.
It takes the following arguments:
* output: the object to output into
* terminator: a regexp that defines the end of the block, e.g. }}} being the end of a code block.
It does not return anything, but rather, renders HTML directly into the output object.
TiddlySpace is a platform for [[interlocution|http://en.wiktionary.org/wiki/interlocution]]; conversations characterised by reasoning. Hosting the conversation under the control of [[members|Member]] in their own [[spaces|Space]] encourages passing from premises to consequences whilst containing the whole history of an asynchronous dialogue, ripe for [[historiography|http://en.wikipedia.org/wiki/Historiography]].
To save on space, TiddlyWiki users often host images externally on sites like Flickr and ImageShack. A URL or HTML code for the image is then pasted into a tiddler (including MainMenu and SiteTitle to display images in the menu and header respectively).
Open the tiddler, position the cursor where the image is to go and paste in the link using the following formatting:
'''URL'''
<nowiki>
[img[URL of image]]
</nowiki>
'''URL with alternate text and link'''
<nowiki>
[img[alternate text|URL of image][tiddler or URL]]
</nowiki>
'''HTML'''
<nowiki>
<html>HTML code from hosting site</html>
</nowiki>
''Image Hosting''
There are various free image hosting services which can be used to store pictures:
* [[TinyPic|http://tinypic.com/index.php]]
* [[ImageShack|http://www.imageshack.us]]
* [[Flickr|http://www.flickr.com]]
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
!ImportTiddlers Method
see [[Importing Tiddlers]]
!Copy & Paste Method
;Locate the plugin you want to install
* It's a good idea to get it from the plugin author's site so you know you have the latest version
;Copy the source of the plugin tiddler
* To do this you need to click the tiddler's 'edit' button. Sometimes instead of an 'edit' button there is a 'view' or 'source' button instead, but either way it should show you the source of the plugin tiddler.
* Click in the text box and do an "Edit", "Select All" from your browser menu, or press Ctrl-A (Cmd-A for Mac users) to select the entire contents. Often the tiddlers contents is already selected for you so you may be able to skip this step.
* Do an "Edit", "Copy", or press Ctrl-C (Cmd-C for Mac users) to copy the entire contents of the tiddler.
;Create the plugin tiddler in your TiddlyWiki
* Back in your own TiddlyWiki, click 'new tiddler' to create a tiddler.
* You can name the tiddler anything you like but to save confusion give it the same as the plugin you are installing.
* Do an "Edit", "Paste", or Ctrl-V/Cmd-V to paste the plugin source code into your new plugin tiddler.
* (Note if you updating a plugin you already have you can just edit it, do a select all, delete to clear the contents before you paste in the new contents).
;Add the "systemConfig" tag
* Before you save the new plugin tiddler, add the tag "systemConfig" to the tags box. It must start with a lowercase 's'. This is what tells TiddlyWiki to execute the code in the plugin tiddler when starting.
;Save and reload
* The plugin is not active until you save and reload your TiddlyWiki so click 'save changes', then click reload in your browser.
;Testing
* Now your plugin should be active and working. Check that it is doing what it should be doing.
!Troubleshooting
cf. [[Troubleshooting]]
;If it's not working but you don't get an error
Check the following
* Did you remember the systemConfig tag? It must be spelt correctly and it is case sensitive.
* Did you save and reload?
;You get javascript error messages (check your Javascript Console in Firefox)
* It means that there are errors in the plugin code.
* Check that you copied the entire plugin source code and that you clicked edit (or view or source) before copying.
* It's possible that the plugin is buggy. If you email the plugin author or post to the TiddlyWiki Google Group you may get some help. Mention your browser your OS and the details of the problem you're having.
A Tiddler is the fundamental unit of content in a TiddlyWiki. Each TiddlySpace tiddler exists in a [[bag|Bag]] and may be accessed through the TiddlyWeb [[HTTP API]]. For example there is a copy of this tiddler available at http://glossary.tiddlyspace.com/Tiddler.txt
A Tiddler may contain human readable content, [[binary data|Binary Tiddler]], or JavaScript code that makes up a TiddlyWiki [[Plugin|plugin]].
Add stuff to your StyleSheet tiddler. Also take a look at http://tiddlythemes.com/
(to be expanded)..
{{{
!Heading Level 1
!!Heading Level 2
!!!Heading Level 3
!!!!Heading Level 4
!!!!!Heading Level 5
!!!!!!Heading Level 6
}}}
Display as:
!Heading Level 1
!!Heading Level 2
!!!Heading Level 3
!!!!Heading Level 4
!!!!!Heading Level 5
!!!!!!Heading Level 6
The clear method of a [[TiddlyWiki class|TiddlyWiki]] object removes all tiddlers from it and clears its dirty flag. It takes no parameters.
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
A ''getWeek'' method has been added to the Date object. Any date object can return it's week number (between 1 and 52).
The function can be use like this:
//{{{
var date = new Date(); // Mon Feb 07 2011 23:35:42 GMT+0100 (CET) {}
date.getWeek(); // 6
//}}}
The latest TiddlyWiki development build can be obtained from http://nightly.tiddlywiki.org.
Nightly builds may have bugs or be unstable and therefore should not to be relied on for regular use. They are intended for testing purposes only.
A SiteIcon is a graphic that identifies your space.
A SiteIcon should be an image file that is supported by a web browser.
A good site icon will be square and at least 48*48 pixels size.
For a site foo on http://tiddlyspace.com the SiteIcon lives at the following address:
http://foo.tiddlyspace.com/bags/foo_public/tiddlers/SiteIcon
First, set up a CSS rule to do the justification. Add something like
this to your StyleSheet tiddler (find it on tab More => Shadowed):
{{{
.justifyright {
text-align: right;
}
}}}
that gives you a css class of justifyright that you can use to make
stuff be right-aligned. Make sure you get the dot at the start of
".justifyright".
Now, edit some tiddler and put the stuff you want to justify inside
triple-curly-brackets, with the CSS class after the first two. You
will need to put the brackets on lines by themselves.
{{justifyright{
This paragraph will be right-aligned.
}}}
If you want full justification, add a CSS rule like this, and then use
"justifyfull" inside the triple curlies:
{{{
.justifyfull {
text-align: justify;
}
}}}
Note that '''this won't work''' if you use the triple curlies inline:
{{{
{{justifyright{ DOESN'T WORK: This is not right justified }}}
}}}
{{justifyright{ DOESN'T WORK: This is not right justified }}}
This is because triple curlies make spans if you use them inline
<nowiki>{{{like this}}}</nowiki>, but divs if you use them on lines by themselves.
/***
https://github.com/tiddlyweb/chrjs/raw/master/main.js
***/
//{{{
// TiddlyWeb adaptor
// v0.14.3
/*jslint vars: true, unparam: true, nomen: true, white: true */
/*global jQuery */
var tiddlyweb = (function($) {
"use strict";
var tw = {
routes: {
// host is the TiddlyWeb instance's URI (including server_prefix)
// placeholders "_type" & "name" refer to the respective bag/recipe
root : "{host}/",
bags : "{host}/bags",
bag : "{host}/bags/{name}",
recipes : "{host}/recipes",
recipe : "{host}/recipes/{name}",
tiddlers : "{host}/{_type}s/{name}/tiddlers",
tiddler : "{host}/{_type}s/{name}/tiddlers/{title}",
revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
search : "{host}/search?q={query}"
}
};
var convertTimestamp, supplant;
// host (optional) is the URI of the originating TiddlyWeb instance
tw.Resource = function(type, host) {
if(arguments.length) { // initialization
this._type = type;
if(host !== false) {
this.host = host !== undefined ? host.replace(/\/$/, "") : null;
}
}
};
$.extend(tw.Resource.prototype, {
// retrieves resource from server
// callback is passed resource, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
// filters is an optional filter string (e.g. "select=tag:foo;limit=5")
get: function(callback, errback, filters) {
var uri = this.route();
if(filters) {
var separator = uri.indexOf("?") === -1 ? "?" : ";";
uri += separator + filters;
}
var self = this;
return $.ajax({
url: uri,
type: "GET",
dataType: "json",
success: function(data, status, xhr) {
var resource = self.parse(data);
resource.etag = xhr.getResponseHeader("Etag");
callback(resource, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
});
},
// sends resource to server
// callback is passed data, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
put: function(callback, errback) {
var self = this;
var options = {
url: this.route(),
type: "PUT",
contentType: "application/json",
data: JSON.stringify(this.baseData()),
success: function(data, status, xhr) {
callback(self, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
};
if(this.ajaxSetup) {
this.ajaxSetup(options);
}
return $.ajax(options);
},
// deletes resource on server
// callback is passed data, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
"delete": function(callback, errback) {
var self = this;
var options = {
url: this.route(),
type: "DELETE",
success: function(data, status, xhr) {
callback(self, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
};
if(this.ajaxSetup) {
this.ajaxSetup(options);
}
return $.ajax(options);
},
// returns an object carrying only the essential information of the resource
baseData: function() {
var data = {},
self = this;
$.each(this.data, function(i, item) {
var value = self[item];
if(value !== undefined) {
data[item] = value;
}
});
return data;
},
// returns corresponding instance from a raw object (if applicable)
parse: function(data) {
return data;
},
// list of accepted keys in serialization
data: [],
// returns resource's URI
route: function() {
return supplant(tw.routes[this._type], this);
}
});
var Container = function(type, name, host) {
if(arguments.length) { // initialization
tw.Resource.apply(this, [type, host]);
this.name = name;
this.desc = "";
this.policy = new tw.Policy({});
}
};
Container.prototype = new tw.Resource();
$.extend(Container.prototype, {
tiddlers: function() {
return new tw.TiddlerCollection(this);
},
parse: function(data) {
var type = tw._capitalize(this._type),
container = new tw[type](this.name, this.host);
data.policy = new tw.Policy(data.policy);
return $.extend(container, data);
},
data: ["desc", "policy"]
});
// attribs is an object whose members are merged into the instance (e.g. query)
tw.Collection = function(type, host, attribs) {
if(arguments.length) { // initialization
tw.Resource.apply(this, [type, host]);
$.extend(this, attribs);
}
};
tw.Collection.prototype = new tw.Resource();
tw.TiddlerCollection = function(container, tiddler) {
if(arguments.length) { // initialization
tw.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
this.container = container || null;
this.tiddler = tiddler || null;
}
};
tw.TiddlerCollection.prototype = new tw.Collection();
$.extend(tw.TiddlerCollection.prototype, {
parse: function(data) {
var container = this.container;
return $.map(data, function(item, i) {
var tiddler = new tw.Tiddler(item.title, container),
bag = item.bag;
tiddler = tw.Tiddler.prototype.parse.apply(tiddler, [item]);
if(!tiddler.bag && bag) { // XXX: bag always present!?
tiddler.bag = new tw.Bag(bag, container.host);
}
if(!tiddler.recipe && item.recipe) {
tiddler.recipe = new tw.Recipe(item.recipe, container.host);
}
delete item.recipe;
return $.extend(tiddler, item);
});
},
route: function() {
var params = this.container;
if(this.tiddler) {
var container = this.tiddler.bag || this.tiddler.recipe;
params = {
_type: container._type,
host: container.host,
name: container.name,
title: this.tiddler.title
};
}
return supplant(tw.routes[this._type], params);
}
});
tw.Search = function(query, host) {
tw.Collection.apply(this, ["search", host]);
this.query = query;
};
tw.Search.prototype = new tw.Collection();
$.extend(tw.Search.prototype, {
parse: function(data) {
this.container = { // XXX: hacky
_type: "bag",
host: this.host
};
var tiddlers = tw.TiddlerCollection.prototype.parse.apply(this, arguments);
delete this.container;
return tiddlers;
}
});
// title is the name of the tiddler
// container (optional) is an instance of either Bag or Recipe
// optionally accepts a single object representing tiddler attributes
tw.Tiddler = function(title, container) {
tw.Resource.apply(this, ["tiddler", false]);
this.title = title;
this.bag = container && container._type === "bag" ? container : null;
this.recipe = container && container._type === "recipe" ? container : null;
var self = this;
$.each(this.data, function(i, item) {
self[item] = undefined; // exposes list of standard attributes for inspectability
});
if(title && title.title) { // title is an object of tiddler attributes
$.extend(this, title);
}
};
tw.Tiddler.prototype = new tw.Resource();
$.extend(tw.Tiddler.prototype, {
revisions: function() {
return new tw.TiddlerCollection(this.bag || this.recipe, this);
},
route: function() {
var container = this.bag || this.recipe;
var params = $.extend({}, this, {
host: container ? container.host : null,
_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
name: container ? container.name : null
});
return supplant(tw.routes[this._type], params);
},
parse: function(data) {
var tiddler = new tw.Tiddler(this.title),
container = this.bag || this.recipe;
if(data.bag) {
tiddler.bag = new tw.Bag(data.bag, container.host);
delete data.bag;
}
delete data.recipe;
tiddler.created = data.created ? convertTimestamp(data.created) : new Date();
delete data.created;
tiddler.modified = data.modified ? convertTimestamp(data.modified) : new Date();
delete data.modified;
if(this.recipe) {
tiddler.recipe = this.recipe;
}
return $.extend(tiddler, data);
},
data: ["created", "creator", "modifier", "modified", "tags", "type", "text",
"fields"],
ajaxSetup: function(options) {
var self = this;
if(this.etag && (options.type === "PUT" || options.type === "DELETE")) {
options.beforeSend = function(xhr) {
xhr.setRequestHeader("If-Match", self.etag);
};
}
if(options.type === "PUT") {
var callback = options.success;
options.success = function(data, status, xhr) {
var loc = xhr.getResponseHeader("Location"),
etag = xhr.getResponseHeader("Etag");
if(loc && etag) {
self.etag = etag;
if(!self.bag) {
var bag = loc.split("/bags/").pop().split("/")[0];
self.bag = new tw.Bag(bag, self.recipe.host);
}
callback(self, status, xhr);
} else { // IE
self.get(callback, options.error);
}
};
}
}
});
tw.Revision = function(id, tiddler) {
var container = tiddler.bag || tiddler.recipe;
tw.Tiddler.apply(this, [tiddler.title, container]);
this._type = "revision";
this.revision = id;
};
tw.Revision.prototype = new tw.Tiddler();
$.extend(tw.Revision.prototype, {
revisions: false,
data: false,
put: false,
"delete": false
});
tw.Bag = function(name, host) {
Container.apply(this, ["bag", name, host]);
};
tw.Bag.prototype = new Container();
tw.Recipe = function(name, host) {
Container.apply(this, ["recipe", name, host]);
this.recipe = [];
};
tw.Recipe.prototype = new Container();
$.extend(tw.Recipe.prototype, {
data: ["recipe"].concat(Container.prototype.data)
});
tw.Policy = function(constraints) { // TODO: validation?
var self = this;
$.each(this.constraints, function(i, item) {
self[item] = constraints[item];
});
};
tw.Policy.prototype.constraints = ["read", "write", "create", "delete",
"manage", "accept", "owner"];
/*
* utilities
*/
tw._capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
// convert YYYYMMDDhhmmss timestamp to Date instance
convertTimestamp = function(t) {
if (t.match(/^\d{12,17}$/)) {
return new Date(Date.UTC(
parseInt(t.substr(0, 4), 10),
parseInt(t.substr(4, 2), 10) - 1,
parseInt(t.substr(6, 2), 10),
parseInt(t.substr(8, 2), 10),
parseInt(t.substr(10, 2), 10),
parseInt(t.substr(12, 2) || "0", 10),
parseInt(t.substr(14, 3) || "0", 10)
));
} else {
return new Date(Date.parse(t));
}
};
// adapted from Crockford (http://javascript.crockford.com/remedial.html)
supplant = function(str, obj) {
return str.replace(/{([^{}]*)}/g, function (a, b) {
var r = obj[b];
r = typeof r === "string" || typeof r === "number" ? r : a;
return $.inArray(b, ["host", "query"]) !== -1 ? r : encodeURIComponent(r); // XXX: special-casing
});
};
return tw;
}(jQuery));
//}}}
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AP8zZgAAAGYA//8zAADMMwD/mTMAAGYzAP8zMwAAADMAzP8AAADMAADMmQAAAGYAAMwzAAAAAADuzAAA3QAAALvMAACqAAAAiMwAAHcAAABVmQAARAAAACKZAAARAADuAJkA3QAAALsAmQCqAAAAiACZAHcAAABVAJkARAAAACIAZgARAADuAABm3QAAALsAAGaqAAAAiAAAZncAAABVAABmRAAAACIAAGYRAAAA7u7uM93d3QC7u7szqqqqAIiIiDN3d3cAVVVVM0RERAAiIiIzERERAAAAADMBAQEBAQEBAQEBpXl5eXl5eXl5eXmlAQEBAQEBAQEBAQEBAQEBAQEBgHl5eXl5eXl5eXl5eXl5gAEBAQEBAQEBAQEBAQEB/Xp5eXlVT04qKioqTk9VeXl5ev0BAQEBAQEBAQEBAaV5eXlPKioqKioqKioqKioqT3l5eaUBAQEBAQEBAQGAeXlVTioqKioqKioqKioqKioqTlV5eYABAQEBAQEBgHl5VSoqKioqKioqKioqKioqKioqKlV5eYABAQEBAaV5eVUqKioqKioqKioqKioqKioqKioqKlV5eaUBAQEBeXlVKioqKioqKioqKioqKioqKioqKioqKlV5eQEBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBeXlPKioqKioqKjEyMjIyMjIyMjEqKioqKioqT3l5AXp5eSoqKioqKioxMjIxBwcHBzEyMjEqKioqKioqeXl6eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl5eU8qKioqKioyMgcHBwcHBwcHBwcyMioqKioqKk95eXl5TioqKioqMTIxBwcHBwcHBwcHBzEyMSoqKioqTnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eSoqKioqKjEyBwcHBwcHBwcHBwcHMjEqKioqKip5eXl5KioqKioqMTIHBwcHBwcHBwcHBwcyMSoqKioqKnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eU4qKioqKjEyMQcHBwcHBwcHBwcxMjEqKioqKk55eXl5TyoqKioqKjIyBwcHBwcHBwcHBzIyKioqKioqT3l5eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl6eXkqKioqKioqMTIyMQcHBwcxMjIxKioqKioqKnl5egF5eU8qKioqKioqMTIyMjIyMjIyMSoqKioqKipPeXkBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBAXl5VSoqKioqKioqKioqKioqKioqKioqKipVeXkBAQEB+nl5VSoqKioqKioqKioqKioqKioqKioqVXl5+gEBAQEBenl5VSoqKioqKioqKioqKioqKioqKlV5eXoBAQEBAQEBeXl5VU4qKioqKioqKioqKioqKk5VeXl5AQEBAQEBAQEBenl5eU8qKioqKioqKioqKipPeXl5egEBAQEBAQEBAQEB+nl5eXlVT04qKioqTk9VeXl5efoBAQEBAQEBAQEBAQEBAXl5eXl5eXl5eXl5eXl5eXkBAQEBAQEBAQEBAQEBAQEBAQF6eXl5eXl5eXl5eXoBAQEBAQEBAQEB/+AH//+AAf/+AAB//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///gB/8oAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAACAAAAAwAAAAMAAAADAAAABG1bSA61m3JXuqB4mbuhd8m9o3jqvaF4+b2hePm9o3jqu6F3ybqgeJm1m3JXbVtIDgAAAAQAAAADAAAAAwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACI98Wye0nXWavKF4876kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev+8oXjztJ11mo98WycAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAQAAAAHAAAAChwcHBKulnGJvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+K6WcYkcHBwSAAAACgAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAEAAAADAAAABwAAAAtuYkUst552z76kev++pHr+1LuS//Latf/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/8tq1/9S7kv++pHr+vqR6/7eeds9uYkUsAAAACwAAAAcAAAADAAAAAQAAAAAAAAABAAAAAgAAAAQAAAAIi3hbNbqgd+a+pHr/xayD/+3Vr//85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr//FrIP/vqR6/7qgd+aJdVg0AAAACAAAAAQAAAACAAAAAQAAAAEAAAACAAAABIl8WSW8oXjlvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7yheOWJfFklAAAABAAAAAIAAAABAAAAAAAAAAFfXz8Iu6F4zL6kev/Msor/+uK+//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//rivv/Msor/vqR6/7uheMxfXz8IAAAAAQAAAAAAAAAAAAAAAbqid4K+pHr/xayD//ngvP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//fgvP/FrIP/vqR6/7qid4IAAAABAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAALuheJa+pHr/1LuS//zlwP/85cD//OXA//zlwP/85cD//OXA//riwP/Pq8f/r4HM/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HN/6+BzP/Pq8f/+uLA//zlwP/85cD//OXA//zlwP/85cD//OXA/9S5kv++pHr/u6F4lgAAAACii3MLvKF4876kev/y2rX//OXA//zlwP/85cD//OXA//zlwP/64sD/w5vJ/6+Bzf+vg83/w5vc/9W06v/dwPD/3cDw/9W06v/Dm9z/r4PN/6+Bzf/Dm8n/+uLA//zlwP/85cD//OXA//zlwP/85cD/8tq1/76kev+8oXjzootzC72feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVvaF4mL6kev/fxZ7//OXA//zlwP/85cD//OXA//zlwP/v08L/r4HM/6+Dzf/Wtev/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/r4PN/6+BzP/v08L//OXA//zlwP/85cD//OXA//zlwP/fxZ7/vqR6/72heJi8oXfIvqR6/+zUrv/85cD//OXA//zlwP/85cD//OXA/9Crx/+vgc3/w5vc/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Dm9z/r4HN/9Crx//85cD//OXA//zlwP/85cD//OXA/+zUrv++pHr/vKF3yL2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvaF4+b6kev/64r7//OXA//zlwP/85cD//OXA//zlwP+zhsz/r4HN/93A8P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/3cDw/6+Bzf+zhsz//OXA//zlwP/85cD//OXA//zlwP/64r7/vqR6/72hePm9oXj5vqR6//rivv/85cD//OXA//zlwP/85cD//OXA/7OGzP+vgc3/3cDw/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//dwPD/r4HN/7OGzP/85cD//OXA//zlwP/85cD//OXA//rivv++pHr/vaF4+b2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvKF3yL6kev/s1K7//OXA//zlwP/85cD//OXA//zlwP/Qq8f/r4HN/8Ob3P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/w5vc/6+Bzf/Qq8f//OXA//zlwP/85cD//OXA//zlwP/s1K7/vqR6/7yhd8i9oXiYvqR6/9/Fnv/85cD//OXA//zlwP/85cD//OXA/+/Twv+vgcz/r4PN/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9a16/+vg83/r4HM/+/Twv/85cD//OXA//zlwP/85cD//OXA/9/Fnv++pHr/vaF4mL2feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVootzC7yhePO+pHr/8tq1//zlwP/85cD//OXA//zlwP/85cD/+uLA/8Obyf+vgc3/r4PN/8Ob3P/VtOr/3cDw/93A8P/VtOr/w5vc/6+Dzf+vgc3/w5vJ//riwP/85cD//OXA//zlwP/85cD//OXA//Latf++pHr/vKF486KLcwsAAAAAu6N3l76kev/Uu5L//OXA//zlwP/85cD//OXA//zlwP/85cD/+uLA/8+rx/+vgcz/r4HN/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HM/8+rx//64sD//OXA//zlwP/85cD//OXA//zlwP/85cD/1LmS/76kev+7oXiWAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAAAAAAAC6oneCvqR6/8Wsg//54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/34Lz/xayD/76kev+6oneCAAAAAAAAAAAAAAAAAAAAAH9/VQa8oHjLvqR6/8yyiv/64r7//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/+uK+/8yyiv++pHr/vKB4y39/VQYAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh67o3nkvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7ujeeSyoW4eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqbdim7o3nkvqR6/8Wsg//t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/t1a//xayD/76kev+7o3nkupt2KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh68oHjLvqR6/76kev7Uu5L/8tq1//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/y2rX/1LmS/76kev6+pHr/vKB4y7Khbh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/VQa6oneCvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+Lqid4J/f1UGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l28gu6F4lryhePO+pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vKF487uheJa3l28gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAootzC72feFW9oXiYvKF3yL2jeOq9oXj5vaF4+b2jeOq8oXfIvaF4mL2feFWii3MLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+AAf//4Af/
The ''getTiddler'' method of the [[store|TiddlyWiki Class]] object returns the DOM element of a tiddler in the ''store''. It takes one parameter, the name of a tiddler. If the tiddler does not exist, null is returned.
It can be used like so
{{{
store.getTiddler("GettingStarted");
}}}
In the SiteSubtitle tiddler you can define the subtitle of your tiddlywiki (seen under the main title)
In ~TiddlySpace by default it is set as
{{{
a TiddlySpace
}}}
You can set it to anything you want, such as:
{{{
documentation on the shadow tiddlers
}}}
/***
|''Name''|BinaryUploadPlugin|
|''Version''|0.3.15|
|''Author''|Ben Gillies and Jon Robson|
|''Type''|plugin|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/BinaryUploadPlugin.js|
|''Description''|Upload a binary file to TiddlyWeb|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig TiddlyWebConfig|
!Usage
{{{
<<binaryUpload bag:<name> edit:tags edit:title tags:<default tags> title:<title> >>
}}}
* {{{bag:<name>}}}: optional; if left out, the file will be saved to the current workspace
* {{{edit:tags}}}: specifies that you want to tag the file being uploaded
* {{{edit:title}}}: specifies that you want to set the title to something other than the filename
* {{{tags:<default tags>}}}: specifies a default set of tags to apply to the file (requires {{{edit:tags}}} to be set)
* {{{title:<title>}}}: predefines the title of the binary tiddler
!Requires
TiddlyWeb
tiddlywebplugins.form
!Code
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var macro = config.macros.binaryUpload = {
locale: {
titleDefaultValue: "Please enter a title...",
tagsDefaultValue: "Please enter some tags...",
titlePrefix: "title: ",
tagsPrefix: "tags: ",
loadSuccess: 'Tiddler %0 successfully uploaded',
loadError: "An error occurred when uploading the tiddler %0",
uploadInProgress: "Please wait while the file is uploaded...",
membersOnly: "Only members can upload."
},
renderInputFields: function(container, options) {
var locale = macro.locale;
var editableFields = options.edit;
var includeFields = {
tags: editableFields && editableFields.contains("tags") ? true : false,
title: editableFields && editableFields.contains("title") ? true : false
};
var fields = ["title", "tags"];
for(var i = 0; i < fields.length; i++) {
var fieldName = fields[i];
var userDefault = options[fieldName];
var defaultValue = userDefault ? userDefault[0] : false;
if(includeFields[fieldName] || defaultValue) {
var localeDefault = locale["%0DefaultValue".format(fieldName)];
var className = defaultValue ? "userInput" : "userInput notEdited";
var inputEl;
var val = defaultValue || localeDefault || "";
var iContainer = $("<div />").addClass("binaryUpload%0".format(fieldName)).
appendTo(container);
if(defaultValue && !includeFields[fieldName]) {
var label = locale["%0Prefix".format(fieldName)];
$("<span />").text(label).appendTo(iContainer);
$("<span />").addClass("disabledInput").text(val).appendTo(iContainer);
inputEl = $("<input />").attr("type", "hidden");
} else {
inputEl = $("<input />").attr("type", "text");
}
inputEl.attr("name", fieldName).
addClass("%0Edit".format(fieldName)).
val(val).addClass(className).appendTo(iContainer);
}
}
},
getTiddlerName: function(fileName) {
var fStart = fileName.lastIndexOf("\\");
var fStart2 = fileName.lastIndexOf("/");
fStart = fStart < fStart2 ? fStart2 : fStart;
fileName = fileName.substr(fStart+1);
return fileName;
},
errorHandler: function(fileName) {
displayMessage("upload of file %0 failed".format(fileName));
},
uploadFile: function(place, baseURL, workspace, options) {
var pleaseWait = $(".uploadProgress", place);
var iframeName = options.target;
var form = $("form", place);
var existingVal = $("input[name=title]", form).val();
var fileName = existingVal || $('input:file', form).val();
if(!fileName) {
return false; // the user hasn't selected a file yet
}
fileName = macro.getTiddlerName(fileName);
$("input[name=title]", place).val(fileName);
// we need to go somewhere afterwards to ensure the onload event triggers
var redirectTo = "/%0/tiddlers.txt?select=title:%1".
format(workspace, fileName);
var token = tiddlyspace ? tiddlyspace.getCSRFToken() : "";
var action = "%0?csrf_token=%1&redirect=%2"
.format(baseURL, token, redirectTo);
form[0].action = action; // dont use jquery to work with ie
form[0].target = iframeName;
// do not refactor following line... won't work in IE6 otherwise
$(place).append($('<iframe name="' + iframeName + '" id="' + iframeName + '"/>').css('display','none'));
macro.iFrameLoader(iframeName, function() {
var content = document.getElementById(iframeName).contentWindow.document.documentElement;
if($(content).text().indexOf(fileName) > -1) {
options.callback(place, fileName, workspace, baseURL);
} else {
macro.errorHandler(fileName);
}
form.show(1000);
pleaseWait.hide(1000);
});
form.hide(1000);
pleaseWait.show(1000);
return true;
},
createUploadForm: function(place, options) {
var locale = macro.locale;
if(readOnly) {
$('<div class="annotation" />').text(locale.membersOnly).
appendTo(place);
return;
}
var bag = options.bag;
options.callback = options.callback ? options.callback :
function(place, fileName, workspace, baseurl) {
macro.displayFile(place, fileName, workspace);
displayMessage(locale.loadSuccess.format(fileName));
$("input[type=text]", place).val("");
};
var defaults = config.defaultCustomFields;
place = $("<div />").addClass("container").appendTo(place)[0];
var workspace = bag ? "bags/%0".format(bag) : config.defaultCustomFields["server.workspace"];
var baseURL = defaults["server.host"];
baseURL += (baseURL[baseURL.length - 1] !== "/") ? "/" : "";
baseURL = "%0%1/tiddlers".format(baseURL, workspace);
//create the upload form, complete with invisible iframe
var iframeName = "binaryUploadiframe%0".format(Math.random());
// do not refactor following line of code to work in IE6.
var form = $('<form action="%0" method="POST" enctype="multipart/form-data" />'.
format(baseURL)).addClass("binaryUploadForm").
appendTo(place)[0];
macro.renderInputFields(form, options);
$(form).
append('<div class="binaryUploadFile"><input type="file" name="file" /></div>').
append('<div class="binaryUploadSubmit"><input type="submit" value="Upload" /></div>').
submit(function(ev) {
this.target = iframeName;
options.target = iframeName;
macro.uploadFile(place, baseURL, workspace, options);
});
$('<div />').addClass("uploadProgress").text(locale.uploadInProgress).hide().appendTo(place);
$("input[name=file]", place).change(function(ev) {
var target = $(ev.target);
var fileName = target.val();
var title = $("input[type=text][name=title]", place);
if(!title.val()) {
title.val(fileName);
}
});
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
params = paramString.parseParams(null, null, true);
macro.createUploadForm(place, params[0]);
},
iFrameLoader: function(iframeName, callback) {
var iframe = document.getElementById(iframeName); //jQuery doesn't seem to want to do this!?
var locale = macro.locale;
$(".userInput").addClass("notEdited"); // reset editing
var finishedLoading = function() {
callback();
};
var iFrameLoadHandler = function() {
finishedLoading.apply();
return;
};
iframe.onload = iFrameLoadHandler;
//IE
completeReadyStateChanges = 0;
iframe.onreadystatechange = function() {
if (++(completeReadyStateChanges) == 3) {
iFrameLoadHandler();
}
};
},
displayFile: function(place, title, workspace) {
var adaptor = store.getTiddlers()[0].getAdaptor();
var context = {
workspace: workspace,
host: config.defaultCustomFields['server.host']
};
adaptor.getTiddler(title, context, null, function(context) {
if(context.status) {
store.addTiddler(context.tiddler);
story.displayTiddler(place, title);
var image = config.macros.image;
if(image && image.refreshImage) {
image.refreshImage("/%0/tiddlers/%1".format(workspace, title));
image.refreshImage(title);
image.refreshImage("/%0".format(title));
image.refreshImage("%0/%1/tiddlers/%2".format(config.extensions.tiddlyweb.host, workspace, title));
}
} else {
displayMessage(macro.locale.loadError.format(title));
}
});
}
};
if(tiddlyspace) {
config.macros.binaryUploadPublic = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var options = paramString.parseParams(null, null, true)[0];
var bag = tiddlyspace.getCurrentBag("public");
options.bag = bag;
macro.createUploadForm(place, options);
}
};
config.messages.privacySetting = config.options.chkPrivateMode ?
"private" : "public";
config.macros.binaryUpload.defaultWorkspace = tiddlyspace.
getCurrentWorkspace(config.messages.privacySetting);
}
})(jQuery);
//}}}
{{{
[element =]createTiddlyCheckbox(parent,caption,checked,onChange)
}}}
The global function ''createTiddlyCheckbox'' creates a DOM check box input element. This function takes four parameters:
; parent
: the DOM element where the text node will be placed.
; caption
: text to be displayed after the check box element.
; checked
: the initial state of the check box.
; onChange
: a callback function to be called when a check box changed event occurs.
/***
|''Name''|TiddlySpaceInitialization|
|''Version''|0.7.2|
|''Description''|Initializes new TiddlySpaces the first time they are created|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/blob/master/src/plugins/TiddlySpaceInit.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig RandomColorPalettePlugin chrjs ImageMacroPlugin|
!TODO
* robust error notification and recovery
!MarkupPreHead
<!--{{{-->
<link rel="shortcut icon" href="/recipes/%0_public/tiddlers/favicon.ico" />
<link href="/bags/%0_public/tiddlers.atom" rel="alternate"
type="application/atom+xml" title="%0's public feed" />
<link rel="canonical" href="%1/" />
<!--}}}-->
!Code
***/
//{{{
(function($) {
var versionField = "tiddlyspaceinit_version";
var markupPreHead = store.getTiddlerText(tiddler.title + "##MarkupPreHead", "");
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace;
var tweb = config.extensions.tiddlyweb;
var plugin = config.extensions.TiddlySpaceInit = {
version: "0.6",
SiteTitle: "%0",
SiteSubtitle: "a TiddlySpace",
flagTitle: "%0SetupFlag",
flagWarning: "Please do not modify this tiddler; it was created " +
"automatically upon space creation.",
dispatch: function(ev) {
var title = plugin.flagTitle.format([currentSpace.name]);
config.annotations[title] = plugin.flagWarning;
if(currentSpace.type != "private") {
return;
}
var tiddlers = [];
var tid = store.getTiddler(title);
if(tid) {
curVersion = parseFloat(tid.fields[versionField]);
reqVersion = parseFloat(plugin.version);
if(curVersion < reqVersion) {
plugin.update(curVersion, tid);
tid.fields[versionField] = plugin.version;
tid.incChangeCount();
tid = store.saveTiddler(tid);
tiddlers.push(tid);
}
} else { // first run
tid = new Tiddler(title);
tid.tags = ["excludeLists", "excludeSearch", "excludePublisher"];
tid.fields = $.extend({}, config.defaultCustomFields);
tid.fields[versionField] = plugin.version;
tid.text = "@@%0@@".format([plugin.flagWarning]);
tid = store.saveTiddler(tid);
tiddlers = tiddlers.concat(plugin.firstRun(), tid);
}
autoSaveChanges(null, tiddlers);
},
update: function(curVersion, flagTiddler) {
if(curVersion < 0.2) {
this.createAvatar();
}
if(curVersion < 0.3) {
flagTiddler.tags.pushUnique("excludePublisher"); // XXX: never persisted
}
if(curVersion < 0.5) { // v0.4 was faulty
this.setupMarkupPreHead();
}
if(curVersion < 0.6) {
this.purgeSystemSettings();
}
},
pubTid: {
tags: ["excludeLists", "excludeSearch"],
fields: $.extend({}, config.defaultCustomFields, {
"server.workspace": tiddlyspace.getCurrentWorkspace("public")
})
},
makeTiddlerIfNot: function(tiddler) {
if (!store.tiddlerExists(tiddler.title)) {
$.extend(true, tiddler, plugin.pubTid);
return [store.saveTiddler(tiddler)];
} else {
return [];
}
},
firstRun: function() {
var tiddlers = [];
// generate Site*itle
$.each(["SiteTitle", "SiteSubtitle"], function(i, item) {
var tid = new Tiddler(item);
tid.text = plugin[item].format([currentSpace.name]);
tiddlers.push.apply(tiddlers,
plugin.makeTiddlerIfNot(tid));
});
// generate public ColorPalette
var tid = new Tiddler("ColorPalette");
tid.text = config.macros.RandomColorPalette.generatePalette({
saturation_pale: 0.67, saturation_light: 0.53,
saturation_mid: 0.43, saturation_dark: 0.06,
pale: 0.99, light: 0.85, mid: 0.5, dark: 0.31
},
false);
tiddlers.push.apply(tiddlers, plugin.makeTiddlerIfNot(tid));
this.createAvatar();
this.setupMarkupPreHead();
return tiddlers;
},
// remove _cookie slices (TiddlyWiki 2.6.2 beta 6 remnants)
purgeSystemSettings: function() {
var ss = store.getTiddler("SystemSettings");
if(ss) {
var lines = ss.text.split("\n");
var persistentOptions = $.grep(lines, function(line, i) {
return line.indexOf("_cookie:") == -1;
});
ss.text = persistentOptions.join("\n");
ss = store.saveTiddler(ss);
autoSaveChanges(null, [ss]);
}
},
createAvatar: function() {
var avatar = "SiteIcon";
var host = tweb.host;
var notify = function(xhr, error, exc) {
displayMessage("ERROR: could not create avatar - " + // TODO: i18n
"%0: %1".format([xhr.statusText, xhr.responseText]));
// TODO: resolve!?
};
var pubBag = tiddlyspace.getCurrentBag("public");
var tid = new tiddlyweb.Tiddler(avatar);
tid.bag = new tiddlyweb.Bag(pubBag, host);
var callback = function(data, status, xhr) {}; // avatar already exists; do nothing
var errback = function(xhr, error, exc) {
if(xhr.status != 404) {
return;
}
// copy default avatar
var _notify = function(tid, status, xhr) {
displayMessage("created avatar"); // TODO: i18n
var image = config.macros.image;
if(image && image.refreshImage) {
var uri = "/%0/tiddlers/SiteIcon".
format(tiddlyspace.getCurrentWorkspace("public"));
image.refreshImage(uri);
image.refreshImage("SiteIcon");
}
};
var _callback = function(tid, status, xhr) {
tid.title = avatar;
tid.bag.name = pubBag;
delete tid.etag;
tid.put(_notify, notify); // TODO: add to current session document (via adaptor?)
};
tweb.getUserInfo(function(user) {
var avatarTitle = currentSpace.name == user.name ?
"defaultUserIcon" : "defaultSiteIcon";
var tid = new tiddlyweb.Tiddler(avatarTitle);
tid.bag = new tiddlyweb.Bag("common", host);
tid.get(_callback, notify);
});
};
tid.get(callback, errback);
},
setupMarkupPreHead: function() {
var pubWorkspace = tiddlyspace.getCurrentWorkspace("public");
var existing = store.getTiddler("MarkupPreHead");
if(!existing || existing.fields["server.workspace"] != pubWorkspace) {
tweb.getStatus(function(status) {
var tid = new Tiddler("MarkupPreHead");
tid.text = markupPreHead.format(currentSpace.name, tiddlyspace.getHost(status.server_host,
currentSpace.name));
tid.tags = ["excludeLists"];
tid.fields = $.extend({}, config.defaultCustomFields);
tid.fields["server.workspace"] = pubWorkspace;
tid.fields["server.page.revision"] = "false";
tid = store.saveTiddler(tid);
autoSaveChanges(null, [tid]);
});
}
}
};
$(document).bind("startup", plugin.dispatch);
})(jQuery);
//}}}
Takes 3 arguments: field (can also be a tiddler attribute),value,sortField (optional)
Returns all tiddlers that match the given field and value. If sortField is given the resulting tiddlers are sorted.
See the similiar [[TiddlyWiki.prototype.getTaggedTiddlers]]
To create a new tiddler from the current date and time:
{{{
<<newJournal>>
}}}
Displays as:
<<newJournal>>
This is a special tiddler(a [[Shadow Tiddler]]) which allows you to control the layout and functionality used for editing a [[Tiddler]] in TiddlyWiki. See [[here|http://tiddlywiki.org/wiki/EditTemplate]].
Read more about the [[EditTemplate Shadow Tiddler|Shadow - EditTemplate]]@shadowtiddlers
look up things //and// add your own knowledge by simply creating a new tiddler!
This function returns the text inside a DOM element. It does this by using the jQuery .text() function.
It takes the DOM element as an argument.
Open the tiddler by clicking on Edit (grey menu at top right of tiddler) or double clicking on any of the text. Edit the tiddler as required. To format text (bold, italics etc), see [[Wiki Markup]].
To save the tiddler, click on Done. The tiddler will display in read mode. Click on Save Changes (top right-hand menu) before leaving the TiddlyWiki.
for items tagged glossary
To select autosave, go to 'options' on the right-hand top menu. A blue box will open. Look around halfway down and click on 'autosave'.
----
What does autosave mean? Does it save every few minutes? Does it save after every keystroke?
If AutoSave is enabled, the TiddlyWiki document is saved whenever a tiddler is changed. If it is disabled, changes have to be saved manually using SaveChanges.
----
The ''fetchTiddler'' method of a [[TiddlyWiki class|TiddlyWiki Class]] object returns an object of the [[Tiddler class|Tiddler]] that the TiddlyWiki contains.
It expects one parameter: the name of the tiddler.
{{{
store.fetchTiddler('Name Of Tiddler');
}}}
If the tiddler does not exist, then an undefined value is returned.
Note: This is different from a null value.
This is a primitive method used by many other methods in the TiddlyWiki class.
Reply to this tiddler if you have a particular request for missing content or have content you wish to contribute but it doesn't as of yet have a tiddler covering it in this space.
All suggestions are greatly appreciated and will be displayed below.
The ''displayDefaultTiddlers'' method of the [[Story]] class is used to display all the tiddlers that are listed in the [[DefaultTiddlers]] shadow tiddler.
Note: Any tiddlers already displayed in the story will persist.
The ''setDirty'' method of the [[Story]] class sets the dirty flag of a single tiddler, which indicates whether it contains unsaved changes. It takes two parameters:
* the title of the tiddler
* the boolean value to set the dirty flag to
This method does not return any value.
For example to set this tiddler to dirty you would do the following:
{{{
story.setDirty('Story.setDirty', true);
}}}
Slices allows you to use special notation to pull out a chunk of specially marked text from within a tiddler. Each slice has a name and a value which can be specified anywhere within a tiddler in any of these formats:
{{{
theName: textSlice
|theName:| textSlice |
|theName| textSlice |
}}}
The name may contain any of the characters {{{a-ZA-Z_0-9}}}, and may also be decorated with {{{''}}} or {{{//}}} markers for ''bold'' and //italic// formatting that are ignored. For example:
{{{
|''theName:''| textSlice |
}}}
Slices can be then be referenced by qualifying the parent tiddler name with the symbols "::" and the name of the slice. For example:
{{{
ColorPalette::PrimaryLight
}}}
Slices doesn't work eveywhere; at this point it is mainly intended to support the ColorPalette and similar usages.
Finally, here's an example of some more complex slice formatting:
{{{
version: 1.2.3.4
Author: Joe Brown
''Credits:'' ~ASmith ~BBrown ~CCalony
//~SeeAlso:// The rise and fall of the M-perium
|!Name|!Value|
|Name:|Slice Tester|
|URL:|http:\\sample.com\TestSliced |
|''Type:''| Plugin |
|//Source//| http:\\sample.com\TestSliced\src\text.js |
}}}
The slices defined from the above example render as:
<<<
version: 1.2.3.4
Author: Joe Brown
''Credits:'' ~ASmith ~BBrown ~CCalony
//~SeeAlso:// The rise and fall of the M-perium
|!Name|!Value|
|Name:|Slice Tester|
|URL:|http:\\sample.com\TestSliced |
|''Type:''| Plugin |
|//Source//| http:\\sample.com\TestSliced\src\text.js |
<<<
<<list filter [tag[common]]>>
* [[TiddlyWiki]] is a wiki, notebook, information manager.
* TiddlyWiki is a wiki that is programmed in JavaScript and runs entirely self-contained in the browser.
* TiddlyWiki is a revolutionary new way to manage information using [[microcontent|http://www.useit.com/alertbox/980906.html]].
* TiddlyWiki is also used as a web framework.
'' TiddlyWiki in ten seconds... ''
by TomO (source http://dcubed.com/#TiddlyWiki)
* 10...TiddlyWiki is a web-based [[wiki|http://en.wikipedia.org/wiki/Wiki]] that has a very rich Javascript runtime built into every page. If you are reading a TiddlyWiki document, you have the //entire// TiddlyWiki application, in addition to all the "articles" that make up the wiki itself.
* 9...The "articles" within a TiddlyWiki are called ''tiddlers'', and they are saved with the main HTML page used to view the document. If you open a TW document, you can see all the tiddlers saved at the bottom of the file.
* 8...When you view a TW document over the web, you are usually prohibited from making changes. For interactive, modifiable documents like this one, you typically need to save the document locally to your machine and work with it there.
* 7...Tiddlers can be referenced by their name but, more importantly, they can be arbitrarily ''tagged'' to categorize them. Tags may be freely modified, and there are numerous interface widgets within TW to list or find tiddlers by their tags.
* 6...When you click on an internal hyperlink to a tiddler, it will usually open up directly above or below the tiddler you are currently reading and should scroll immediately into view.
* 5...When you hover your mouse over a tiddler, a small context-sensitive ''tiddler menu'' appears above and to the right of the tiddler. One of the important items in this menu is ''edit'' (or ''view''), which allows you to view and modify the source for a tiddler.
* 4...Tiddler source is a combination of just plain text, plus special formatting commands in ''wiki-text'' that allow you to express style and layout for tiddlers without knowing any HTML. It is important to know that the formatting commands, tiddler menus, and just about everything else can be arbitrarily extended by third-party ''plug-ins'' to create custom solutions like this one.
* 3...2...1 That is it in a nutshell, but if you are still feeling a little lost, try this [[tutorial|http://www.blogjones.com/TiddlyWikiTutorial.html ]].
[[Back to FAQ list|TiddlyWiki FAQ ]]
/***
|''Name''|TiddlySpaceSearcher|
|''Version''|0.2.5|
|''Requires''|TiddlySpaceConfig TiddlySpaceFollowingPlugin|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var tsScan = config.macros.tsScan;
config.shadowTiddlers.SearchTemplate = "<<view server.bag SiteIcon label:no width:24 height:24 preserveAspectRatio:yes>> <<view server.bag spaceLink title external:no>> in space <<view server.bag spaceLink>>";
config.shadowTiddlers.StyleSheetSearch = [".resultsArea .siteIcon { display: inline; }",
".searchForm {text-align: left;}"].join("\n");
store.addNotification("StyleSheetSearch", refreshStyles);
var search = config.macros.tsSearch = {
locale: {
advanced: "Advanced Options",
header: "Search",
resultsHeader: "Results (%0)",
find: "find",
noResults: "No tiddlers matched your search query",
query: "QUERY: ",
error: "please provide a search query or a tag, modifier or title!",
titleAdvanced: "where the title is",
modifierAdvanced: "where the last modifier is",
spaceAdvanced: "only in the space: ",
notspaceAdvanced: "but not in the spaces: ",
tagsAdvanced: "with the tags: "
},
andConstructor: function(container, label, fieldname, negationMode) {
var tags = $("<div />").appendTo(container);
$('<span />').text(label).appendTo(tags);
var id = "area" + Math.random();
container = $("<span />").attr("id", id).appendTo(tags)[0];
function add(container) {
var el = $('<input type="text" />').attr("field", fieldname).appendTo(container);
if(negationMode) {
el.attr("negation", "true");
}
}
add(container);
var el = $("<button />").text("AND").click(function(ev) {
add($(ev.target).data("container"));
ev.preventDefault();
}).appendTo(tags);
$(el).data("container", container);
},
fieldConstructor: function(container, label, field) {
container = $("<div />").appendTo(container)[0];
$("<span />").text(label).appendTo(container);
$("<input />").attr("text", "input").attr("field", field).appendTo(container);
},
advancedOptions: function(form) {
var locale = search.locale;
var container = $("<div />").addClass("tsAdvancedOptions").appendTo(form)[0];
$("<h2/ >").text(search.locale.advanced).appendTo(container);
$("<div />").addClass("separator").appendTo(container);
search.fieldConstructor(container, locale.titleAdvanced, "title");
search.fieldConstructor(container, locale.modifierAdvanced, "modifier");
search.fieldConstructor(container, locale.spaceAdvanced, "space");
search.andConstructor(container, locale.notspaceAdvanced, "space", true);
search.andConstructor(container, locale.tagsAdvanced, "tag");
},
constructSearchQuery: function(form) {
var data = [], select = [];
var query = $("[name=q]", form).val();
if(query) {
data.push("q=%0".format(query));
}
// add tags, fields etc..
$("[field]", form).each(function(i, el) {
var val = $(el).val();
var name = $(el).attr("field");
var negate = $(el).attr("negation") == "true";
if(val && name) {
val = encodeURIComponent(val);
val = negate ? "!" + val : val;
if(name == "space") {
val += "_public";
name = "bag";
}
if(negate) {
select.push("select=%0:%1".format(name,val));
} else {
var prefix = data.length === 0 ? "q=" : "";
data.push('%0%1:"%2"'.format(prefix, name, val));
}
}
});
var dataString = data.join(" ");
if(dataString.length === 0 && !query) {
return false;
}
var selectStatement = select.join("&");
if(dataString.length > 0 && selectStatement.length > 0) {
dataString += "&";
}
dataString += selectStatement;
return "/search?%0".format(dataString);
},
constructForm: function(place) {
var locale = search.locale;
$("<h1 />").text(locale.header).appendTo(place);
var form = $("<form />").appendTo(place)[0];
$('<input type="text" name="q" />').appendTo(form);
$('<input type="submit" />').val(locale.find).appendTo(form);
search.advancedOptions(form);
var query = $('<h2 class="query"/>').appendTo(place)[0];
var results = $("<div />").appendTo(place).addClass("resultsArea")[0];
var lookup = function(url) {
if(!url) {
results.empty().addClass("error").text(locale.error);
return;
}
config.extensions.tiddlyweb.getStatus(function(status) {
$(query).text(locale.query);
var href = status.server_host.url + url;
$("<a />").attr("href", href).text(href).appendTo(query);
tsScan.scan(results, { url: url, emptyMessage: search.locale.noResults, cache: true,
template: "SearchTemplate", sort: "title", callback: function(tiddlers) {
$("<h2 />").text(locale.resultsHeader.format(tiddlers.length)).prependTo(results);
}
});
});
};
$(form).submit(function(ev) {
ev.preventDefault();
var url = search.constructSearchQuery(form);
config.macros.tsSearch.lastSearch = url;
lookup(url);
});
if(search.lastSearch) {
lookup(search.lastSearch);
}
return form;
},
handler: function(place) {
var container = $("<div />").addClass("searchForm").appendTo(place)[0];
search.constructForm(container);
}
}
})(jQuery);
//}}}
/***
|''Name''|??Theme|
|''Source''|http://??|
|''Version:''|0.1|
|''Author:''|Name|
|''Date:''|date|
|''License:''|link to license|
|''Comments:''|Please make comments at http://groups.google.nl/group/TiddlyWiki|
|''~CoreVersion:''|2.6.x|
|''Type''|CSS|
|''Description''|a ''~TiddlyWiki'' theme: http://??|
|''PageTemplate:''|##PageTemplate|
|''ViewTemplate:''|##ViewTemplate|
|''EditTemplate:''|##EditTemplate|
|''StyleSheet:''|##StyleSheet|
***/
!PageTemplate
<!--{{{-->
<!--}}}-->
!ViewTemplate
<!--{{{-->
<!--}}}-->
!EditTemplate
<!--{{{-->
<!--}}}-->
!StyleSheet
/*{{{*/
/*}}}*/
HTML entities provide a way to encode special characters.
'' Commonly Used Symbols ''
| !Code | !Symbol | !Description |h
| &eacute; | é | acute accent|
| &rarr; | → | right arrow|
| &larr; | ← | left arrow|
| &rArr; | ⇒ | double right arrow|
| &lArr; | ⇐ | double left arrow|
| &there4; | ∴ | therefore (mathematical)|
'' See Also ''
* [[Use of other languages such as XML, HTML]]
'' External Resources ''
* [http://de.selfhtml.org/html/referenz/zeichen.htm HTML entities reference] (DE)
* [http://www.tiddlywiki.com/#HtmlEntities HTML Entities]
* [http://www.w3schools.com/TAGS/ref_entities.asp HTML Entities Reference]
* [http://www.w3schools.com/TAGS/ref_symbols.asp HTML Symbol Entities Reference]
* [http://piddlytots.tiddlyspot.com/#HTMLEntityReference HTML Entities Reference, in TiddlyWiki markup]
This tiddler contains the mark up to display tiddlers. You can change the mark up to create a custom view of a tiddler.
By default it contains the following markup:
{{{
<div class='toolbar'
macro='toolbar [[ToolbarCommands::ViewToolbar]] icons:yes height:16 width:16 more:popup'>
</div>
<div class='heading'>
<span class='spaceSiteIcon'
macro='tiddlerOrigin label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
</span>
<span class="titleBar">
<div class='title' macro='view title text'></div>
<div class="subtitle" macro='viewRevisions page:5'>
last modified on
<span macro="view modified date"></span>
</div>
</span>
<span class='followPlaceHolder' macro='followTiddlers'></span>
<span class='modifierIcon'
macro='view modifier SiteIcon label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
</span>
<div class='tagClear'></div>
</div>
<div class='content'>
<div class='viewer' macro='view text wikified'></div>
</div>
<div class='tagInfo'>
<div class='tidTags' macro='tags'></div>
<div class='tagging' macro='tagging'></div>
</div>
}}}
CamelCase (camel case or camel-case)—also known as medial capitals—is the practice of writing compound words or phrases in which the elements are joined without spaces.
[[TiddlyWeb|http://tiddlyweb.com]] is an open source implementation of a server side for TiddlyWiki with a [[HTTP API]] for storing and accessing content on The Web. TiddlyWeb is being developed by [[Osmosoft]] and is available from the [[TiddlyWeb Project Page|http://github.com/tiddlyweb]] on [[github|http://github.com]] or [[PyPI|http://pypi.python.org/pypi/tiddlyweb]].
The ''getTags'' method that belongs to the ''store'' object is used to return a list of all the tags used in your tiddlywiki and the number of times each is used.
It takes one optional parameter, an array of all the tags you wish to exclude from the returned results.
You can use it without excluding some tags like so:
{{{
store.getTags();
}}}
This will return something like this:
{{{
[["command", 1], ["concept", 3], ["Developer Tools", 5], ["excludeLists", 74], ["excludeMissing", 7], ["excludePublisher", 1], ["excludeSearch", 72], ["global", 3], ["method", 17], ["store", 4], ["story", 4], ["systemConfig", 39], ["tiddler", 3], ["tiddlywiki api", 1]]
}}}
To filter out certain tags use it like this:
{{{
store.getTags(["excludeLists", "excludeSearch", "excludePublisher", "excludeMissing", "systemConfig"]);
}}}
This will return something like this:
{{{
[["command", 1], ["concept", 3], ["Developer Tools", 5], ["global", 3], ["method", 17], ["store", 4], ["story", 4], ["tiddler", 3], ["tiddlywiki api", 1]]
}}}
Binary tiddlers are tiddlers which have the field "server.content-type" set to a content type / MIME type
See http://en.wikipedia.org/wiki/MIME
Tiddlers when served via the [[HTML Serialization]] are rendered using this MIME type. See [[image tiddlers]]@faq
!SpaceUnplugged
{{unpluggedSpaceTab{
{{wizard{
<<image unsyncedIcon width:48>> <<message messages.syncExplanation>>
}}}
{{wizard syncKey{
{{keyHeading{
Key}}}
{{changedServer keyItem{<<message macros.sync.syncStatusList.changedServer.text>>}}} {{changedBoth keyItem{<<message macros.sync.syncStatusList.changedBoth.text>>}}} {{changedLocally keyItem{<<message macros.sync.syncStatusList.changedLocally.text>>}}} {{notFound keyItem{<<message macros.sync.syncStatusList.notFound.text>>}}}
}}}
<<sync>>
!Menu
<<message messages.memberStatus>> <<homeLink>>
{{unsyncedList{<<message messages.syncListHeading>> <<list filter [is[unsynced]]>>}}}
<<tabs txtTiddlySpaceTab
search "search across TiddlySpace" Backstage##Search
tiddlers "tiddlers control panel" Backstage##BackstageTiddlers
plugins "Manage installed plugins" PluginManager
batch "Perform batch operations on public/private tiddlers" Backstage##BatchOps
tweaks "Tweak the appearance and behaviour of TiddlyWiki" AdvancedOptions
"import/export" "Import/export tiddlers from/to a TiddlyWiki" Backstage##ImportExport
>>
running TiddlySpace@glossary version <<message extensions.tiddlyweb.status.tiddlyspace_version>>
{{autotable{
<<tiddler Backstage##Resources>>
}}}
!Resources
[[blog|@@blog]] [[documentation|@@docs]] [[featured spaces|@@featured]]
!Search
<<tsSearch>>
!ImportExport
<<fileImport>>
You can download this TiddlySpace as an offline TiddlyWiki:
{{chunkyButton{<<exportSpace>>}}}
!BackstageTiddlers
|upload a <<message messages.privacySetting>> file: <<binaryUpload>>|<<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>>|
|>|<<search>>|
|>|<<tiddler Backstage##Tiddlers>>|
!Tiddlers
<<tabs
txtMainTab
"Recent" "Recently edited tiddlers" TabTimeline
"All" "All tiddlers" TabAll
"Public" "All public tiddlers" [[TiddlySpaceTabs##Public]]
"Private" "All private tiddlers" [[TiddlySpaceTabs##Private]]
"Tags" "All tags" TabTags
"Spaces" "Tiddlers grouped by space" [[TiddlySpaceTabs##Spaces]]
"Missing" "Missing tiddlers" TabMoreMissing
"Orphans" "Orphaned tiddlers" TabMoreOrphans
"Shadows" "Shadowed tiddlers" TabMoreShadowed
>>
!BatchOps
<<tabs
txtPublisherTab
"Private" "Move tiddlers from private to public" Backstage##BatchPrivate
"Public" "Move tiddlers from public to private" Backstage##BatchPublic
>>
!BatchPrivate
<<TiddlySpacePublisher type:private>>
!BatchPublic
<<TiddlySpacePublisher type:public>>
This tiddler contains a list of tiddlers that are opened automatically when you load the tiddlywiki.
The default is:
{{{
[[GettingStarted]]
}}}
An example could be:
{{{
[[HelloThere]]
[[Reference]]
[[Features]]
}}}
Note you can also put filters into your DefaultTiddlers tiddler. For instance to open all tiddlers tagged with blog on startup:
{{{
[tag[blog]]
}}}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="2 724 68 55"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<g>
<path d="M 2.25 756 L 11.25 747 L 24.75 760.4994 L 60.750004 724.4994 L 69.75 733.49902
L 24.749977 778.49976 Z" fill="#101010" class="glyph"/>
</g>
</g>
</svg>
!Text
Renders the field exactly how it is stored.
For example
{{{
<<view modified text>>
<<view title text>>
}}}
gives:
* <<view modified text>>
* <<view title text>>
!Link
Renders the value of the field as a link
{{{
<<view title link>>
}}}
gives
* <<view title link>>
!Date
Applicable to the modified and created fields. Note a further parameter - a date format can be used.
{{{
<<view created date>>
<<view modified date "YYYY">>
}}}
gives:
* <<view created date>>
* <<view modified date "YYYY">>
See [[Date Formats]] for possible date format strings.
!Wikified
Treats the string as wikitext.
e.g.
{{{
<<view customfield wikified>>
}}}
An optional third parameter can be used to transform the text before it is wikified. For example:
{{{
<<view customfield wikified "//%0//">>
}}}
The result of this example would be to make the field display in italics.
//(Notice: the placeholder starts with a '%', in contrast to the placeholders used by the [[tiddler macro]] that start with '$')//
!TiddlySpace specific
See [[TiddlySpace View Types]]
This is the new TiddlySpace based community wiki for TiddlyWiki powered by the [[community|Contributors]]. It includes content migrated from the [[old wiki|http://oldwiki.tiddlywiki.org]]. [[See here|http://groups.google.com/group/tiddlywiki/browse_thread/thread/c005b5a50001bbc9/6f7c92dbc3355de2]] for more information about the migration process.
[[Main Page content from old wiki]]
If you feel a tiddler here should be deleted please mark it with the tag "delete" - this feed is monitored and an admin will review and delete these tiddlers.
If you already are a registered user of TiddlySpace, you are granted editing privileges in [[this space|TiddlySpace]], regardless of whether or not you are a member of the TiddlyWiki space. In case you are not yet registered with TiddlySpace, see http://tiddlyspace.com as to how to to become a member.
If you prefer you can view all the tiddlers in this space separately in [[html|/tiddlers?select=tag:!excludeLists]] format.
In the SiteTitle tiddler you can define the title of your TiddlyWiki. When you first create a TiddlyWiki it defaults to
{{{
TiddlyWiki
}}}
However you can edit it to display anything that you choose.
Once you have some content then you may choose to determine a tiddler, or set of tiddlers to display each time you load ~TiddlySpace. This is determined by the [[DefaultTiddlers]].
<html><hr><html>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>This Space</title>
<script type='text/javascript' src='/bags/common/tiddlers/backstage.js'></script>
<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
</head>
<body>
<div id="container">
<div id="text-html" class="main section">
<a class="app" href="/apps">back to apps</a>
<div class="left">
<h2>About this space <button class='toggleNext'>show</button></button></h2>
<div id="siteinfo"></div>
<h2>Site Icon</h2>
<div>
<img id="siteicon" class="siteicon">
<form id="upload" method="POST" enctype="multipart/form-data">
<input type="hidden" name="title" value="SiteIcon" />
<input type="hidden" name="tags" value="excludeLists">
<input type="hidden" name="csrf_token" class="csrf" />
<input type="file" name="file" />
<input type="submit" value="upload" />
</form>
</div>
<h2>Vital Statistics</h2>
<div id="info">please wait while information is loaded about this space...</div>
</div>
<div class="right">
<div class="ts-membership">
<h2>
Add Member
<a href="http://docs.tiddlyspace.com/What%20is%20a%20member%3F" title="What is a Member?" class="help">What is a Member?</a>
</h2>
<div>
<p>Add a new member to your space by entering their name below. Enter a space to add all existing members of that space.</p>
<form class="ts-members">
<input class="inputBox" type="text" name="username">
<input type="submit" value="Add Member" />
</form>
</div>
<h2>
Existing Members <button class='toggleNext'><</button></button>
</h2>
<div>
Your space currently has the following members:
<ul class="ts-members"></ul>
</div>
<h2>
Include Space
<a class="help" href="http://docs.tiddlyspace.com/What%20is%20space%20inclusion%3F" title="What is inclusion?">What is Inclusion?</a>
</h2>
<form class="ts-includes">
<input class="inputBox" type="text" name="spacename">
<input type="submit" value="Include Space" />
</form>
</div>
<div>
<h2>Included Spaces <button class='toggleNext'><</button></button></h2>
<div>
This space includes the following spaces:
<ul class="ts-includes"></ul>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
<script type='text/javascript' src='/bags/common/tiddlers/jquery.js'></script>
<script type='text/javascript' src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script type='text/javascript' src='/bags/common/tiddlers/chrjs.space'></script>
<script type='text/javascript' src='/bags/common/tiddlers/chrjs.users'></script>
<script type='text/javascript' src='/bags/common/tiddlers/chrjs.identities'></script>
<script type='text/javascript' src='/bags/tiddlyspace/tiddlers/TiddlySpaceCSRF'></script>
<script type='text/javascript' src='/bags/common/tiddlers/jquery-form.js'></script>
<script type='text/javascript' src="/bags/common/tiddlers/siteiconupload.js"></script>
<script type='text/javascript' src="/bags/common/tiddlers/ts.js"></script>
<script type="text/javascript">
ts.init(function(ts) {
if(!ts.currentSpace) {
return;
}
var address = window.location.hostname.split(".");
var spaceName = address[0];
var publicBag = spaceName + "_public";
$("#siteUrl").text(window.location.hostname);
initSiteIconUpload(spaceName);
function countTiddlers(members) {
var numMembers = members ? members.length : false;
var publicBagUrl = "/bags/" + publicBag + "/tiddlers";
var url = members ? "/bags/" + spaceName + "_private/tiddlers" :
publicBagUrl;
$.ajax({ url: url, dataType: "text",
success: function(tiddlers) {
var numTiddlers = $.trim(tiddlers).split("\n").length;
var html = "";
function printFullInfo(numPublicTiddlers) {
var totalTiddlers = numPublicTiddlers + numTiddlers;
html += ['This space has ', numMembers,
' members, <a href="/tiddlers">', totalTiddlers,
' local tiddlers</a>, <a href="' + url + '">',
numTiddlers, ' are private</a> and <a href="',
publicBagUrl, '">',
numPublicTiddlers, ' public</a>.'].join("");
$("#info").html(html);
}
if(numMembers) {
$.ajax({
url: publicBagUrl,
dataType: "text",
success: function(tiddlers) {
printFullInfo($.trim(tiddlers).split("\n").length);
}
});
} else {
html += 'This space has <a href="' + url + '">' + numTiddlers + " public tiddlers</a>";
$("#info").html(html);
}
}
});
}
var space = new tiddlyweb.Space(spaceName, "/");
space.members().get(function(members) {
countTiddlers(members);
}, function() {
countTiddlers();
});
function complete(tiddler) {
$("#siteinfo .edit").show();
$("#siteinfo .value").data("tiddler", tiddler).
empty().html(tiddler.render);
}
function siteInfoEditor(tiddler) {
var errback = function() {
$("#siteinfo .edit").click();
$("<div class='error' />").text("Error occurred whilst saving.").prependTo("#siteinfo .value");
};
$("<button class='edit' />").click(function(ev) {
var editBtn = $(ev.target);
$(editBtn).hide();
var val = $(".value", $(ev.target).parent("#siteinfo")[0]);
var wikitext = $(val).data("tiddler").text;
var html = $(val).html();
$(val).empty();
$("<textarea />").val(wikitext).appendTo(val);
$("<button />").text("save").click(function(ev) {
var text = $("textarea", val).val();
$(val).empty().text("saving...");
tiddler.text = text;
tiddler.put(function() {
tiddler.get(function(tid) {
tiddler = tid;
complete(tid);
}, errback, "render=y");
}, errback);
$(editBtn).show();
}).appendTo(val);
$("<button />").text("cancel").
click(function(ev) {
complete(tiddler);
}).appendTo(val);
}).text("edit").appendTo("#siteinfo");
}
var tiddler = new tiddlyweb.Tiddler("SiteInfo", new tiddlyweb.Bag(publicBag, "/"));
$("<div class='value' />").text("(Loading SiteInfo tiddler)").data("tiddler", tiddler).appendTo("#siteinfo");
tiddler.get(
function(tid) {
tiddler = tid;
$("#siteinfo .value").data("tiddler", tid).html(tid.render || tid.text);
if($(document.body).hasClass("ts-member")) {
siteInfoEditor(tid);
}
},
function() {
$("#siteinfo .value").text("This space has not published any information about itself.");
if($(document.body).hasClass("ts-member")) {
siteInfoEditor(tiddler);
}
}, "render=1");
});
function toggleNext(ev) {
var label1 = "hide";
var label2 = "show";
var target = $(ev.target).parent().next();
var visible = $(ev.target).hasClass("open") ? true : false;
var label = visible ? label1 : label2;
$(target).stop(true, true);
if(!visible) {
$(target).slideDown(200);
$(ev.target).addClass("open").text(label1);
} else {
if($(target).parents().is(":hidden")) {
// see http://forum.jquery.com/topic/slideup-doesn-t-work-with-hidden-parent
$(target).hide();
} else {
$(target).slideUp(200);
}
$(ev.target).removeClass("open").text(label2);
}
}
// setup hide/show sliders
$(".toggleNext").each(function(i, el) {
$(el).addClass("open").click(toggleNext);
toggleNext({ target: el });
});
if(window != window.top) {
$("html").addClass("iframeMode");
$("a").live("click",function(ev) {
$(ev.target).attr("target", "_blank");
});
}
</script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
[[ViewTemplate]]
<!--{{{-->
<hr/>
<div class='answers' macro='tsScan fat:y template:"CommentTemplate##Template" hide:tiddlywikidev_public sort:modified'></div>
<!--}}}-->
The tabs macro creates an area where it displays one of several tiddlers alternately, as the user clicks on the tab labels at the top.
!Usage
{{{<<tabs ID Label1 Tip1 Tiddler1 Label2 Tip2 Tiddler2 [Label3 ...]>>}}}
* ID: specifies the name of a cookie used to save the information about which tab was displayed last.
* Label1, Label2, ... define the labels that are displayed at the top of the area for each tab
* Tip1, Tip2, ... define tooltips that explain, somewhat more verbosely than the labels, what you can expect to find on each tab.
* Tiddler1, Tiddler2, ... name the tiddlers that are displayed on each tab.
Obviously, there must be exactly three strings for each tab.
The syntax for the tabs macro looks like this:
{{{
<<tabs txt[cookieName]
"[label]" "[title]" [[tiddler]]
"[label]" "[title]" [[tiddler]]
...
>>
}}}
The //displayTiddler// method of the [[Story Class]] works the same way that the createTiddler method does, except that the newly-displayed tiddler is animated opening, and the browser window scrolls to display it. This method takes five parameters:
* the parent DOM element to display the tiddler inside (required but may be //null// if the tiddler already exists, or the special strings "bottom" and "top" to place the newly created tiddler at the bottom or top of the story)
* the title of the tiddler or a tiddler itself
* optionally the template to view the tiddler as. This should be either the constant //~DEFAULT_VIEW_TEMPLATE// or //~DEFAULT_EDIT_TEMPLATE//.
* optionally a boolean value indicating whether to animate opening the tiddler
* optionally a boolean value indicating whether to animate slowly. To see this in action, hold down the Shift, Option, or Alt key when clicking a tiddler link.
This method does not return any values.
{{{
//# Display a given tiddler with a given template. If the tiddler is already displayed but with a different
//# template, it is switched to the specified template. If the tiddler does not exist, and if server hosting
//# custom fields were provided, then an attempt is made to retrieve the tiddler from the server
//# srcElement - reference to element from which this one is being opened -or-
//# special positions "top", "bottom"
//# tiddler - tiddler or title of tiddler to display
//# template - the name of the tiddler containing the template -or-
//# one of the constants DEFAULT_VIEW_TEMPLATE and DEFAULT_EDIT_TEMPLATE -or-
//# null or undefined to indicate the current template if there is one, DEFAULT_VIEW_TEMPLATE if not
//# animate - whether to perform animations
//# customFields - an optional list of name:"value" pairs to be assigned as tiddler fields (for edit templates)
//# toggle - if true, causes the tiddler to be closed if it is already opened
//# animationSrc - optional. If provided, this will specify the element which is to act as the start of the animation -or-
//# the source of the animation will be the srcElement.
}}}
==Examples==
{{{
story.displayTiddler(null, "Title of an Existing Tiddler");
}}}
{{{
story.displayTiddler("bottom", "Title of Tiddler To Create", DEFAULT_EDIT_TEMPLATE);
}}}
By default TiddlyWiki will make backups with each 'Save Changes' in the right hand sidebar.
You can't save from the browser's internal File -> Save as.. (crl-s) dialog.
See: [[TiddlyWiki has been incorrectly saved]]
For limiting the number of backups there are different plugins available.
See: [[Backups]]
You can make copies of TiddlyWiki files from your file system too.
Quote: Eric (2007-09-24)|
This is supported by the core {{{<<newTiddler>>}}} macro, using a 'computed value' parameter to specify the initial text:
{{{
<<newTiddler text:{{store.getTiddlerText("DefaultContent","")}}>>
}}}
where "~DefaultContent" is a tiddler containing the initial text to use.
Also see [[Preloading]]
A link to a story consisting of a single tiddler or many tiddlers within a given TiddlyWiki.
For instance:
{{{
http://glossary.tiddlyspace.com/#[[Permalink]]%20[[TiddlySpace%20API]]
}}}
is a permalink of the story containing the tiddlers Permalink and ~TiddlySpace API.
/***
|''Name''|TiddlySpaceViewTypes|
|''Version''|0.5.6|
|''Status''|@@beta@@|
|''Description''|Provides TiddlySpace specific view types|
|''Author''|Jon Robson|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceViewTypes.js|
|''Requires''|TiddlySpaceConfig TiddlySpaceTiddlerIconsPlugin|
!Usage
Provides replyLink, spaceLink and SiteIcon view types.
!!SiteIcon view parameters
* labelPrefix / labelSuffix : prefix or suffix the label with additional text. eg. labelPrefix:'modified by '
* spaceLink: if set to "yes" will make any avatars link to the corresponding space. {{{<<originMacro spaceLink:yes>>}}}
!Code
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var originMacro = config.macros.tiddlerOrigin;
var tweb = config.extensions.tiddlyweb;
config.macros.view.replyLink = {
locale: {
label: "Reply to this tiddler"
}
};
config.macros.view.views.replyLink = function(value, place, params, wikifier,
paramString, tiddler) {
var valueField = params[0];
var imported;
if(valueField == "title") { // special casing for imported tiddlers
var localTitle = tiddler.title;
var serverTitle = tiddler.fields["server.title"];
if(serverTitle && localTitle != serverTitle) {
value = serverTitle ? serverTitle : localTitle;
imported = true;
}
} else {
title = tiddler[valueField] ? tiddler[valueField] : tiddler.fields[valueField];
}
var args = paramString.parseParams("anon")[0];
var label = (args.label) ? args.label : config.macros.view.replyLink.locale.label;
var space;
if(tiddler) {
var bag = tiddler.fields["server.bag"];
space = tiddlyspace.resolveSpaceName(bag);
}
var container = $('<span class="replyLink" />').appendTo(place)[0];
tweb.getUserInfo(function(user) {
if(!user.anon) {
if((space && user.name != space &&
user.name != tiddlyspace.currentSpace.name) || imported) {
createSpaceLink(container, user.name, value, label);
tweb.getStatus(function(status) { // force callback to run after existing callbacks
var url = config.extensions.tiddlyspace.getHost(status.server_host, user.name) + "#[[" + encodeURIComponent(value) + "]]";
jQuery("a", container).attr("href", url);
});
}
}
});
};
config.macros.view.views.spaceLink = function(value, place, params, wikifier,
paramString, tiddler) {
var spaceName = tiddlyspace.resolveSpaceName(value);
var isBag = params[0] == "server.bag" && value === spaceName ? true : false;
var args = paramString.parseParams("anon")[0];
var titleField = args.anon[2];
var labelField = args.labelField ? args.labelField[0] : false;
var label;
if(labelField) {
label = tiddler[labelField] ? tiddler[labelField] : tiddler.fields[labelField];
} else {
label = args.label ? args.label[0] : false;
}
var title = tiddler[titleField] ? tiddler[titleField] : tiddler.fields[titleField];
var link = createSpaceLink(place, spaceName, title, label, isBag);
if(args.external && args.external[0] == "no") {
$(link).click(function(ev) {
var el = $(ev.target);
var title = el.attr("tiddler");
var bag = el.attr("bag");
var space = el.attr("tiddlyspace");
bag = space ? space + "_public" : bag;
if(title && bag) {
ev.preventDefault();
tiddlyspace.displayServerTiddler(el[0], title,
"bags/" + bag);
}
return false;
});
}
};
config.macros.view.views.SiteIcon = function(value, place, params, wikifier,
paramString, tiddler) {
var options = originMacro.getOptions(paramString);
if(!tiddler || value == "None") { // some core tiddlers lack modifier
value = false;
}
var field = params[0];
if(field == "server.bag") {
options.notSpace = !originMacro._isSpace(value);
}
tiddlyspace.renderAvatar(place, value, options);
};
})(jQuery);
//}}}
TiddlyWiki is inherently flexible; with some basic knowledge of HTML and CSS, the entire layout can be easily adjusted.
All layout and style definitions are stored in [[Shadow Tiddler|shadow tiddlers]] by default, and can thus be modified from within the TiddlyWiki interface:
| ''Shadow Tiddler'' | ''Description'' |
|>| ''HTML Templates'' |
|[[PageTemplate]] |HTML code for the composition of the overall page design.|
|[[ViewTemplate]] |HTML code for the individual [[Tiddler]] layout |
|[[EditTemplate]] |HTML code for the tiddler editing mode |
|>| ''Style Sheets'' |
|[[StyleSheet]] |CSS code for custom user styles |
|[[StyleSheetColors]] |CSS code for default color style |
|[[StyleSheetLayout]] |CSS code for default layout styles |
|[[StyleSheetLocale]] |CSS code for locale-specific definitions |
|[[StyleSheetPrint]] |CSS code for default printing styles |
|[[ColorPalette]] |color scheme |
! See Also
* [[Getting started with custom tiddler fields|Custom Tiddler Fields]]: Arbitrary custom fields within tiddlers.
/***
|''Name''|TiddlySpaceCloneCommand|
|''Version''|0.5.7|
|''Description''|provides a toolbar command for cloning external tiddlers|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceCloneCommand.js|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Code
***/
//{{{
(function($) {
var cmd = config.commands;
var tiddlyspace = config.extensions.tiddlyspace;
var fieldsCache = {};
cmd.cloneTiddler = {
text: cmd.editTiddler.text,
tooltip: "Create a copy of this tiddler in the current space",
errorMsg: "Error publishing %0: %1",
isEnabled: function(tiddler) {
return !config.filterHelpers.is.local(tiddler) && !readOnly;
},
handler: function(ev, src, title) {
var tiddler = store.getTiddler(title);
if(tiddler) {
fieldsCache[title] = $.extend({}, tiddler.fields);
tiddler.fields["server.workspace"] = tiddlyspace.getCurrentWorkspace("private");
tiddler.fields["server.permissions"] = "read, write, create"; // no delete
delete tiddler.fields["server.page.revision"];
delete tiddler.fields["server.title"];
delete tiddler.fields["server.etag"];
// special handling for pseudo-shadow tiddlers
if(tiddlyspace.coreBags.contains(tiddler.fields["server.bag"])) {
tiddler.tags.remove("excludeLists");
}
} else { // ensure workspace is the current space
var el = story.findContainingTiddler(src);
el = $(el);
var fields = el.attr("tiddlyfields");
if(fields) { // inherited via TiddlyLink
fields = fields.decodeHashMap();
fields["server.workspace"] = config.
defaultCustomFields["server.workspace"];
} else {
fields = config.defaultCustomFields;
}
fields = String.encodeHashMap(fields);
el.attr("tiddlyfields", fields);
}
cmd.editTiddler.handler.apply(this, arguments);
if(tiddler) {
tiddler.fields["server.permissions"] += ", delete";
}
return false;
}
};
cmd.editTiddler.isEnabled = function(tiddler) {
return !cmd.cloneTiddler.isEnabled.apply(this, arguments);
};
// hijack cancelTiddler to restore original fields
var _cancelHandler = cmd.cancelTiddler.handler;
cmd.cancelTiddler.handler = function(ev, src, title) {
var tiddler = store.getTiddler(title);
if(tiddler) {
tiddler.fields = fieldsCache[title] || tiddler.fields;
delete fieldsCache[title];
}
return _cancelHandler.apply(this, arguments);
};
// hijack saveTiddler to clear unused fields stash
var _saveHandler = cmd.saveTiddler.handler;
cmd.saveTiddler.handler = function(ev, src, title) {
delete fieldsCache[title];
return _saveHandler.apply(this, arguments);
};
})(jQuery);
//}}}
!Best Practises
*collecting ideas for desirable structures and content of [[this wiki|Welcome]]@tiddlyspace
!List Perhaps Worth Reviewing
Referenced, yet not existing... <<tag excludeMissing>>
A WikiWord is a word composed of a bunch of other words slammed together with each of their first letters capitalised. WikiWord notation in a conventional WikiWikiWeb is used to name individual pages while TiddlyWiki uses WikiWord titles for smaller chunks of MicroContent. Referring to a page with a WikiWord automatically creates a link to it. Clicking on a link jumps to that page or, if it doesn't exist, to an editor to create it. It's also easy to have NonWikiWordLinks, and there's a WikiWordEscape for situations where you don't want a WikiWord to be interpreted as a link.
A [[WikiWord|http://en.wikipedia.org/wiki/CamelCase#Wiki_linking]] (also known as ''WikiLink'' or ''CamelCase'' word) is any word that starts with a capital letter and contains at least one more capital letter.
WikiWords are often formed by joining two or more capitalized words (e.g. "GettingStarted", "AboutThisSite").
In [[TiddlyWiki]], as well as in many other wiki engines, WikiWords are automatically considered to be links to other [[tiddlers]] or pages.
''Disabling [[WikiWords|WikiWord]]''
See [[How do I deactivate a wiki word?]]
<<tiddler Backstage##Tiddlers>>
The ''getParam()'' method is used to return the first value of a given parameter.
It takes 3 parameters:
* params - the parameters to be searched
* name - the name of the parameter you want the first value of
* defaultValue - the default value to return if no parameter of the given name can be found
{{{
createTiddlyLink(place,title,includeText,className,isStatic,linkedFromTiddler,noToggle)
}}}
The ''createTiddlyLink'' global function renders a link to an internal Web page. It requires two parameters:
; place
: the DOM element where the link will be placed.
; title
:
; includeText
: //(optional)//
; className
: //(optional)//
; isStatic
: //(optional)//
; linkedFromTiddler
: //(optional)//
; noToggle
: //(optional)//
The ''getShadowTiddlerText'' method of the [[Tiddlywiki Class]] allows you to retrieve the contents of a shadow tiddler. The returned ''string'' is not wikified so will be in it's raw wikitext format.
It takes one parameter, the tiddler of one of the shadow tiddlers. Such as:
{{{
store.getShadowTiddlerText("SiteSubtitle");
}}}
which returns:
{{{
"a reusable non-linear personal web notebook"
}}}
If you provide a name which doesn't exist or doesn't belong to a shadow tiddler this method will return an empty string. E.g.
{{{
""
}}}
/***
|''Name''|RefreshTiddlerCommand|
|''Version''|0.3.0|
***/
//{{{
(function($) {
var cmd = config.commands.refreshTiddler = {
text: "refresh",
locale: {
refreshing: "Refreshing tiddler..."
},
tooltip: "refresh this tiddler to be the one on the server",
handler: function(ev, src, title) {
var tiddler = store.getTiddler(title);
if(!tiddler) {
tiddler = new Tiddler(title);
merge(tiddler.fields, config.defaultCustomFields);
}
$(story.getTiddler(title)).find(".viewer").
empty().text(cmd.locale.refreshing);
var dirtyStatus = store.isDirty();
story.loadMissingTiddler(title, {
"server.workspace": tiddler.fields["server.recipe"] ? "recipes/" + tiddler.fields["server.recipe"] :
tiddler.fields["server.workspace"] || "bags/"+tiddler.fields["server.bag"],
"server.host": tiddler.fields["server.host"],
"server.type": tiddler.fields["server.type"]
}, function() {
store.setDirty(dirtyStatus);
});
}
};
})(jQuery);
//}}}
Text such as computer code that should be displayed without wiki processing and preserving line breaks:
{{{
Some plain text including WikiLinks
}}}
Displays as:
{{{
Some plain text including WikiLinks
}}}
!See Also
[[Suppressing Formatting]]
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
<!--{{{-->
<div macro='slideRevision'></div>
<div class='heading'>
<span class="titleBar">
<div class='title' macro='view title text'></div>
</span>
<span class='modifierIcon'
macro='view modifier SiteIcon label:no height:48 width:48 preserveAspectRatio:yes'>
</span>
<div class='toolbar'
macro='toolbar [[ToolbarCommands::RevisionToolbar]] icons:yes height:48 width:48 more:popup'>
</div>
<div class='tagClear'></div>
</div>
<div class='content'>
<div class='viewer' macro='view text wikified'></div>
</div>
<div class='tagInfo'>
<div class='tidTags' macro='tags'></div>
<div class='tagging' macro='tagging'></div>
</div>
<!--}}}-->
A ''getYearForWeekNo'' method has been added to the Date object. Any date object will be able to return the current year.
The function can be use like this:
//{{{
var date = new Date();
date.getYearForWeekNo();
//}}}
It would return {{{2011}}}.
With the [[ServerAdaptorMechanism]], TiddlyWiki adopts a simple model for interacting with servers:
* ''Server adaptors'' are plugins that provide a standardised interface to a particular server architecture. As standard, TiddlyWiki provides the FileAdaptor for talking to static TiddlyWiki files but others are available for talking to popular wiki servers
* A ''host'' string identifies a particular server, usually by it's URL
* A ''workspace'' string identifies a particular compartment or storage area within a server, for instance the name of a wiki on a shared MediaWiki server
* A ''title'' identifies a tiddler within a particular workspace
Via the [[ServerAdaptorExtendedFields]], particular tiddlers can have a connection to a particular server.
To generate a list of [[tags]] applied to the current [[tiddler]]:
{{{
<<tags [tiddler]>>
}}}
Note this will not display any tags that are themselves tagged excludeLists.
For instance if there is a tiddler called "foo" tagged excludeLists and the tags macro is run on a tiddler with the tag foo, this tag will not be displayed.
/***
|''Name''|ToggleTiddlerPrivacyPlugin|
|''Version''|0.7.0|
|''Status''|@@beta@@|
|''Description''|Allows you to set the privacy of new tiddlers and external tiddlers within an EditTemplate, and allows you to set a default privacy setting|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/ToggleTiddlerPrivacyPlugin.js|
!Notes
When used in conjunction with TiddlySpaceTiddlerIconsPlugin changing the privacy setting will also interact with any privacy icons.
Currently use of
{{{<<setPrivacy defaultValue:public>>}}} is in conflict with {{{<<newTiddler fields:"server.workspace:x_private">>}}}
There is an option, found in the tweak tab of the backstage, called txtPrivacyMode. Set this to either ''public'' or ''private'' depending on your security preference. If you choose not to set it then it will default to ''public''.
!Params
defaultValue:[private|public]
Allows you to set the default privacy value (Default is private)
!Code
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var macro = config.macros.setPrivacy = {
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
if(readOnly) {
return;
}
var el = $(story.findContainingTiddler(place));
var args = paramString.parseParams("name", null, true, false, true)[0];
var container = $("<div />").addClass("privacySettings").appendTo(place)[0];
var currentSpace = tiddlyspace.currentSpace.name;
var currentBag = tiddler ? tiddler.fields["server.bag"] : false;
var isNewTiddler = el.hasClass("missing") || !currentBag; // XXX: is this reliable?
var status = tiddlyspace.getTiddlerStatusType(tiddler);
var customFields = el.attr("tiddlyfields");
customFields = customFields ? customFields.decodeHashMap() : {};
if(isNewTiddler || !["public", "private", "unsyncedPrivate", "unsyncedPublic"].contains(status)) {
var defaultValue = "public";
if(args.defaultValue) {
defaultValue = args.defaultValue[0].toLowerCase();
} else {
defaultValue = config.options.chkPrivateMode ? "private" : "public";
}
defaultValue = defaultValue ?
"%0_%1".format(currentSpace, defaultValue) : customFields["server.bag"];
var options = config.macros.tiddlerOrigin ?
config.macros.tiddlerOrigin.getOptions(paramString) : {};
this.createRoundel(container, tiddler, currentSpace, defaultValue, options);
}
},
updateEditFields: function(tiddlerEl, bag) {
var saveBagField = $('[edit="server.bag"]', tiddlerEl);
var saveWorkspaceField = $('[edit="server.workspace"]', tiddlerEl);
var input = $("<input />").attr("type", "hidden");
if(saveBagField.length === 0) {
input.clone().attr("edit", "server.bag").val(bag).appendTo(tiddlerEl);
} else {
saveBagField.val(bag);
}
$(tiddlerEl).attr("tiddlyFields", ""); // reset to prevent side effects
var workspace = "bags/" + bag;
if(saveWorkspaceField.length === 0) {
input.clone().attr("edit", "server.workspace").val(workspace).appendTo(tiddlerEl);
} else {
saveWorkspaceField.val(workspace);
}
},
setBag: function(tiddlerEl, newBag, options) {
var title = $(tiddlerEl).attr("tiddler");
var tiddler = store.getTiddler(title);
var originButton = $(".originButton", tiddlerEl)[0];
var refreshIcon = function(type) {
var originMacro = config.macros.tiddlerOrigin;
if(originButton && originMacro) {
options.noclick = true;
originMacro.showPrivacyRoundel(tiddler, type, originButton, options);
}
};
macro.updateEditFields(tiddlerEl, newBag);
var newWorkspace = "bags/" + newBag;
if(tiddler) {
tiddler.fields["server.bag"] = newBag;
tiddler.fields["server.workspace"] = newWorkspace; // for external tiddlers
}
var rPrivate = $("input[type=radio].isPrivate", tiddlerEl);
var rPublic = $("input[type=radio].isPublic", tiddlerEl);
if(newBag.indexOf("_public") > -1) {
rPrivate.attr("checked", false);
rPublic.attr("checked", true);
status = "public";
} else {
rPublic.attr("checked", false); // explicitly do this for ie
rPrivate.attr("checked", true);
status = "private";
}
refreshIcon(status);
},
createRoundel: function(container, tiddler, currentSpace, defaultValue, options) {
var privateBag = "%0_private".format(currentSpace);
var publicBag = "%0_public".format(currentSpace);
var rbtn = $("<input />").attr("type", "radio").attr("name", tiddler.title);
var rPrivate = rbtn.clone().val("private").addClass("isPrivate").appendTo(container);
$("<label />").text("private").appendTo(container); // TODO: i18n
var rPublic = rbtn.clone().val("public").addClass("isPublic").appendTo(container);
$("<label />").text("public").appendTo(container); // TODO: i18n
var el = story.findContainingTiddler(container);
$("[type=radio]", container).click(function(ev) {
var btn = $(ev.target);
tiddler.fields["server.page.revision"] = "false";
if(btn.hasClass("isPrivate")) { // private button clicked.
$(el).addClass("isPrivate").removeClass("isPublic");
macro.setBag(el, privateBag, options);
} else {
$(el).addClass("isPublic").removeClass("isPrivate");
macro.setBag(el, publicBag, options);
}
});
window.setTimeout(function() {
macro.setBag(el, defaultValue, options);
}, 100);
// annoyingly this is needed as customFields are added to end of EditTemplate so are not present yet
// and don't seem to respect any existing customFields.
}
};
})(jQuery);
//}}}
The ''tiddlerExists'' method of a [[TiddlyWiki class|TiddlyWiki]] object returns whether a tiddler exists in the TiddlyWiki. If a shadow tiddler exists for the title, it will return true. This method expects one parameter: the title of the tiddler.
It is used like so:
{{{
// store is the TiddlyWiki class
store.tiddlerExists('TiddlerExists');
}}}
Which returns {{{"true"}}}
The ''removeTiddler'' method of a [[TiddlyWiki|TiddlyWiki class]] object removes a tiddler from the TiddlyWiki. It takes one parameter: the name of the tiddler to delete. E.g.
{{{
store.removeTiddler('TiddlerTitle');
}}}
It wil notify the functions set as listeners with [[addNotification|TiddlyWiki.prototype.addNotification]] and set the dirty flag.
Note: If the tiddler does not exist it returns silently.
{{{
[element =]createTiddlyElement(parent,element[,id[, className[,text[,attribs]]]])
}}}
The global function ''createTiddlyElement'' creates a DOM element. This function takes five parameters:
; parent
: the parent DOM element to add the new element to
; element
: the type of element to create. This is a lowercase string matching the name of the HTML tag you'd like to create -- so, for example, to create a div element, you'd pass 'div'.
; id
: the DOM id to give the element.
; className
: the CSS class to give the element.
; text
: text to put inside the element.
Any of these parameters may be null. This function returns the created DOM element.
/***
|''Name''|TiddlyWebAdaptor|
|''Description''|adaptor for interacting with TiddlyWeb|
|''Author:''|FND|
|''Contributors''|Chris Dent, Martin Budden|
|''Version''|1.4.10|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
|''Keywords''|serverSide TiddlyWeb|
!Notes
This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]].
!To Do
* createWorkspace
* document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin)
!Code
***/
//{{{
(function($) {
var adaptor = config.adaptors.tiddlyweb = function() {};
adaptor.prototype = new AdaptorBase();
adaptor.serverType = "tiddlyweb";
adaptor.serverLabel = "TiddlyWeb";
adaptor.mimeType = "application/json";
adaptor.parsingErrorMessage = "Error parsing result from server";
adaptor.noBagErrorMessage = "no bag specified for tiddler";
adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename
// retrieve current status (requires TiddlyWeb status plugin)
adaptor.prototype.getStatus = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/status";
var uri = uriTemplate.format([context.host]);
var req = httpReq("GET", uri, adaptor.getStatusCallback, context,
null, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) {
context.status = responseText ? status : false;
try {
context.statusText = xhr.statusText;
} catch(exc) { // offline (Firefox)
context.status = false;
context.statusText = null;
}
context.httpStatus = xhr.status;
if(context.status) {
context.serverStatus = $.evalJSON(responseText); // XXX: error handling!?
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve a list of workspaces
adaptor.prototype.getWorkspaceList = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.workspaces = [];
var uriTemplate = "%0/recipes"; // XXX: bags?
var uri = uriTemplate.format([context.host]);
var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback,
context, { accept: adaptor.mimeType }, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
try {
var workspaces = $.evalJSON(responseText);
} catch(ex) {
context.status = false; // XXX: correct?
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
context.workspaces = workspaces.map(function(itm) { return { title: itm }; });
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve a list of tiddlers
adaptor.prototype.getTiddlerList = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/%1/%2/tiddlers%3";
var params = context.filters ? "?" + context.filters : "";
if(context.format) {
params = context.format + params;
}
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), params]);
var req = httpReq("GET", uri, adaptor.getTiddlerListCallback,
context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
context.tiddlers = [];
try {
var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
} catch(ex) {
context.status = false; // XXX: correct?
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
context.tiddlers.push(tiddler);
}
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// perform global search
adaptor.prototype.getSearchResults = function(context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/search?q=%1%2";
var filterString = context.filters ? ";" + context.filters : "";
var uri = uriTemplate.format([context.host, context.query, filterString]); // XXX: parameters need escaping?
var req = httpReq("GET", uri, adaptor.getSearchResultsCallback,
context, { accept: adaptor.mimeType }, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getSearchResultsCallback = function(status, context, responseText, uri, xhr) {
adaptor.getTiddlerListCallback(status, context, responseText, uri, xhr); // XXX: use apply?
};
// retrieve a particular tiddler's revisions
adaptor.prototype.getTiddlerRevisionList = function(title, limit, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
var req = httpReq("GET", uri, adaptor.getTiddlerRevisionListCallback,
context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerRevisionListCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
context.revisions = [];
try {
var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
} catch(ex) {
context.status = false; // XXX: correct?
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
context.revisions.push(tiddler);
}
var sortField = "server.page.revision";
context.revisions.sort(function(a, b) {
return a.fields[sortField] < b.fields[sortField] ? 1 :
(a.fields[sortField] == b.fields[sortField] ? 0 : -1);
});
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve an individual tiddler revision -- XXX: breaks with standard arguments list -- XXX: convenience function; simply use getTiddler?
adaptor.prototype.getTiddlerRevision = function(title, revision, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.revision = revision;
return this.getTiddler(title, context, userParams, callback);
};
// retrieve an individual tiddler
//# context is an object with members host and workspace
//# callback is passed the new context and userParams
adaptor.prototype.getTiddler = function(title, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = title;
if(context.revision) {
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions/%4";
} else {
uriTemplate = "%0/%1/%2/tiddlers/%3";
}
if(!context.tiddler) {
context.tiddler = new Tiddler(title);
}
context.tiddler.fields["server.type"] = adaptor.serverType;
context.tiddler.fields["server.host"] = AdaptorBase.minHostName(context.host);
context.tiddler.fields["server.workspace"] = context.workspace;
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title),
context.revision]);
var req = httpReq("GET", uri, adaptor.getTiddlerCallback, context,
merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
try {
var tid = $.evalJSON(responseText);
} catch(ex) {
context.status = false;
context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
if(context.callback) {
context.callback(context, context.userParams);
}
return;
}
var tiddler = adaptor.toTiddler(tid, context.host);
tiddler.title = context.tiddler.title;
tiddler.fields["server.etag"] = xhr.getResponseHeader("Etag");
// normally we'd assign context.tiddler = tiddler here - but we can't do
// that because of IE, which triggers getTiddler in putTiddlerCallback,
// and since ServerSideSavingPlugin foolishly relies on persistent
// object references, we need to merge the data into the existing object
$.extend(context.tiddler, tiddler);
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// retrieve tiddler chronicle (all revisions)
adaptor.prototype.getTiddlerChronicle = function(title, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = title;
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions?fat=1";
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
var req = httpReq("GET", uri, adaptor.getTiddlerChronicleCallback,
context, { accept: adaptor.mimeType }, null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(status) {
context.responseText = responseText;
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// store an individual tiddler
adaptor.prototype.putTiddler = function(tiddler, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = tiddler.title;
context.tiddler = tiddler;
context.host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var uriTemplate = "%0/%1/%2/tiddlers/%3";
try {
context.workspace = context.workspace || tiddler.fields["server.workspace"];
var workspace = adaptor.resolveWorkspace(context.workspace);
} catch(ex) {
return adaptor.locationIDErrorMessage;
}
var uri = uriTemplate.format([context.host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(tiddler.title)]);
var etag = adaptor.generateETag(workspace, tiddler);
var headers = etag ? { "If-Match": etag } : null;
var payload = {
type: tiddler.fields["server.content-type"] || null,
text: tiddler.text,
tags: tiddler.tags,
fields: $.extend({}, tiddler.fields)
};
delete payload.fields.changecount;
$.each(payload.fields, function(key, value) {
if(key.indexOf("server.") == 0) {
delete payload.fields[key];
}
});
payload = $.toJSON(payload);
var req = httpReq("PUT", uri, adaptor.putTiddlerCallback,
context, headers, payload, adaptor.mimeType, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.putTiddlerCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.status) {
var loc = xhr.getResponseHeader("Location");
var etag = xhr.getResponseHeader("Etag");
if(loc && etag) {
var bag = loc.split("/bags/").pop().split("/")[0];
context.tiddler.fields["server.bag"] = bag;
context.tiddler.fields["server.workspace"] = "bags/" + bag;
var rev = etag.split("/").pop().split(/;|:/)[0];
context.tiddler.fields["server.page.revision"] = rev;
context.tiddler.fields["server.etag"] = etag;
if(context.callback) {
context.callback(context, context.userParams);
}
} else { // IE
context.adaptor.getTiddler(context.tiddler.title, context,
context.userParams, context.callback);
}
} else if(context.callback) {
context.callback(context, context.userParams);
}
};
// store a tiddler chronicle
adaptor.prototype.putTiddlerChronicle = function(revisions, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = revisions[0].title;
var headers = null;
var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(context.title)]);
if(workspace.type == "bag") { // generate ETag
var etag = [adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(context.title), 0].join("/"); //# zero-revision prevents overwriting existing contents
headers = { "If-Match": '"' + etag + '"' };
}
var payload = $.toJSON(revisions);
var req = httpReq("POST", uri, adaptor.putTiddlerChronicleCallback,
context, headers, payload, adaptor.mimeType, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.putTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.callback) {
context.callback(context, context.userParams);
}
};
// store a collection of tiddlers (import TiddlyWiki HTML store)
adaptor.prototype.putTiddlerStore = function(store, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
var uriTemplate = "%0/%1/%2/tiddlers";
var host = context.host;
var workspace = adaptor.resolveWorkspace(context.workspace);
var uri = uriTemplate.format([host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name)]);
var req = httpReq("POST", uri, adaptor.putTiddlerStoreCallback,
context, null, store, "text/x-tiddlywiki", null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.putTiddlerStoreCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.callback) {
context.callback(context, context.userParams);
}
};
// rename an individual tiddler or move it to a different workspace -- TODO: make {from|to}.title optional
//# from and to are objects with members title and workspace (bag; optional),
//# representing source and target tiddler, respectively
adaptor.prototype.moveTiddler = function(from, to, context, userParams, callback) { // XXX: rename parameters (old/new)?
var self = this;
var newTiddler = store.getTiddler(from.title) || store.getTiddler(to.title); //# local rename might already have occurred
var oldTiddler = $.extend(true, {}, newTiddler); //# required for eventual deletion
oldTiddler.title = from.title; //# required for original tiddler's ETag
var _getTiddlerChronicle = function(title, context, userParams, callback) {
return self.getTiddlerChronicle(title, context, userParams, callback);
};
var _putTiddlerChronicle = function(context, userParams) {
if(!context.status) {
return callback(context, userParams);
}
var revisions = $.evalJSON(context.responseText); // XXX: error handling?
// change current title while retaining previous location
for(var i = 0; i < revisions.length; i++) {
delete revisions[i].revision;
if(!revisions[i].fields.origin) { // NB: origin = "<workspace>/<title>"
revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/");
}
revisions[i].title = to.title;
}
// add new revision
var rev = $.extend({}, revisions[0]);
$.each(newTiddler, function(i, item) {
if(!$.isFunction(item)) {
rev[i] = item;
}
});
rev.title = to.title;
rev.created = rev.created.convertToYYYYMMDDHHMM();
rev.modified = new Date().convertToYYYYMMDDHHMM();
delete rev.fields.changecount;
revisions.unshift(rev);
if(to.workspace) {
context.workspace = to.workspace;
} else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag
context.workspace = "bags/" + rev.bag;
}
var subCallback = function(context, userParams) {
if(!context.status) {
return callback(context, userParams);
}
context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler);
};
return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback);
};
var _deleteTiddler = function(context, userParams) {
if(!context.status) {
return callback(context, userParams);
}
$.extend(true, newTiddler, context.tiddler);
context.callback = null;
return self.deleteTiddler(oldTiddler, context, context.userParams, callback);
};
callback = callback || function() {};
context = this.setContext(context, userParams);
context.host = context.host || oldTiddler.fields["server.host"];
context.workspace = from.workspace || oldTiddler.fields["server.workspace"];
return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle);
};
// delete an individual tiddler
adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = tiddler.title; // XXX: not required!?
var uriTemplate = "%0/bags/%1/tiddlers/%2";
var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var bag = tiddler.fields["server.bag"];
if(!bag) {
return adaptor.noBagErrorMessage;
}
var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag),
adaptor.normalizeTitle(tiddler.title)]);
var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler);
var headers = etag ? { "If-Match": etag } : null;
var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers,
null, null, null, null, true);
return typeof req == "string" ? req : true;
};
adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) {
context.status = [204, 1223].contains(xhr.status);
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
if(context.callback) {
context.callback(context, context.userParams);
}
};
// compare two revisions of a tiddler (requires TiddlyWeb differ plugin)
//# if context.rev1 is not specified, the latest revision will be used for comparison
//# if context.rev2 is not specified, the local revision will be sent for comparison
//# context.format is a string as determined by the TiddlyWeb differ plugin
adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) {
context = this.setContext(context, userParams, callback);
context.title = title;
var tiddler = store.getTiddler(title);
try {
var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
} catch(ex) {
return adaptor.locationIDErrorMessage;
}
var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/");
var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef;
var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null;
var uriTemplate = "%0/diff?rev1=%1";
if(rev2) {
uriTemplate += "&rev2=%2";
}
if(context.format) {
uriTemplate += "&format=%3";
}
var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1),
adaptor.normalizeTitle(rev2), context.format]);
if(rev2) {
var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null,
null, null, null, null, true);
} else {
var payload = {
title: tiddler.title,
text: tiddler.text,
modifier: tiddler.modifier,
tags: tiddler.tags,
fields: $.extend({}, tiddler.fields)
}; // XXX: missing attributes!?
payload = $.toJSON(payload);
req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context,
null, payload, adaptor.mimeType, null, null, true);
}
return typeof req == "string" ? req : true;
};
adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) {
context.status = status;
context.statusText = xhr.statusText;
context.httpStatus = xhr.status;
context.uri = uri;
if(status) {
context.diff = responseText;
}
if(context.callback) {
context.callback(context, context.userParams);
}
};
// generate tiddler information
adaptor.prototype.generateTiddlerInfo = function(tiddler) {
var info = {};
var uriTemplate = "%0/%1/%2/tiddlers/%3";
var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete?
host = this.fullHostName(host);
var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
info.uri = uriTemplate.format([host, workspace.type + "s",
adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(tiddler.title)]);
return info;
};
// create Tiddler instance from TiddlyWeb tiddler JSON
adaptor.toTiddler = function(json, host) {
var created = Date.convertFromYYYYMMDDHHMM(json.created);
var modified = Date.convertFromYYYYMMDDHHMM(json.modified);
var fields = json.fields;
fields["server.type"] = adaptor.serverType;
fields["server.host"] = AdaptorBase.minHostName(host);
fields["server.bag"] = json.bag;
fields["server.title"] = json.title;
if(json.recipe) {
fields["server.recipe"] = json.recipe;
}
if(json.type && json.type != "None") {
fields["server.content-type"] = json.type;
}
fields["server.permissions"] = json.permissions.join(", ");
fields["server.page.revision"] = json.revision;
fields["server.workspace"] = "bags/" + json.bag;
var tiddler = new Tiddler(json.title);
tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags,
created, json.fields, json.creator);
return tiddler;
};
adaptor.resolveWorkspace = function(workspace) {
var components = workspace.split("/");
return {
type: components[0] == "bags" ? "bag" : "recipe",
name: components[1] || components[0]
};
};
adaptor.generateETag = function(workspace, tiddler) {
var revision = tiddler.fields["server.page.revision"];
var etag = revision == "false" ? null : tiddler.fields["server.etag"];
if(!etag && workspace.type == "bag") {
if(typeof revision == "undefined") {
revision = "0";
} else if(revision == "false") {
return null;
}
etag = [adaptor.normalizeTitle(workspace.name),
adaptor.normalizeTitle(tiddler.title), revision].join("/");
etag = '"' + etag + '"';
}
return etag;
};
adaptor.normalizeTitle = function(title) {
return encodeURIComponent(title);
};
})(jQuery);
/*
* jQuery JSON Plugin
* version: 1.3
* source: http://code.google.com/p/jquery-json/
* license: MIT (http://www.opensource.org/licenses/mit-license.php)
*/
(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return this.getUTCFullYear()+'-'+
toIntegersAtLease(this.getUTCMonth())+'-'+
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};$.toJSON=function(o,compact)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
if(compact)
return"["+ret.join(",")+"]";else
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
if(compact)
ret.push(name+":"+val);else
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o)
{return $.toJSON(o,true);};$.evalJSON=function(src)
{return eval("("+src+")");};$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery);
//}}}
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
The [[suspendNotifications|TiddlyWiki.prototype.suspendNotifications]] method of a [[TiddlyWiki class|TiddlyWiki]] object suspends notifications from being issued by the [[notify|TiddlyWiki.prototype.notify]] and [[notifyAll|TiddlyWiki.prototype.notifyAll]] methods. The [[resumeNotifications|TiddlyWiki.prototype.resumeNotifications]] method must be called in order to resume notifications.
This method takes no parameters. It may be called multiple times; [[resumeNotifications|TiddlyWiki.prototype.resumeNotifications]] must be called an equal number of times in order for notifications to be issued.
[[ColorPalette|ColorPalette shadows]]
[[DefaultTiddlers|DefaultTiddlers shadows]]
[[EditTemplate|EditTemplate shadows]]
[[GettingStarted|GettingStarted shadows]]
[[MainMenu|MainMenu shadows]]
[[PageTemplate|PageTemplate shadows]]
[[PluginManager|PluginManager shadows]]
[[SideBarOptions|SideBarOptions shadows]]
[[SiteSubtitle|SiteSubtitle shadows]]
[[SiteTitle|SiteTitle shadows]]
[[StyleSheet|StyleSheet shadows]]
[[TabAll|TabAll shadows]]
[[TabMoreMissing|TabMoreMissing shadows]]
[[TabMoreOrphans|TabMoreOrphans shadows]]
[[TabMoreShadowed|TabMoreShadowed shadows]]
[[TabTimeline|TabTimeline shadows]]
[[ViewTemplate|ViewTemplate shadows]]
[[WindowTitle|WindowTitle shadows]]
Adding another [[user|User]] as a [[member|Member]] of a [[space|Space]] makes them a peer of the space, and grants him the same privileges, as well as being able to [[create|New Tiddler]], [[edit|Edit Tiddler]], [[delete|Delete Tiddler]] and [[publish|Publish]] content, as a member they are able to [[add|Add Member]] and [[remove|Remove Member]] [[members|Member]] from the [[space|Space]].
This is analogous to cutting a key and giving it to a house guest. He may turn change the locks and lock you out, but that's unlikely to happen with people you invite into your home.
/*{{{*/
.tiddler .originButton div {
display: inline-block;
}
.tiddler .spaceSiteIcon .siteIcon {
_display: inline; /* IE doesn't like inline-block */
}
.tiddler .originButton {
display: block;
}
.selected .tagging,
.selected .tagging:hover {
border: none;
background: none;
}
.tagging {
float: none;
background: none;
border: none;
}
.tagging li.listTitle {
margin-left: 0px;
}
.tagging li {
margin: 0 8px;
}
.tagging .tiddlyLink {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
padding: 1px 2px;
line-height: 1.2em;
}
/* for following */
#popup .siteIcon {
float: left;
height: 25px;
}
.content {
width: 100%; /* IE */
font-size: 0.9em;
}
.editorHeading {
height: 48px;
}
.heading {
left: 0;
margin-bottom: 40px;
position: relative;
top: 32px;
}
.followButton a {
display: block;
margin-top: -20px;
}
.tiddler .followPlaceHolder {
display: block;
position: absolute;
top: 16px;
right: 64px;
_right: 138px; // add width of modifierIcon
}
.tiddler .followButton {
position: relative;
height: 24px;
text-align: left;
color: #fff;
background: [[ColorPalette::PrimaryMid]];
padding: 10px 0px 0px 10px;
width: 38px;
margin: -16px -8px 24px 0;
}
/* creates the larger triangle */
.followButton:before {
content: "\00a0";
display: block; /* reduce the damage in FF3.0 */
position: relative;
bottom: -20px;
right: 0;
width: 0;
height: 0;
border-width: 0 0 20px 20px;
border-style: solid;
border-color: transparent [[ColorPalette::PrimaryMid]];
}
.toolbar svg {
height: 16px;
width: 16px;
}
.toolbar svg .glyph {
fill: #ccc;
}
.toolbar a:hover .glyph {
fill: black;
}
.toolbar a:active .glyph {
fill: [[ColorPalette::Background]];
}
.originButton,
.followPlaceHolder,
.tiddler .subtitle {
cursor: pointer;
}
.editSpaceSiteIcon .originButton {
cursor: auto;
}
.tiddler .subtitle:hover {
font-weight: bold;
background: none;
}
.originButton img,
.originButton svg {
margin-left: 0px;
}
.modifierIcon {
position: absolute;
width: 74px;
top: 0px;
right: 0px;
_right: 74px; /* in IE6 positioning works incorrectly so use -width instead */
text-align: right;
}
.modifierIcon img,
.modifierIcon svg {
margin-right: 8px;
}
.tiddler .viewer {
padding-bottom: 16px;
margin: 0 0 0 56px;
line-height: 1.4em;
}
.viewer pre {
margin-left: 0;
}
.siteIcon .label {
color: [[ColorPalette::TertiaryDark]];
}
.tiddler .spaceSiteIcon {
float: left;
margin-right: 0;
margin-top: 0;
position: relative;
display: block;
}
.tiddler .titleBar {
display: block;
margin-right: 136px;
margin-left: 56px;
}
.followButton a {
color: [[ColorPalette::Background]];
}
.tiddler {
position: relative;
padding: 0;
margin-bottom: 3em;
border-top: 3px solid [[ColorPalette::PrimaryMid]];
background: #fff;
}
.tiddler .editor {
padding: 0px 8px;
}
.tiddler .heading .title {
position: relative;
display: block;
word-wrap: break-word;
font-size: 32px;
line-height: 32px;
}
.tiddler .heading .editor.title {
font-size: 1.7em;
line-height: normal;
}
.tiddler .headingClear {
clear: both;
}
.tiddler .subtitle {
font-style: italic;
font-size: 0.9em;
color: #a6a59e;
margin-top: 0;
}
.toolbar {
position: absolute;
padding: 0;
top: 8px;
right: -8px;
}
.toolbar .moreCommand.highlight {
background: none;
}
.tiddler .toolbar .button {
border: none;
display: inline;
padding: 0px;
margin-right: 16px;
}
.tiddler .toolbar a:hover {
background: none;
}
.tiddler .tagged .listTitle {
display: none;
}
.revButton {
float: right;
}
/*! EditTemplate specific*/
.tiddler .privacySettings {
text-align: center;
}
.tiddler .privacySettings .originButton {
display: inline;
}
.editSpaceSiteIcon, .privacyEdit {
float: left;
}
.editSpaceSiteIcon svg,
.editSpaceSiteIcon img,
.editSpaceSiteIcon .roundelLabel {
float: left;
}
.tagTitle {
position: absolute;
text-align: center;
width: 48px;
top: 0px;
left: -56px;
}
.editSpaceSiteIcon .originButton img,
.editSpaceSiteIcon .originButton svg {
height: 16px;
margin-left: 24px;
margin-right: 32px;
width: 16px;
}
.tagAnnotation {
margin-top: 8px;
padding-bottom: 8px;
}
.annotationsBox {
margin-top: 8px;
}
.editorFooter {
position: relative;
padding: 0;
margin-top: 16px;
margin-left: 64px;
}
.tiddler .editorFooter .editor {
padding-left: 0px;
}
.heading .editor input {
width: 100%;
font-size: 1.5em;
}
.spaceSiteIcon .externalImage .image a:hover,
.modifierIcon .externalImage .image a:hover {
background: none;
}
div.toolbar {
visibility:hidden;
right:-16px;
}
.selected div.toolbar {
visibility: visible;
}
.followButton a:hover {
background: [[ColorPalette::PrimaryMid]];
text-decoration: underline;
}
a.image:hover {
background: transparent;
}
@media all and (max-device-width: 480px) {
div.toolbar {
visibility:visible;
}
}
@media only screen and (device-width: 768px) {
div.toolbar {
visibility:visible;
}
}
@media all and (max-width: 960px) {
.tiddler .titleBar {
margin-left: 36px;
margin-right: 80px;
}
.tiddler .heading {
margin-bottom: 48px;
}
.tiddler .heading .title {
font-size: 32px;
line-height: 32px;
}
.tiddler .modifierIcon img,
.tiddler .modifierIcon svg,
.tiddler .spaceSiteIcon .originButton img,
.originButton svg {
width: 32px;
height: 32px;
margin-left: 0px;
margin-right: 0px;
}
.tiddler .followPlaceHolder {
right: 48px;
}
.tiddler .followButton {
width: 24px;
}
.tiddler .viewer {
margin: 0px 0px 0px 36px;
padding-top: 0;
}
br {
line-height: 0.5em;
}
}
/*}}}*/
The [[SiteIcon]] tiddler is a special tiddler that determines the logo of any given space.
The SiteIcon will typically be displayed at 48px by 48px and can be an image or an svg file.
To upload a SiteIcon you can use the binaryUpload macro specifying the title as SiteIcon.
{{{<<binaryUpload edit:title>>}}} .
Wiki markup rules can be suppressed for any given section of text by enclosing it in 3 ''double'' quotes:
{{{
"""//WikiWord//"""
}}}
Displays as:
"""//WikiWord//"""
WikiWords can also be suppressed by prefixing the WikiWord with ''~'':
{{{
~WikiWord
}}}
Displays as:
~WikiWord
!!Also See
[[Code formatting]]
A tiddler is often opened using the [[displayTiddler()]] method of the ''Story'' object.
When opened, the TW core creates and inserts a DOM element. This element is given an ''id'' comprising of the prefix ''tiddler'' and the ''tiddler title'', such as {{{tiddlerSiteTitle}}}.
The tiddler is opened in a HTML element. The ''Story'' object, by default, uses an element that has it's id set to ''tidderDisplay''.
All tiddlers you currently have open will be contained in the ''#tiddlyDisplay'' element.
The core renders the ViewTemplate (HTML syntax) into that DOM element, and then processes any special extended TW syntax defined within that template. An example of this extended TW syntax would be
{{{
<div class='title' macro='view title text'></div>
}}}
which enables TW to retrieve and display the title of the tiddler. [[Read more about how TW handles this extended syntax|Extended HTML Syntax Handling]]
After handling the extended HTML syntax and rendering the output within the #tiddlerTiddlerTitle element the process of opening a tiddler is complete.
Almost everything in [[TiddlyWiki]] is controlled via [[Tiddlers|Tiddler]].
* [[Tiddlers|Tiddler]]
* [[HTML Templates]]
* [[Style Sheets]]
* [[Macros]]
* [[Plugins]]
* [[Cookies]] (used for storing certain user options)
A ''getWeek'' method has been added to the Date object. Any date object can return it's week number (between 1 and 52).
The function can be use like this:
//{{{
var date = new Date(); // Mon Feb 07 2011 23:35:42 GMT+0100 (CET) {}
date.getWeek(); // 6
//}}}
The ''createTiddler'' method of a [[TiddlyWiki class|TiddlyWiki]] object instantiates a [[Tiddler class|Tiddler]] object. It takes one parameter, which is the title of the tiddler requested. If a tiddler hasn't previously been created by the author, an empty Tiddler object is returned.
This method does not link the Tiddler in any way to the TiddlyWiki. See [[TiddlyWiki.prototype.saveTiddler]].
See [[SiteInfo]] for details on how to install.
HTML entities can be used to easily type special characters:
{{{
Here is a quote symbol: "
And a pound sign: £
}}}
Displays as:
Here is a quote symbol: "
And a pound sign: £
!Notes
For a full list of available HTML references see:
http://www.w3schools.com/tags/ref_entities.asp
/***
|''Name''|TiddlySpacePublishingCommands|
|''Version''|0.8.5|
|''Status''|@@beta@@|
|''Description''|toolbar commands for drafting and publishing|
|''Author''|Jon Robson|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpacePublishingCommands.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Usage
Provides changeToPrivate, changeToPublic and saveDraft commands
Provides TiddlySpacePublisher macro.
{{{<<TiddlySpacePublisher type:private>>}}} make lots of private tiddlers public.
{{{<<TiddlySpacePublisher type:public>>}}} make lots of public tiddlers public.
!TODO
* add public argument?
!Code
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var originMacro = config.macros.tiddlerOrigin;
tiddlyspace.getTiddlerStatusType = function(tiddler) {
var isShadow = store.isShadowTiddler(tiddler.title);
var exists = store.tiddlerExists(tiddler.title);
if(isShadow && !exists) {
return "shadow";
} else if(!exists) {
return "missing";
} else {
var types = ["private", "public"];
var type = "external";
for(var i = 0; i < types.length; i++) {
var t = types[i];
type = config.filterHelpers.is[t](tiddler) ? t : type;
}
if(config.filterHelpers.is.unsynced(tiddler)) {
type = type == "private" ? "unsyncedPrivate" : "unsyncedPublic";
}
return type;
}
};
var cmd = config.commands.publishTiddler = {
text: "make public",
tooltip: "Change this private tiddler into a public tiddler",
errorMsg: "Error publishing %0: %1",
isEnabled: function(tiddler) {
return !readOnly && config.filterHelpers.is["private"](tiddler);
},
handler: function(ev, src, title) {
var tiddler = store.getTiddler(title);
if(tiddler) {
var newBag = cmd.toggleBag(tiddler.fields["server.bag"]);
this.moveTiddler(tiddler, {
title: tiddler.fields["publish.name"] || tiddler.title,
fields: { "server.bag": newBag }
});
}
},
toggleBag: function(bag, to) {
var newBag;
if(typeof bag != typeof "") {
var tiddler = bag;
bag = tiddler.fields["server.bag"];
}
if(bag.indexOf("_private") > -1) { // should make use of endsWith
to = to ? to : "public";
newBag = bag.replace("_private", "_" + to);
} else {
to = to ? to : "private";
newBag = bag.replace("_public", "_" + to);
}
return newBag;
},
copyTiddler: function(title, newTitle, newBag, callback) {
var original = store.getTiddler(title);
newTitle = newTitle ? newTitle : title;
var adaptor = original.getAdaptor();
var publish = function(original, callback) {
var tiddler = $.extend(new Tiddler(newTitle), original);
tiddler.fields = $.extend({}, original.fields, {
"server.bag": newBag,
"server.workspace": "bags/%0".format(newBag),
"server.page.revision": "false"
});
delete tiddler.fields["server.title"];
tiddler.title = newTitle;
adaptor.putTiddler(tiddler, null, null, callback);
};
publish(original, callback);
},
moveTiddler: function(tiddler, newTiddler, callback) {
var info = {
copyContext: {},
deleteContext: {}
};
var _dirty = store.isDirty();
var adaptor = tiddler.getAdaptor();
var newTitle = newTiddler.title;
var oldTitle = tiddler.title;
delete tiddler.fields["server.workspace"];
var oldBag = tiddler.fields["server.bag"];
var newBag = newTiddler.fields["server.bag"];
var newWorkspace = "bags/%0".format(newBag);
cmd.copyTiddler(oldTitle, newTitle, newBag, function(ctx) {
info.copyContext = ctx;
var context = {
tiddler: tiddler,
workspace: newWorkspace
};
store.addTiddler(ctx.tiddler);
tiddler.title = oldTitle; // for cases where a rename occurs
if(ctx.status) { // only do if a success
if(oldBag != newBag) {
adaptor.deleteTiddler(tiddler, context, {}, function(ctx) {
info.deleteContext = ctx;
var el;
if(tiddler) {
tiddler.fields["server.workspace"] = newWorkspace;
tiddler.fields["server.bag"] = newBag;
}
el = el ? el : story.refreshTiddler(oldTitle, null, true);
if(oldTitle != newTitle) {
store.deleteTiddler(oldTitle);
store.notify(oldTitle, true);
}
if(el) {
story.displayTiddler(el, newTitle);
}
if(oldTitle != newTitle) {
story.closeTiddler(oldTitle);
}
if(callback) {
callback(info);
}
store.setDirty(_dirty);
});
} else {
if(callback) {
callback(info);
}
}
refreshDisplay();
}
});
}
};
var changeToPrivate = config.commands.changeToPrivate = {
text: "make private",
tooltip: "turn this public tiddler into a private tiddler",
isEnabled: function(tiddler) {
return !readOnly && config.filterHelpers.is["public"](tiddler);
},
handler: function(event, src, title) {
var tiddler = store.getTiddler(title);
var newBag = cmd.toggleBag(tiddler, "private");
var newTiddler = { title: title, fields: { "server.bag": newBag }};
cmd.moveTiddler(tiddler, newTiddler);
}
};
config.commands.changeToPublic = cmd;
/* Save as draft command */
var saveDraftCmd = config.commands.saveDraft = {
text: "save draft",
tooltip: "Save as a private draft",
isEnabled: function(tiddler) {
return changeToPrivate.isEnabled(tiddler);
},
getDraftTitle: function(title) {
var draftTitle;
var draftNum = "";
while(!draftTitle) {
var suggestedTitle = "%0 [draft%1]".format(title, draftNum);
if(store.getTiddler(suggestedTitle)) {
draftNum = !draftNum ? 2 : draftNum + 1;
} else {
draftTitle = suggestedTitle;
}
}
return draftTitle;
},
createDraftTiddler: function(title, gatheredFields) {
var tiddler = store.getTiddler(title);
var draftTitle = saveDraftCmd.getDraftTitle(title);
var draftTiddler = new Tiddler(draftTitle);
if(tiddler) {
$.extend(true, draftTiddler, tiddler);
} else {
$.extend(draftTiddler.fields, config.defaultCustomFields);
}
for(var fieldName in gatheredFields) {
if(TiddlyWiki.isStandardField(fieldName)) {
draftTiddler[fieldName] = gatheredFields[fieldName];
} else {
draftTiddler.fields[fieldName] = gatheredFields[fieldName];
}
}
var privateBag = tiddlyspace.getCurrentBag("private");
var privateWorkspace = tiddlyspace.getCurrentWorkspace("private");
draftTiddler.title = draftTitle;
draftTiddler.fields["publish.name"] = title;
draftTiddler.fields["server.workspace"] = privateWorkspace;
draftTiddler.fields["server.bag"] = privateBag;
draftTiddler.fields["server.title"] = draftTitle;
draftTiddler.fields["server.page.revision"] = "false";
delete draftTiddler.fields["server.etag"];
return draftTiddler;
},
handler: function(ev, src, title) {
var tiddler = store.getTiddler(title); // original tiddler
var tidEl = story.getTiddler(title);
var uiFields = {};
story.gatherSaveFields(tidEl, uiFields);
var tid = saveDraftCmd.createDraftTiddler(title, uiFields);
tid = store.saveTiddler(tid.title, tid.title, tid.text, tid.modifier,
new Date(), tid.tags, tid.fields);
autoSaveChanges(null, [tid]);
story.closeTiddler(title);
story.displayTiddler(src, title);
story.displayTiddler(src, tid.title);
}
};
var macro = config.macros.TiddlySpacePublisher = {
locale: {
title: "Batch Publisher",
changeStatusLabel: "Make %0",
noTiddlersText: "No tiddlers to publish",
changeStatusPrompt: "Make all the selected tiddlers %0.",
description: "Change tiddlers from %0 to %1 in this space"
},
listViewTemplate: {
columns: [
{ name: "Selected", field: "Selected", rowName: "title", type: "Selector" },
{ name: "Tiddler", field: "tiddler", title: "Tiddler", type: "Tiddler" },
{ name: "Status", field: "status", title: "Status", type: "WikiText" }
],
rowClasses: []
},
changeStatus: function(tiddlers, status, callback) { // this is what is called when you click the publish button
var publicBag;
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var newTiddler = {
title: tiddler.title,
fields: { "server.bag": cmd.toggleBag(tiddler, status) }
};
cmd.moveTiddler(tiddler, newTiddler, callback);
}
},
getMode: function(paramString) {
var params = paramString.parseParams("anon")[0];
var status = params.type ?
(["public", "private"].contains(params.type[0]) ? params.type[0] : "private") :
"private";
var newStatus = status == "public" ? "private" : "public";
return [status, newStatus];
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var wizard = new Wizard();
var locale = macro.locale;
var status = macro.getMode(paramString);
wizard.createWizard(place, locale.title);
wizard.addStep(macro.locale.description.format(status[0], status[1]),
'<input type="hidden" name="markList" />');
var markList = wizard.getElement("markList");
var listWrapper = $("<div />").addClass("batchPublisher").
attr("refresh", "macro").attr("macroName", macroName).
attr("params", paramString)[0];
markList.parentNode.insertBefore(listWrapper, markList);
$.data(listWrapper, "wizard", wizard);
macro.refresh(listWrapper);
},
getCheckedTiddlers: function(listWrapper, titlesOnly) {
var tiddlers = [];
$(".chkOptionInput[rowName]:checked", listWrapper).each(function(i, el) {
var title = $(el).attr("rowName");
if(titlesOnly) {
tiddlers.push(title);
} else {
tiddlers.push(store.getTiddler(title));
}
});
return tiddlers;
},
refresh: function(listWrapper) {
var checked = macro.getCheckedTiddlers(listWrapper, true);
var paramString = $(listWrapper).empty().attr("params");
var wizard = $.data(listWrapper, "wizard");
var locale = macro.locale;
var params = paramString.parseParams("anon")[0];
var publishCandidates = [];
var status = macro.getMode(paramString);
var pubType = status[0];
var newPubType = status[1];
var tiddlers = params.filter ? store.filterTiddlers(params.filter[0]) :
store.filterTiddlers("[is[%0]]".format(pubType));
var enabled = [];
for(var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var title = tiddler.title;
if(!tiddler.tags.contains("excludePublisher") && title !== "SystemSettings") {
publishCandidates.push({ title: title, tiddler: tiddler, status: pubType});
}
if(checked.contains(title)) {
enabled.push("[rowname=%0]".format(title));
}
}
if(publishCandidates.length === 0) {
createTiddlyElement(listWrapper, "em", null, null, locale.noTiddlersText);
} else {
var listView = ListView.create(listWrapper, publishCandidates, macro.listViewTemplate);
wizard.setValue("listView", listView);
var btnHandler = function(ev) {
var tiddlers = macro.getCheckedTiddlers(listWrapper);
var callback = function(status) {
$(".batchPublisher").each(function(i, el) {
macro.refresh(el);
});
};
macro.changeStatus(tiddlers, newPubType, callback);
};
wizard.setButtons([{
caption: locale.changeStatusLabel.format(newPubType),
tooltip: locale.changeStatusPrompt.format(newPubType),
onClick: btnHandler
}]);
$(enabled.join(",")).attr("checked", true); // retain what was checked before
}
}
};
})(jQuery);
//}}}
!Spaces
<<groupBy server.bag>>
!Private
<<list filter [is[private]]>>
!Public
<<list filter [is[public]]>>
!Drafts
<<list filter [is[draft]]>>
/***
|''Description''|Sanitisation for dynamically pulling tiddlers into your space and displaying them|
!Notes
Works both inside and outside TiddlyWiki. Uses the HTML Sanitizer provided by the Google Caja project
(see http://code.google.com/p/google-caja/wiki/JsHtmlSanitizer for more on this), which is licensed under
an Apache License (see http://www.apache.org/licenses/LICENSE-2.0).
!Code
***/
//{{{
(function($) {
var cleanURL = function(url) {
var regexp = /^(?:http|https|mailto|ftp|irc|news):\/\//;
return (regexp.test(url)) ? url : null;
};
$.sanitize = function(html) {
return html_sanitize(html, cleanURL);
};
/*
* HTML Sanitizer, provided by Google Caja
*/
/* Copyright Google Inc.
* Licensed under the Apache Licence Version 2.0
* Autogenerated at Tue May 17 17:39:24 BST 2011
* @provides html4
*/var html4={};html4.atype={NONE:0,URI:1,URI_FRAGMENT:11,SCRIPT:2,STYLE:3,ID:4,IDREF:5,IDREFS:6,GLOBAL_NAME:7,LOCAL_NAME:8,CLASSES:9,FRAME_TARGET:10},html4.ATTRIBS={"*::class":9,"*::dir":0,"*::id":4,"*::lang":0,"*::onclick":2,"*::ondblclick":2,"*::onkeydown":2,"*::onkeypress":2,"*::onkeyup":2,"*::onload":2,"*::onmousedown":2,"*::onmousemove":2,"*::onmouseout":2,"*::onmouseover":2,"*::onmouseup":2,"*::style":3,"*::title":0,"a::accesskey":0,"a::coords":0,"a::href":1,"a::hreflang":0,"a::name":7,"a::onblur":2,"a::onfocus":2,"a::rel":0,"a::rev":0,"a::shape":0,"a::tabindex":0,"a::target":10,"a::type":0,"area::accesskey":0,"area::alt":0,"area::coords":0,"area::href":1,"area::nohref":0,"area::onblur":2,"area::onfocus":2,"area::shape":0,"area::tabindex":0,"area::target":10,"bdo::dir":0,"blockquote::cite":1,"br::clear":0,"button::accesskey":0,"button::disabled":0,"button::name":8,"button::onblur":2,"button::onfocus":2,"button::tabindex":0,"button::type":0,"button::value":0,"canvas::height":0,"canvas::width":0,"caption::align":0,"col::align":0,"col::char":0,"col::charoff":0,"col::span":0,"col::valign":0,"col::width":0,"colgroup::align":0,"colgroup::char":0,"colgroup::charoff":0,"colgroup::span":0,"colgroup::valign":0,"colgroup::width":0,"del::cite":1,"del::datetime":0,"dir::compact":0,"div::align":0,"dl::compact":0,"font::color":0,"font::face":0,"font::size":0,"form::accept":0,"form::action":1,"form::autocomplete":0,"form::enctype":0,"form::method":0,"form::name":7,"form::onreset":2,"form::onsubmit":2,"form::target":10,"h1::align":0,"h2::align":0,"h3::align":0,"h4::align":0,"h5::align":0,"h6::align":0,"hr::align":0,"hr::noshade":0,"hr::size":0,"hr::width":0,"iframe::align":0,"iframe::frameborder":0,"iframe::height":0,"iframe::marginheight":0,"iframe::marginwidth":0,"iframe::width":0,"img::align":0,"img::alt":0,"img::border":0,"img::height":0,"img::hspace":0,"img::ismap":0,"img::name":7,"img::src":1,"img::usemap":11,"img::vspace":0,"img::width":0,"input::accept":0,"input::accesskey":0,"input::align":0,"input::alt":0,"input::autocomplete":0,"input::checked":0,"input::disabled":0,"input::ismap":0,"input::maxlength":0,"input::name":8,"input::onblur":2,"input::onchange":2,"input::onfocus":2,"input::onselect":2,"input::readonly":0,"input::size":0,"input::src":1,"input::tabindex":0,"input::type":0,"input::usemap":11,"input::value":0,"ins::cite":1,"ins::datetime":0,"label::accesskey":0,"label::for":5,"label::onblur":2,"label::onfocus":2,"legend::accesskey":0,"legend::align":0,"li::type":0,"li::value":0,"map::name":7,"menu::compact":0,"ol::compact":0,"ol::start":0,"ol::type":0,"optgroup::disabled":0,"optgroup::label":0,"option::disabled":0,"option::label":0,"option::selected":0,"option::value":0,"p::align":0,"pre::width":0,"q::cite":1,"select::disabled":0,"select::multiple":0,"select::name":8,"select::onblur":2,"select::onchange":2,"select::onfocus":2,"select::size":0,"select::tabindex":0,"table::align":0,"table::bgcolor":0,"table::border":0,"table::cellpadding":0,"table::cellspacing":0,"table::frame":0,"table::rules":0,"table::summary":0,"table::width":0,"tbody::align":0,"tbody::char":0,"tbody::charoff":0,"tbody::valign":0,"td::abbr":0,"td::align":0,"td::axis":0,"td::bgcolor":0,"td::char":0,"td::charoff":0,"td::colspan":0,"td::headers":6,"td::height":0,"td::nowrap":0,"td::rowspan":0,"td::scope":0,"td::valign":0,"td::width":0,"textarea::accesskey":0,"textarea::cols":0,"textarea::disabled":0,"textarea::name":8,"textarea::onblur":2,"textarea::onchange":2,"textarea::onfocus":2,"textarea::onselect":2,"textarea::readonly":0,"textarea::rows":0,"textarea::tabindex":0,"tfoot::align":0,"tfoot::char":0,"tfoot::charoff":0,"tfoot::valign":0,"th::abbr":0,"th::align":0,"th::axis":0,"th::bgcolor":0,"th::char":0,"th::charoff":0,"th::colspan":0,"th::headers":6,"th::height":0,"th::nowrap":0,"th::rowspan":0,"th::scope":0,"th::valign":0,"th::width":0,"thead::align":0,"thead::char":0,"thead::charoff":0,"thead::valign":0,"tr::align":0,"tr::bgcolor":0,"tr::char":0,"tr::charoff":0,"tr::valign":0,"ul::compact":0,"ul::type":0},html4.eflags={OPTIONAL_ENDTAG:1,EMPTY:2,CDATA:4,RCDATA:8,UNSAFE:16,FOLDABLE:32,SCRIPT:64,STYLE:128},html4.ELEMENTS={a:0,abbr:0,acronym:0,address:0,applet:16,area:2,b:0,base:18,basefont:18,bdo:0,big:0,blockquote:0,body:49,br:2,button:0,canvas:0,caption:0,center:0,cite:0,code:0,col:2,colgroup:1,dd:1,del:0,dfn:0,dir:0,div:0,dl:0,dt:1,em:0,fieldset:0,font:0,form:0,frame:18,frameset:16,h1:0,h2:0,h3:0,h4:0,h5:0,h6:0,head:49,hr:2,html:49,i:0,iframe:4,img:2,input:2,ins:0,isindex:18,kbd:0,label:0,legend:0,li:1,link:18,map:0,menu:0,meta:18,nobr:0,noframes:20,noscript:20,object:16,ol:0,optgroup:0,option:1,p:1,param:18,pre:0,q:0,s:0,samp:0,script:84,select:0,small:0,span:0,strike:0,strong:0,style:148,sub:0,sup:0,table:0,tbody:1,td:1,textarea:8,tfoot:1,th:1,thead:1,title:24,tr:1,tt:0,u:0,ul:0,"var":0},html4.ueffects={NOT_LOADED:0,SAME_DOCUMENT:1,NEW_DOCUMENT:2},html4.URIEFFECTS={"a::href":2,"area::href":2,"blockquote::cite":0,"body::background":1,"del::cite":0,"form::action":2,"img::src":1,"input::src":1,"ins::cite":0,"q::cite":0},html4.ltypes={UNSANDBOXED:2,SANDBOXED:1,DATA:0},html4.LOADERTYPES={"a::href":2,"area::href":2,"blockquote::cite":2,"body::background":1,"del::cite":2,"form::action":2,"img::src":1,"input::src":1,"ins::cite":2,"q::cite":2};var html=function(a){function x(b,c,d){var e=[];w(function(b,e){for(var f=0;f<e.length;f+=2){var g=e[f],h=e[f+1],i=null,j;if((j=b+"::"+g,a.ATTRIBS.hasOwnProperty(j))||(j="*::"+g,a.ATTRIBS.hasOwnProperty(j)))i=a.ATTRIBS[j];if(i!==null)switch(i){case a.atype.NONE:break;case a.atype.SCRIPT:case a.atype.STYLE:h=null;break;case a.atype.ID:case a.atype.IDREF:case a.atype.IDREFS:case a.atype.GLOBAL_NAME:case a.atype.LOCAL_NAME:case a.atype.CLASSES:h=d?d(h):h;break;case a.atype.URI:h=c&&c(h);break;case a.atype.URI_FRAGMENT:h&&"#"===h.charAt(0)?(h=d?d(h):h,h&&(h="#"+h)):h=null;break;default:h=null}else h=null;e[f+1]=h}return e})(b,e);return e.join("")}function w(b){var c,d;return v({startDoc:function(a){c=[],d=!1},startTag:function(e,f,g){if(!d){if(!a.ELEMENTS.hasOwnProperty(e))return;var h=a.ELEMENTS[e];if(h&a.eflags.FOLDABLE)return;if(h&a.eflags.UNSAFE){d=!(h&a.eflags.EMPTY);return}f=b(e,f);if(f){h&a.eflags.EMPTY||c.push(e),g.push("<",e);for(var i=0,j=f.length;i<j;i+=2){var k=f[i],l=f[i+1];l!==null&&l!==void 0&&g.push(" ",k,'="',r(l),'"')}g.push(">")}}},endTag:function(b,e){if(d)d=!1;else{if(!a.ELEMENTS.hasOwnProperty(b))return;var f=a.ELEMENTS[b];if(!(f&(a.eflags.UNSAFE|a.eflags.EMPTY|a.eflags.FOLDABLE))){var g;if(f&a.eflags.OPTIONAL_ENDTAG)for(g=c.length;--g>=0;){var h=c[g];if(h===b)break;if(!(a.ELEMENTS[h]&a.eflags.OPTIONAL_ENDTAG))return}else for(g=c.length;--g>=0;)if(c[g]===b)break;if(g<0)return;for(var i=c.length;--i>g;){var h=c[i];a.ELEMENTS[h]&a.eflags.OPTIONAL_ENDTAG||e.push("</",h,">")}c.length=g,e.push("</",b,">")}}},pcdata:function(a,b){d||b.push(a)},rcdata:function(a,b){d||b.push(a)},cdata:function(a,b){d||b.push(a)},endDoc:function(a){for(var b=c.length;--b>=0;)a.push("</",c[b],">");c.length=0}})}function v(c){return function(d,e){d=String(d);var f=null,g=!1,h=[],j=void 0,l=void 0,m=void 0;c.startDoc&&c.startDoc(e);while(d){var n=d.match(g?t:u);d=d.substring(n[0].length);if(g){if(n[1]){var o=b(n[1]),p;if(n[2]){var q=n[3];switch(q.charCodeAt(0)){case 34:case 39:q=q.substring(1,q.length-1)}p=k(i(q))}else p=o;h.push(o,p)}else if(n[4]){l!==void 0&&(m?c.startTag&&c.startTag(j,h,e):c.endTag&&c.endTag(j,e));if(m&&l&(a.eflags.CDATA|a.eflags.RCDATA)){f===null?f=b(d):f=f.substring(f.length-d.length);var r=f.indexOf("</"+j);r<0&&(r=d.length),l&a.eflags.CDATA?c.cdata&&c.cdata(d.substring(0,r),e):c.rcdata&&c.rcdata(s(d.substring(0,r)),e),d=d.substring(r)}j=l=m=void 0,h.length=0,g=!1}}else if(n[1])c.pcdata&&c.pcdata(n[0],e);else if(n[3])m=!n[2],g=!0,j=b(n[3]),l=a.ELEMENTS.hasOwnProperty(j)?a.ELEMENTS[j]:void 0;else if(n[4])c.pcdata&&c.pcdata(n[4],e);else if(n[5]&&c.pcdata)switch(n[5]){case"<":c.pcdata("<",e);break;case">":c.pcdata(">",e);break;default:c.pcdata("&",e)}}c.endDoc&&c.endDoc(e)}}function s(a){return a.replace(m,"&$1").replace(n,"<").replace(o,">")}function r(a){return a.replace(l,"&").replace(n,"<").replace(o,">").replace(p,""").replace(q,"=")}function k(a){return a.replace(j,g)}function i(a){return a.replace(h,"")}function g(a,b){return f(b)}function f(a){a=b(a);if(c.hasOwnProperty(a))return c[a];var f=a.match(d);if(f)return String.fromCharCode(parseInt(f[1],10));if(!!(f=a.match(e)))return String.fromCharCode(parseInt(f[1],16));return""}var b;"script"==="SCRIPT".toLowerCase()?b=function(a){return a.toLowerCase()}:b=function(a){return a.replace(/[A-Z]/g,function(a){return String.fromCharCode(a.charCodeAt(0)|32)})};var c={lt:"<",gt:">",amp:"&",nbsp:"240",quot:'"',apos:"'"},d=/^#(\d+)$/,e=/^#x([0-9A-Fa-f]+)$/,h=/\0/g,j=/&(#\d+|#x[0-9A-Fa-f]+|\w+);/g,l=/&/g,m=/&([^a-z#]|#(?:[^0-9x]|x(?:[^0-9a-f]|$)|$)|$)/gi,n=/</g,o=/>/g,p=/\"/g,q=/\=/g,t=new RegExp("^\\s*(?:(?:([a-z][a-z-]*)(\\s*=\\s*(\"[^\"]*\"|'[^']*'|(?=[a-z][a-z-]*\\s*=)|[^>\"'\\s]*))?)|(/?>)|[\\s\\S][^a-z\\s>]*)","i"),u=new RegExp("^(?:&(\\#[0-9]+|\\#[x][0-9a-f]+|\\w+);|<!--[\\s\\S]*?-->|<!\\w[^>]*>|<\\?[^>*]*>|<(/)?([a-z][a-z0-9]*)|([^<&>]+)|([<&>]))","i");return{escapeAttrib:r,makeHtmlSanitizer:w,makeSaxParser:v,normalizeRCData:s,sanitize:x,unescapeEntities:k}}(html4),html_sanitize=html.sanitize
// stop here if we're not in TiddlyWiki
// XXX: is this the correct way of checking for TiddlyWiki?
if (!window.TiddlyWiki || !window.store || !store instanceof TiddlyWiki) {
return;
}
var tiddlyspace = config.extensions.tiddlyspace;
var _subWikify = Wikifier.prototype.subWikify;
var cleanedTitle = 'This section has been cleaned of any potentially harmful code';
var replaceFunctions = {
html: function(w) {
var sanitizedHTML, spanEl;
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
sanitizedHTML = $.sanitize(lookaheadMatch[1]);
spanEl = createTiddlyElement(w.output, 'span', null, 'sanitized');
spanEl.innerHTML = sanitizedHTML;
spanEl.setAttribute('title', cleanedTitle);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
},
customFormat: function(w) {
switch(w.matchText) {
case '@@':
var e = createTiddlyElement(w.output, 'span');
var styles = config.formatterHelpers.inlineCssHelper(w);
if (styles.length === 0) {
e.className = 'marked';
}
w.subWikifyTerm(e, /(@@)/mg);
break;
case '{{':
var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source);
if(lookaheadMatch) {
w.nextMatch = lookaheadRegExp.lastIndex;
e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
w.subWikifyTerm(e,/(\}\}\})/mg);
}
break;
}
}
};
Wikifier.prototype.subWikify = function(output, terminator) {
var tid = this.tiddler,
spaceName = tiddlyspace.currentSpace.name,
tidSpace, recipeName, stripped;
try {
recipeName = tid.fields['server.recipe'] ||
tid.fields['server.workspace'];
tidSpace = tiddlyspace.resolveSpaceName(recipeName);
if (tidSpace !== spaceName) {
// external tiddler, so replace dangerous formatters
stripped = stripHTML(tid, this.formatter);
}
} catch(e) {
// do nothing. There's no tiddler, so assume it's safe (?!?!?)
}
_subWikify.apply(this, arguments);
if (stripped) {
// change back to the original function
unstripHTML(stripped, this.formatter);
}
};
// replace potentially unsafe formatters with versions that strip bad HTML/CSS
var stripHTML = function(tid, formatter) {
var popped = {}, _handler;
for (var i = 0; i < formatter.formatters.length; i++) {
var f = formatter.formatters[i];
if (replaceFunctions[f.name]) {
_handler = f.handler;
popped[f.name] = _handler;
f.handler = replaceFunctions[f.name];
}
};
return popped;
};
// put the original formatters back where they belong
var unstripHTML = function(stripped, formatter) {
for (var i = 0; i < formatter.formatters.length; i++) {
var f = formatter.formatters[i];
if (stripped[f.name]) {
f.handler = stripped[f.name];
}
};
};
})(jQuery);
//}}}
<!--{{{-->
<link rel="shortcut icon" href="/recipes/tiddlywiki_public/tiddlers/favicon.ico" />
<link href="/bags/tiddlywiki_public/tiddlers.atom" rel="alternate"
type="application/atom+xml" title="tiddlywiki's public feed" />
<!--}}}-->
The tag macro generates a button with the named [[tag]] which when clicked provides a drop-down list of [[tiddlers]] tagged with the given tag along with an option to open all of the tagged tiddlers.
{{{
<<tag tagName [label] [tooltip]>>
}}}
For example
{{{
<<tag macro>>
}}}
Which displays
<<tag macro>>
It takes 2 parameters, the first being a tiddler object, the second being the name of the attribute or field to be accessed (a string).
Soon this should also support access to slices, which is achieved by preceding the second parameter string with ## or :: as appropriate.
For example
{{{
store.getValue(tiddler, "##foo")
}}}
should return the value of the section foo.
*[[TiddlyWiki Wiki|http://tiddlywiki.org/]] - general documentation located at either http://tiddlywiki.tiddlyspace.com/ or http://tiddlywiki.org/
*[[TiddlyWikiDev|http://tiddlywikidev.tiddlyspace.com/#Welcome]] - TiddlyWiki development space
*[[Tiddlywikidocco|http://tiddlywikidocco.tiddlyspace.com/]] - annotated source code
*[[TiddlySpaceDev|http://developers.tiddlyspace.com/]] - TiddlySpace development location
Sections in a tiddler refer to all that which is enclosed in headings. Beware that sections do __not__ entail subsections when being access programatically. Also note that a tiddlers end marks the end of the last section.
For example, assume a tiddler containing the following...
{{{
!Heading1
Some introductory text.
!!Heading2
Some more details.
}}}
Here, section {{{Heading1}}} refers to all content that the section Heading1 contains. If you transclude its content vie the tiddler macro via {{{<<tiddler Sections##Heading1>>}}} you get the following result:
<<<
<<tiddler Sections##Heading1>>
<<<
Likewise {{{<<tiddler Sections##Heading2>>}}} renders as:
<<<
Some more details.
<<<
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
With TiddlyWiki you can:
* Keep your useful information handy
* Organise all your notes
* Make and manage a todo list
** Or a [[What is GTD?|GTD]] system
* Easily publish a dynamic [[TiddlyWiki_As_a_Website|web site]]
* Keep a journal
* Do anything you can do in another kind of wiki but without the setup hassle
* Do ([[Pen and Paper|almost]]) anything you can do with a pen and paper only with convenience of searching and tagging your data
* Write a "Choose Your Own Adventure" style book
Raw HTML text can be included in a tiddler:
{{{
<html>
This is some <strong>HTML</strong> formatting
</html>
}}}
<html>
This is some <strong>HTML</strong> formatting
</html>
!Notes
* only static HTML elements that are valid within a {{{<div>}}} work correctly
* {{{document.write}}} cannot be used to generate dynamic content
* External {{{<script>}}} elements cannot be used within {{{<html>}}} blocks
The refreshAllTiddlers method of the [[Story]] class re-renders all tiddlers currently visible on the page by individually calling the [[refreshTiddler|Story.prototype.refreshTiddler]] for each of the open tiddlers in the story. It does not take any parameters nor does it return any value. Tiddlers with unsaved changes are forced to be re-rendered.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="506 234 68 36" width="30" height="30"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2010-09-16 14:51Z</dc:date><!-- Produced by OmniGraffle Professional 5.2.3 --></metadata><defs></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><rect width="1118" height="783"/><g><path d="M 538.68195 244.31807 C 540.43927 246.07547 540.43927 248.9247 538.68195 250.68204 C 536.92456 252.4394 534.07532 252.4394 532.318 250.68204 C 530.5606 248.9247 530.5606 246.07547 532.318 244.31807 C 534.07532 242.56075 536.92456 242.56075 538.68195 244.31807 M 511.12607 257.99356 C 511.26108 258.13019 511.39728 258.26608 511.53473 258.40121 C 527.2556 273.86606 552.74414 273.86606 568.46515 258.40121 C 568.60248 258.26617 568.73853 258.13037 568.87354 257.9938 C 568.8736 257.99374 568.8736 257.99371 568.8736 257.99362 C 568.87366 257.99371 568.87366 257.9938 568.87372 257.9939 C 570.72504 256.12051 572.35046 254.11153 573.74994 252 C 573.74994 251.99997 573.74994 251.99994 573.74994 251.99992 C 572.35046 249.8884 570.72504 247.87938 568.87372 246.00606 C 568.87366 246.00613 568.87366 246.00621 568.8736 246.00627 C 568.73865 245.86966 568.60254 245.73383 568.46515 245.5987 C 552.74414 230.13387 527.2556 230.13387 511.53473 245.5987 C 511.39728 245.73383 511.26108 245.86974 511.12613 246.00635 C 511.126 246.00624 511.126 246.00616 511.12595 246.00606 C 509.2748 247.87938 507.64954 249.88837 506.24994 251.9998 L 506.24994 251.99983 C 506.24994 251.9999 506.25 251.99992 506.25 251.99997 C 506.25 252 506.24994 252.00005 506.24994 252.00009 L 506.24994 252.00012 C 507.64954 254.11157 509.2748 256.12051 511.12595 257.9939 C 511.126 257.99377 511.126 257.99365 511.12607 257.99359 Z M 515.44916 252 C 515.8548 251.55469 516.27502 251.11778 516.71014 250.68985 C 522.16632 245.32257 529.06055 242.23206 536.17273 241.41824 C 534.6662 241.96199 533.2525 242.83762 532.04498 244.04512 C 527.65155 248.43852 527.65155 255.56163 532.04498 259.95502 C 533.2522 261.16226 534.6656 262.03778 536.17175 262.58154 C 529.05988 261.76761 522.16608 258.6771 516.71014 253.31009 C 516.2751 252.88219 515.85486 252.44528 515.44922 252 Z M 564.55054 251.99995 C 564.14502 252.44525 563.7248 252.88217 563.28973 253.31009 C 557.83368 258.67712 550.93988 261.76764 543.828 262.58157 C 545.33423 262.03781 546.74756 261.1623 547.9549 259.95502 C 552.34833 255.56163 552.34833 248.43852 547.9549 244.04512 C 546.74744 242.83765 545.33374 241.96202 543.82715 241.41824 C 550.9394 242.23206 557.83356 245.3226 563.28973 250.68985 C 563.7248 251.11775 564.14502 251.55467 564.55054 251.99995 Z M 568.8736 257.99362 C 570.7249 256.12033 572.35028 254.11139 573.74988 252.00002" fill="black" class="glyph"/></g></g></svg>
Four dashes on a line by themselves are used to introduce a horizontal rule:
{{{
Before the rule
----
After the rule
}}}
Displays as:
Before the rule
----
After the rule
The HTML tag {{{<hr>}}} can be used as an alternative syntax:
{{{
Before the rule<hr>After the rule
}}}
Displays as:
Before the rule<hr>After the rule
At [[Tiddlyspot|http://tiddlyspot.com]] you can quickly create an online web site using TiddlyWiki. You can save your changes online (using [[UploadPlugin]]) and you can even download your site, work on it offline, then upload it back to the web when you want to.
!Features
* Select from several different TiddlyWiki distributions known as "flavours".
* Can customise your site and use any plugin you want.
* Choose a private or public site.
* Keep some backups of your site in case you need to restore a previous version.
!More Information
* [[Tiddlyspot FAQ|http://faq.tiddlyspot.com]]
* [[Tiddlyspot Blopg|http://tiddlyspot.blogspot.com]]
* [[About Tiddlyspot|http://tiddlyspot.com/?page=about]]
The ''filterTiddlers'' method of a [[TiddlyWiki class|TiddlyWiki Class]] object retrieves a filtered list of its tiddlers. It returns an array of Tiddler() objects that match the filter expression. The method takes one parameter:
* ''filter'' - the filter string (returns an empty array if not provided)
A filter follows a grammar that can be described in http://en.wikipedia.org/wiki/EBNF:
{{{
filter := filterStep {'|' filterStep }
filterStep := '[' filterElements ']', {'[' filterElements ']'}
filterElements := filterElement, {filterElement}
filterElement := '['TiddlerName']' | tag'['TagName']' | sort'['SortField']' | limit'['NoOfResults']'
}}}
Another way of expressing this, without the (in this case) slightly confusing EBNF syntax, might be:
A filter string is of the form:
{{{
filterStep | filterStep ... // only one filterStep is required
}}}
where filterStep is of the form:
{{{
[filterElements] [filterElements] ... // only one filterElements is required
}}}
where filterElements is one or more of the following:
{{{
[TiddlerName]
tag[TagName]
sort[SortField]
limit[NoOfResults]
}}}
Example:
{{{
store.filterTiddlers("[tag[blog post]][sort[-modified]][limit[10]]")
}}}
returns any tiddler tagged "blog post", limited to the 10 most recently edited tiddlers.
!Allowed types of filterElement
|filter|meaning|
|[text]|refers to a single tiddler with title "text"|
|{{{[text text]}}}|refers to a single tiddler with title "text text"|
|tag[tag]|refers to any tiddler tagged with "tag"|
|tag[a tag]|refers to any tiddler tagged with "{{{[[a tag]]}}}"|
|sort[+field] or [sort[field]]|sorts any results already collected in ascending order by "field"|
|sort[-field]|sorts and results already collected in descending order by "field"|
|limit[integer]|limits the results array to contain no more than "integer" tiddlers|
!Multiple filterElements and filterSteps
Multiple ''filterElements'' are combined by concatenating the results from each ''filterElements''.
Multiple ''filterStep'', on the other hand, are evaluated in succession, with the results of each ''filterStep'' used as the tiddler set for the next ''filterStep''.
Examples:
{{{
store.filterTiddlers("[tag[mish]] [tag[mash]]") // two filter elements
returns any tiddler tagged with "mish" or "mash".
store.filterTiddlers("[tag[mish]] | [tag[mash]]") // two filter steps
returns any tiddler tagged with "mish" and of these, any tagged with "mash".
}}}
Welcome to the @tiddlywikidev space.
Here you will be able to find all the documentation you need to understand tiddlywiki and write your own plugins. An overview is given in [[Overview]].
We are currently working very hard to populate this wiki with all the relevant documentation. This will take time so please bear with us.
You might find the annotated source code useful too. To view some just click on any on the links in the [[Links to JS Source Code]] tiddler.
!!You can help out too
You can reply to the tiddler - this is similar to making a comment on the tiddler, although the tiddler will actually reside in your homespace. This wiki will then search tiddlyspace and pull in all the responses and show them as comments. Then you can suggest changes and those suggestions can be discussed (if required) before making it into the actual documentation.
Please note that you will need to be a member of tiddlyspace.
Have suggestions for missing content? Reply to [[TiddlyWiki Dev Missing Stuff]]
This tiddler contains the command to display the plugin manager:
{{{
<<plugins>>
}}}
The TabMoreShadowed tiddler contains a command that displays a list of all tiddlers shadowed with default content in them
{{{
<<list shadowed>>
}}}
In TiddlyWiki this list appears as default in the {{{Shadows}}} tab on the right-hand menu.
!Download (1.7.6)
http://oldwiki.tiddlywiki.org/ccTiddly/ccTiddly_v1.7.6.zip
!Download (1.9 - requires PHP5)
http://oldwiki.tiddlywiki.org/ccTiddly/ccTiddly_1.9.minimal.zip
!Demo
http://wiki.osmosoft.com/alpha http://wiki.osmosoft.com/alpha
!Release Notes
[[CcTiddlyReleases|ccTiddly Alpha Release Notes]]
!Community
If you would like to report a bug, request a feature or just ask for some help please post a message on the ccTiddly google group : [[ccTiddly Google Groups|http://groups.google.com/group/ccTiddly ccTiddly]]
''ccTiddly is a collaborative server side version of TiddlyWiki. (tiddlywiki.com) Its features include :'''
* Multiple workspaces (TiddlyWiki files)
* User Management
* OpenID, LDAP and Delegated Session management support.
* Revision management
* Tag based permissions model
* File Uploading
* Shows workspace viewing statistics
* Offline working (sync)
!!Additional Info
* CcTiddlyDeveloper
* CcTiddlyInstallation
* CcTiddlyConfig
* CcTiddlyPermissions
''NB:'' ccTiddly currently has no official maintainer.
(function($){$.toJSON=function(o)
{if(typeof(JSON)=='object'&&JSON.stringify)
return JSON.stringify(o);var type=typeof(o);if(o===null)
return"null";if(type=="undefined")
return undefined;if(type=="number"||type=="boolean")
return o+"";if(type=="string")
return $.quoteString(o);if(type=='object')
{if(typeof o.toJSON=="function")
return $.toJSON(o.toJSON());if(o.constructor===Date)
{var month=o.getUTCMonth()+1;if(month<10)month='0'+month;var day=o.getUTCDate();if(day<10)day='0'+day;var year=o.getUTCFullYear();var hours=o.getUTCHours();if(hours<10)hours='0'+hours;var minutes=o.getUTCMinutes();if(minutes<10)minutes='0'+minutes;var seconds=o.getUTCSeconds();if(seconds<10)seconds='0'+seconds;var milli=o.getUTCMilliseconds();if(milli<100)milli='0'+milli;if(milli<10)milli='0'+milli;return'"'+year+'-'+month+'-'+day+'T'+
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
if(o.constructor===Array)
{var ret=[];for(var i=0;i<o.length;i++)
ret.push($.toJSON(o[i])||"null");return"["+ret.join(",")+"]";}
var pairs=[];for(var k in o){var name;var type=typeof k;if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;if(typeof o[k]=="function")
continue;var val=$.toJSON(o[k]);pairs.push(name+":"+val);}
return"{"+pairs.join(", ")+"}";}};$.evalJSON=function(src)
{if(typeof(JSON)=='object'&&JSON.parse)
return JSON.parse(src);return eval("("+src+")");};$.secureEvalJSON=function(src)
{if(typeof(JSON)=='object'&&JSON.parse)
return JSON.parse(src);var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};$.quoteString=function(string)
{if(string.match(_escapeable))
{return'"'+string.replace(_escapeable,function(a)
{var c=_meta[a];if(typeof c==='string')return c;c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};var _escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var _meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};})(jQuery);
User-agent: *
Disallow: /bags/*/tiddlers.wiki
Disallow: /recipes/*/tiddlers.wiki
Disallow: /*/revisions
Several [[Macros|MacrosContent]] including the [[Today Macro|today macro]] take a [[Date Format String|Date Formats]] as an optional argument. This string can be a combination of ordinary text, with some special characters that get substituted by parts of the date:
* {{{DDD}}} - day of week in full (eg, "Monday")
* {{{ddd}}} - short day of week (eg, "Mon")
* {{{DD}}} - day of month
* {{{0DD}}} - adds a leading zero
* {{{DDth}}} - adds a suffix
* {{{WW}}} - ~ISO-8601 week number of year
* {{{0WW}}} - adds a leading zero
* {{{MMM}}} - month in full (eg, "July")
* {{{mmm}}} - short month (eg, "Jul")
* {{{MM}}} - month number
* {{{0MM}}} - adds leading zero
* {{{YYYY}}} - full year
* {{{YY}}} - two digit year
* {{{wYYYY}}} - full year with respect to week number
* {{{wYY}}} two digit year with respect to week number
* {{{hh}}} - hours
* {{{0hh}}} - adds a leading zero
* {{{hh12}}} - hours in 12 hour clock
* {{{0hh12}}} - hours in 12 hour clock with leading zero
* {{{mm}}} - minutes
* {{{0mm}}} - minutes with leading zero
* {{{ss}}} - seconds
* {{{0ss}}} - seconds with leading zero
* {{{am}}} or {{{pm}}} - lower case AM/PM indicator
* {{{AM}}} or {{{PM}}} - upper case AM/PM indicator
!!!!Examples
{{{DDth MMM YYYY}}} - 16th February 2011
{{{DDth mmm hh:mm:ss}}} - 16th Feb 2011 11:38:42
The Activity Stream is a way to make use of the following functionality in TiddlySpace. It allows you see what recent activity of the spaces you choose to follow. To use it you must include the @following space.
This macro displays the version of the TiddlyWiki.
!Usage
{{{<<version>>}}}
/***
|''Name:''|ThemedTiddlerPlugin |
|''Description:''|Per-Tiddler Mini-Themes |
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com) |
|''Source:''|http://whatfettle.com/2008/07/ThemedTiddlerPlugin/ |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/PaulDowney/plugins/ThemedTiddlerPlugin/ |
|''Version:''|0.1|
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.4|
!!Documentation
The extended field "theme" is used to reference a tiddler containing a "mini-theme"
A mini-theme is a tiddler containing a [[ViewTemplate]], [[EditTemplate]] and [[StyleSheet]] sections which are applied when the tiddler is displayed.
In addition, a CSS class of the theme name is added to the tiddler which may be useful when writing a mini-theme [[StyleSheet]].
!!Code
***/
//{{{
/*jslint onevar: false nomen: false plusplus: false */
/*global Story, store, setStylesheet, jQuery */
if (!version.extensions.ThemedTiddlerPlugin) {
version.extensions.ThemedTiddlerPlugin = {installed: true};
Story.prototype.__chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler;
Story.prototype.chooseTemplateForTiddler = function (title, n)
{
// translate number into template name
var template = ["ViewTemplate", "EditTemplate"][n ? n - 1 : 0];
var tiddler = store.getTiddler(title);
if (tiddler) {
var theme = tiddler.fields.theme;
if (theme) {
// assert stylesheet
var style = store.getTiddlerText(theme + '##StyleSheet');
if (style) {
setStylesheet(style, theme);
}
// return theme template
var slice = theme + '##' + template;
if (store.getTiddlerText(slice)) {
return slice;
}
}
}
// default template
return this.__chooseTemplateForTiddler.apply(this, arguments);
};
// assert theme name as a class on the tiddler
Story.prototype.__refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function (title, template, force, customFields, defaultText)
{
var tiddlerElem = this.__refreshTiddler.apply(this, arguments);
var tiddler = store.getTiddler(title);
if (tiddler) {
jQuery(tiddlerElem).addClass(store.getTiddler(title).fields.theme);
}
return tiddlerElem;
};
}
//}}}
'' System Tags ''
TiddlyWiki defines a small number of special tags that are used to indicate that tiddlers should be treated differently in some way:
|!systemConfig|marks tiddlers containing JavaScript code that should be executed on startup (usually [[plugins]] or [[macros]])}|
|! systemConfigDisable| prevents tiddler contents from being executed on startup (takes precedence over <code>systemConfig</code> and <code>systemConfigForce</code>)|
|! systemConfigForce| force tiddler contents to be executed on startup (irrespective of requirements like ''CoreVersion'')|
|! systemServer| indicates that the respective tiddler contains server details for [[importing]]|
! systemTheme|indicates [[themes]]|
|! excludeSearch|excludes a tiddler from search results|
|! excludeLists|excludes a tiddler from the lists in the sidebar tabs (e.g. [[Timeline]]), as well as from the generated RSS feed|
|! excludeMissing|excludes a tiddler from the processing that generates the [[Missing Tiddlers]] list|
[[Category:Using TiddlyWiki]]
'' Tagging Tags ''
By creating a tiddler named after a given tag (e.g. ''journal''), tags themselves can be tagged as well (e.g. to hide them from the index in the sidebar tabs).
'' See Also ''
* [[Tags macro|TagsMacro]]
* [[Enhanced Tagging]]
See these:
* [[EasyEditPlugin|http://visualtw.ouvaton.org/VisualTW.html#EasyEditPlugin]] (doesn't require any external files)
* [[WYSIWYG plugin|http://visualtw.ouvaton.org/VisualTW.html#%5B%5BWysiwyg%20plugin%5D%5D]] (requires [http://www.fckeditor.net FCKeditor])
* [[RichTextPlugin|http://tiddlywiki.ouvaton.org/Demo.html]] (requires [http://tinymce.moxiecode.com/index.php TinyMCE])
* [[ASciencePad|http://math.chapman.edu/~jipsen/asciencepad/asciencepad.html]] (an adaptation I believe, i.e. it's not a standard TW core}
This is not WYSIWYG but may be of interest:
* [[PreviewPlugin|http://www.tiddlytools.com/#PreviewPlugin]] in combination with [[QuickEditPackage|http://www.tiddlytools.com/#QuickEditPackage]]
* [[WikiBar|http://aiddlywiki.sourceforge.net/wikibar_demo_2.html]] (Doesn't work in IE)
Non-TiddlyWiki WYSIWYG, of related interest
* [[KNote|http://knote.smartgoldfish.com]] (A standalone note taking program based on TiddlyWiki)
* [[LumiNotes|http://www.luminotes.com]]
* [[TiddlyBackpack|http://www.tiddlybackpack.com]]
[[<< Back to FAQ list|TiddlyWiki FAQ]]
In this tiddler you put the text you wish to be displayed as the title of the page in the browser.
By default it is set to:
{{{
<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>
}}}
which could display something like:
{{{
shadowtiddlers - a tiddlywiki
}}}
You can change this at any time. For example:
{{{
Shadow Tiddlers Documentation | TiddlyWiki.com
}}}
The wikifyPlainText function takes the following parameters:
# text to wikify
# limit - if greater than 0 this will strip the text to a certain length
# the ''tiddler'' in the context of which the wikification should occur.
A TiddlyWiki is a single html file which can be saved to a hard drive, USB stick or server.
'''Save to hard drive'''
Click on Save Changes (right-hand top menu).
Name the file, select the location and click on Save.
The document will be saved with the specified name, location and an .html extension. When next opened it will display in the user's default browser.
'''Save to USB stick'''
Click on Save Changes (right-hand top menu).
Name the file, select USB stick drive as the location and click on Save.
The document will be saved with the specified name, location and an .html extension.
'''Save to Tiddlyspot'''
Click on Save to Web (top right-hand menu). A yellow dialog box appears which says "About to upload on <nowiki>http://tiddlywikiname.tiddlyspot.com/index.html..."</nowiki> It will say "Main TiddlyWiki file uploaded" when it's done.
This function gets the plain text from wikitext (i.e. it strips the wikitext markup and returns just the text). It does this by wikifying into a hidden div using the [[Wikifier.prototype.subWikify()]] function, and calling [[getPlainText()]] on the hidden div. It then removes the hidden div and returns the text.
It takes no arguments
{{annotation{
NOTE: this doesn't return html
}}}
Including is the act of combining one or more spaces.
See [[How do I include/exclude spaces?]]@faq
In case of a problem, [[disabling all plugins|PluginManager]] -- both in [[TiddlyWiki]] and in the browser -- is the first step in identifying the cause. If the problem has disappeared then, re-enabling all plugins ''one at a time'' helps identifying the exact cause of the problem.
Creating a fresh browser profile (e.g. [[with Firefox|http://kb.mozillazine.org/Profile_Manager]]) might help as well.
When encountering a [[Plugin]] error, the [[plugin manager]] will automatically be displayed on startup, highlighting the problematic plugin and presenting an error message.
When encountering a [[macro]] error (e.g. "<<[''...'']>>"), clicking on the error message will reveal more details that are helpful in identifying the issue.
! Community Support
The [[TiddlyWike community|http://groups.google.com/group/TiddlyWiki]] is always glad to help out.
Please provide
* a concise description of the problem
* if applicable, the exact error messages
* step-by-step instructions for reproducing the issue
* system information
** TiddlyWiki [[version number|version]]
** relevant plugins (with links)
** operating system
** browser version (and extensions, if any)
** working online (via HTTP) or local (document on hard drive)
* if possible, a [[minimal test case|http://webkit.org/quality/reduction.html minimal test case]] (a sample document illustrating the issue, using as few components as possible). [[Tiddlyspot]] and [[TiddlySpace]] provide free hosting for TiddlyWiki documents.
''Note:'' It is advised to use a descriptive topic title and provide a ''concise'' description of the problem. Unrelated problems should be discussed in separate threads.
[[Eric says|http://groups.google.com/group/tiddlywiki/browse_thread/thread/5ac0d9749df4958c/89339ebfe98624f4?#89339ebfe98624f4]]:
> In order to test in any kind of useful way, I need a //minimal// test case that demonstrates the problem //and// eliminates as many causes as possible. Typically this is done by installing the suspected plugin "in an empty TW", [...] so that I can immediately try a //simple// test case, without needing to suss what the rest of the document is about or how it has been customized. Of course, some problems aren't reproducible with a simple test case, so the fully- customized document //must// be used, but this should be avoided if at all possible.
[[FND says|http://groups.google.com/group/TiddlyWiki/msg/7d674a17d6a39898 FND]]:
<<<
Generally speaking, there are a variety of reasons which could result in lack of feedback, e.g.
* bad timing: we might simply have missed your post (e.g. due to stress, holidays etc.) - bumping the thread after a few days usually helps
* reproducibility: it's important for us to have all the details we need to properly analyze the problem (cf. http://tiddlywiki.org/wiki/Troubleshooting)
* unclear expectations: sometimes it's not immediately obvious what the question is (also see below)
* mixing topics: separate issues should be discussed separate threads - this also helps recognizing which issues are still unsolved
* excessive verbosity: concise posts often have better chances of getting a response (AKA TLDR... ); while the personal background story might be (and indeed, often is) interesting, it's usually secondary to the actual issue
<<<
!See Also
* [[Safe Mode]]
* <<tag errors>>
* <<tag [[browser issues]]>>
Note this is a wrapper for the [[wikifyPlainText]] function.
The ''wikifyPlain'' global function renders an entire tiddler as plain text. It takes up to 3 parameters
# title of the tiddler who's text should be rendered.
# a [[TiddlyWiki]] store object
# a limit (maximum number of characters to generate).
and returns a string with the output.
It returns the rendered ''text'' - ''not the html''
Should two people edit the same tiddler at the same time, then the first change will be saved and the second [[user|User]] will see the error message "[[Edit Conflict]]". The second [[user|User]] may elect to reapply their changes to the latest revision of the tiddler, or discard their changes. The [[list of revisions|Revision]] (from the tiddler toolbar) should assist a user in making this decision.
Sometimes an edit conflict may occur if you are editing the same tiddler in the same space in two different browser windows/tabs.
In the case of an edit conflict a [[diff|http://en.wikipedia.org/wiki/Diff]] is provided to help generate the correct version of that tiddler.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="72 648 70 70"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
<g>
<path d="M 77.59005 669.34003 C 71.532745 681.90424 73.714462 697.4441 84.135193 707.86475
C 97.315445 721.0451 118.684715 721.0451 131.8649 707.86475
C 145.04515 694.68457 145.04515 673.31537 131.8649 660.13513
C 121.4441 649.7141 105.90419 647.53253 93.339905 653.5899 L 102.047455 662.2976
C 109.58637 660.2373 117.987976 662.16803 123.90997 668.08997
C 132.69673 676.8767 132.69673 691.12317 123.90997 699.90985
C 115.12313 708.6966 100.87699 708.6966 92.09012 699.90985
C 86.168266 693.98804 84.23744 685.58643 86.297653 678.04755 Z M 72 648 L 72 668.25 L 78.75 661.49957
L 99.00019 681.7502 L 105.750175 675.00006 L 85.50013 654.75012 L 92.249985 648 Z" fill="black"
class="glyph"/>
</g>
</g>
</svg>
Versions of TiddlyWiki before and including 2.6.3 are known to have an issue with the upgrade function. To upgrade these versions you will need to download an empty latest version of TiddlyWiki and import your content into it using the "import" function in the backstage.
# Download http://www.tiddlywiki.com/empty.zip (the latest TiddlyWiki version is in there).
# Make a copy of empty.html and either place it in the same directory as the TiddlyWiki you want to upgrade or give it the same name of the TiddlyWiki you want to upgrade and place it in a different directory.
# Load your new empty latest version of TiddlyWiki.
# Go to the backstage area and select import.
# Select the TiddlyWiki you want to have upgraded.
# Import everything from the old TiddlyWiki into this new latest version of TiddlyWiki.
# Save your changed TiddlyWiki and reload it.
# Should work.
This is inverse of the normal way of upgrading: instead of upgrading the core of your TiddlyWiki you are adding all the non-core content of your current TiddlyWiki into a new latest core of TiddlyWiki.
Once you have upgraded your TiddlyWiki to version 2.6.4 or later you will be able to upgrade to subsequent versions in the normal manner.
The ''Store'' is the name given to the instantiated [[TiddlyWiki Class]].
It is the object used to access, manipulate and create tiddlers
To create a permaview URL for all open tiddlers:
{{{
<<permaview>>
}}}
Displays as:
<<permaview>>
The TiddlyWiki class represents an entire TiddlyWiki. It is normally instantiated once, when the page is first loaded, into the global object ''store''. It has one notable property, ''dirty'', which is a boolean representing whether the TiddlyWiki contains unsaved changes.
!!Methods
* [[addNotification|TiddlyWiki.prototype.addNotification]]: hooks a function to changes in a tiddler
* [[clear|TiddlyWiki.prototype.clear]]: empties the TiddlyWiki
* [[createTiddler|TiddlyWiki.prototype.createTiddler]]: instantiates a new tiddler
* [[removeTiddler|TiddlyWiki.prototype.removeTiddler]]: removes an existing tiddler
* [[fetchTiddler|TiddlyWiki.prototype.fetchTiddler]]: retrieves a Tiddler object
* [[filterTiddlers|TiddlyWiki.prototype.filterTiddlers]]: retrieve a filtered list of tiddlers
* [[forEachTiddler|TiddlyWiki.prototype.forEachTiddler]]: executes a function on each tiddler
* [[getMissingLinks|TiddlyWiki.prototype.getMissingLinks]]: retrieves a list of missing links
* [[getOrphans|TiddlyWiki.prototype.getOrphans]]: retrieves a list of orphaned tiddlers
* [[getRecursiveTiddlerText|TiddlyWiki.prototype.getRecursiveTiddlerText]]: retrieves tiddler source code, replacing links with source code
* [[getReferringTiddlers|TiddlyWiki.prototype.getReferringTiddlers]]: finds tiddlers that refer to a particular tiddler
* [[getShadowed|TiddlyWiki.prototype.getShadowed]]: returns an array of all shadow tiddlers available
* [[getTags|TiddlyWiki.prototype.getTags]]: retrieves a list of all tags used in the TiddlyWiki
* [[getTiddlerText|TiddlyWiki.prototype.getTiddlerText]]: returns the source code of a tiddler
* [[getTiddlers|TiddlyWiki.prototype.getTiddlers]]: returns all tiddlers sorted by a criteria
* [[isDirty|TiddlyWiki.prototype.isDirty]]: returns whether there are unsaved changes to the TiddlyWiki
* [[isShadowTiddler|TiddlyWiki.prototype.isShadowTiddler]]: returns whether a tiddler is shadowed
* [[loadFromDiv|TiddlyWiki.prototype.loadFromDiv]]: initializes a TiddlyWiki from saved HTML
* [[.notify|TiddlyWiki.prototype.notify]]: invoke notification handlers for a tiddler
* [[notifyAll|TiddlyWiki.prototype.notifyAll]]: invoke all notification handlers
* [[resumeNotifications|TiddlyWiki.prototype.resumeNotifications]]: resumes update notifications
* [[reverseLookup|TiddlyWiki.prototype.reverseLookup]]: finds all tiddlers matching a criteria
* [[saveTiddler|TiddlyWiki.prototype.saveTiddler]]: saves changes to a tiddler
* [[search|TiddlyWiki.prototype.search]]: search for tiddlers whose source code contains a string
* [[setDirty|TiddlyWiki.prototype.setDirty]]: sets the TiddlyWiki's dirty flag
* [[TiddlyWiki.prototype.suspendNotifications|TiddlyWiki.prototype.suspendNotifications]]: halts update notifications
* [[tiddlerExists|TiddlyWiki.prototype.tiddlerExists]]: returns whether a tiddler exists
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>TiddlySpace Apps</title>
<link rel="stylesheet" href="/bags/common/tiddlers/reset.css" />
<link rel="stylesheet" href="/bags/common/tiddlers/appspage.css" />
<!--[if lt IE 7 ]>
<link rel="stylesheet" href="/bags/common/tiddlers/appspageie6.css" />
<![endif]-->
</head>
<body>
<div id="wrapper">
<div id="TSbar"></div>
<div id="main-content">
<div id="space-details">
<a href="/_space"><img class="siteicon"></a>
<div id="title-subtitle">
<h1 class="spaceaddress">
<span class="spaceName"></span><span class="hostName"></span>
</h1>
<p class="tagline"><span class="subTitle"></span><a class="managespaces" href="/_space">manage space</a></p>
</div>
</div>
<div id="holder">
<div id="appswitcher-wrapper">
<div id="appswitcher">
<h2>Your Apps</h2>
<ul id="app-list">
<li class="write"><a href="/takenote">
<img src="/bags/common/tiddlers/pencil_blue.png" alt="Icon for Takenote" class="app-img" />
WRITE
</a>
</li>
<li class="htmlserialisation">
<a href="/tiddlers.html?select=tag:!excludeLists;sort=-modified">
<img src="/bags/common/tiddlers/browse_read_blue.png" alt="Icon for the HTML Serialisation" class="app-img" />
BROWSE
</a>
</li>
<li class="links">
<a href="/links">
<img src="/bags/common/tiddlers/share_blue.png" alt="Icon for the Links App" class="app-img" />
SHARE
</a>
</li>
<li class="tiddlywiki">
<a href="/tiddlers.wiki">
<img src="/bags/common/tiddlers/tiddlywiki2_blue.png" alt="Icon for TiddlyWiki" class="app-img" />
TIDDLYWIKI
</a>
</li>
</ul>
<div id="addapp">
<button class="inactive">Add More!</button>
</div>
</div>
<div id="app-desc">
<ul>
<li class="writedesc"><p>write your notes on the web. Link them, tag them, share them. Your notes are available everywhere, on and offline.</p></li>
<li class="htmlserialisationdesc"><p>an easy to understand HTML representation of your content.</p></li>
<li class="linksdesc"><p>share direct links to your content. The share app provides you with quick and easy access to the key links within your TiddlySpace.</p></li>
<li class="tiddlywikidesc"><p>use TiddlyWiki to create, edit and organise your content.</p></li>
</ul>
</div>
<div style="clear: both;"></div>
</div>
</div>
</div>
<div id="footer"><!-- ie doesn't support footer tag -->
<div id="footer-content">
<div class="links">
<a href="http://blog.tiddlyspace.com">blog</a>
<a href="http://featured.tiddlyspace.com">featured</a>
<a href="http://docs.tiddlyspace.com">documentation</a>
<a href="https://github.com/TiddlySpace/tiddlyspace">source</a>
</div>
<p>TiddlySpace 2011, created by <a href="http://osmosoft.com">Osmosoft</a></p>
</div>
</div>
</div>
<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
<script type="text/javascript" src="/bags/common/tiddlers/jquery.js"></script>
<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
<script type="text/javascript" src="/bags/common/tiddlers/chrjs-store.js"></script>
<script type="text/javascript" src="/bags/common/tiddlers/jquery-json.js"></script>
<script type="text/javascript" src="/bags/common/tiddlers/appspage.js"></script>
</body>
</html>
<!--{{{-->
<div class='header'>
<div id='sidebarSearch'>
<span macro='search'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='clearFloat'></div>
</div>
<div id='menuBar'>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<!--}}}-->
//{{{
(function($){
var macro = config.macros.originalSource = {
handler: function(place, macroName, params, wikifier, paramString, tiddler){
if(tiddler.fields['info_source']) {
wikify("Original Source: %0".format(tiddler.fields['info_source']), place);
}
}
};
})(jQuery);
//}}}
You, as a someone who has [[Registered]] with [[TiddlySpace]] are a User.
The TabTimeline tiddler contains a command to list in reverse chronological the tiddlers in your TiddlyWiki
{{{
<<timeline>>
}}}
In TiddlyWiki this list appears as default in the {{{Recent}}} tab on the right-hand menu.
Edit the EditTemplate tiddler.
To create a chronological list of recent edits:
{{{
<<timeline field maxlength dateformat template:title groupTemplate:title filter:filter>>
}}}
All the parameters are optional:
* ''field'' determines which field to use as the basis for the list. It is usually {{{modified}}} or {{{created}}}
* ''maxlength'' is an integer that limits the maximum number of tiddlers to include in the list
* ''dateformat'' is a [[date format string|Date Formats]] that determines the format of the dates
* ''template'' names the tiddler to use as the template for list entries
** The default template is {{{<<view title link>>}}} to cause the display of the tiddler title as a link to the tiddler
* ''groupTemplate'' names the tiddler to use as the template for grouping entries in the list
** The default groupTemplate is {{{<<view %0 date '%1'>>}}}, where {{{%0}}} is the name of the field being displayed and {{{%1}}} is the ''dateformat'' selected in the third argument
* ''filter'' is a tiddler filter that is used to filter the tiddlers that appear in the list
For example:
{{{
<<timeline created 5>>>
}}}
displays as:
<<timeline created 5>>
{{{
<<timeline modified 5>>
}}}
displays as:
<<timeline modified 5>>
This tiddler contains the mark up to display the page. You can change the mark up to create a custom view of the page.
By default it contains the following markup:
{{{
<!--{{{-->
<div class='header'>
<div id='sidebarSearch'>
<span macro='search'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='clearFloat'></div>
</div>
<div id='menuBar'>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<!--}}}-->
}}}
[[TiddlyWiki]] was not originally designed for multi-user collaboration; the single-file paradigm makes concurrent editing a challenging issue.
However, there are various solutions enabling TiddlyWiki to be used as a collaborative platform.
! Overview
Server-side solutions for [[TiddlyWiki]] provide ubiquitous access to hosted TiddlyWiki documents, and potentially enable multi-user collaboration on a single TiddlyWiki document.
There are a number of solutions, each suited to specific needs:
| Name | Description | Requirements | Multi-User Support | Revision History | Status |h
|[[ccTiddly]] | |PHP and MySQL |yes |yes |''unknown'' |
|[[Coral]] | |Java | | |''unknown'' |
|[[GieWiki]] |Hopes to include all the features you would expect in a community wiki engine, runs on Google App Engine |Python, [[Google App Engine SDK|http://code.google.com/intl/da/appengine/downloads.html]] |yes |yes |actively developed, currently (2011-07-22) at version 1.13.1 |
|[[MiniTiddlyServer]] | |PHP |no |no (regular TiddlyWiki backups only) |abandoned |
|[[MyWiki|http://aasted.org/wiki/]] |Needs no database. Works out of box. |PHP |No |No |Abandoned. Last version in 2004|
|[[PrinceTiddlyWiki]] | | | | |abandoned |
|[[PhpTiddlyWiki]] ([[fixed version|http://www.borism.net/2009/03/18/server-side-tiddlywiki-with-php-easy/]]) | |PHP | | |abandoned |
|[[ServerLockPlugin]] |prevent overwriting changes (simultaneous editing) when using a TiddlyWiki document stored on a remote server |PHP |yes (prevents simultaneous editing) |no (regular TiddlyWiki backups only) |''unknown'' |
|[[TiddlyHome]] | |PHP |yes |yes |actively maintained |
|[[TiddlyLock]] |prevent overwriting changes (simultaneous editing) when using a TiddlyWiki document over a shared network drive |network share |yes (prevents simultaneous editing)|no (regular TiddlyWiki backups only) |''unknown'' |
|[[TiddlyWeb]] |reference implementation of a server-side API where individual tiddlers can be used in lots of different wikis |Python |yes |yes |actively developed and maintained |
|[[UploadPlugin]] |upload TiddlyWiki document |PHP |no |no (regular TiddlyWiki backups only) | actively maintained |
|[[version control systems|http://en.wikipedia.org/wiki/Revision_control]] (e.g. Subversion, Git, Mercurial) |since version 2.2, TiddlyWiki is very much suitable to be used in conjunction with regular version control systems | |yes (to a limited extent) |yes | |
|[[WebDavPlugin]] |save TiddlyWiki to [[WebDav|http://en.wikipedia.org/wiki/WebDAV]] directory |WebDAV-enabled server |no |no (regular TiddlyWiki backups only) |''unknown'' |
|[[ZiddlyWiki]] | |Python, Zope |yes |yes |irregularly maintained |
! Hosting Services
* [[Tiddlyspot]] (based on UploadPlugin)
* [[TiddlySpace]] (based on TiddlyWeb)
* [[LimeBits|http://www.limebits.com]], a host for WebDAV-based open source applications including [[TiddlyWiki|http://www.limebits.com/apps/bitfinder/#url=/&tag=TiddlyWiki]] (based on WebDAVSavingPlugin)
! Other
* [[TiddlyHome 2.0|http://tiddlyhome2.bidix.info]]
* [[TiddlyHost|http://tiddlyhost.appspot.com]]
* [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]]
* [[ProjectWiki|http://github.com/diclophis/projectwiki/tree/master]]
! See Also
* [[Can I use TiddlyWiki as a multi-user/collaborative/server based wiki?]]
* [[I put my TiddlyWiki file on my web server and I can't save]]
{{{
createTiddlyDropDown(place,onchange,options,defaultValue)
}}}
The global function ''createTiddlyDropDown'' creates a DOM ''select'' element and populated by a list of ''option'' elements. This function takes four parameters:
; place
: the DOM element where the ''select'' element will be placed.
; onchange
: a callback function to be called when a check box changed event occurs.
; options
: an ''Array'' containing the names of each ''option'' element. The ''name'' also serves as the element's label.
; defaultValue
: the ''name'' of the option that will be the select element's default value.
/***
|''Name:''|TiddlySpaceLinkPlugin|
|''Description:''|Formatter to reference other spaces from wikitext |
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com) |
|''Source:''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceLinkPlugin.js|
|''Version:''|1.4.2|
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.4|
!!Documentation
This plugin provides wikitext formatters for referencing another [[space|Space]] on the same TiddlySpace server, as in the following examples:
<<<
{{{@space}}} -- @space
{{{~@space}}} -- ~@space
{{{Tiddler@space}}} -- Tiddler@space
{{{[[Tiddler Title]]@space}}} -- [[Tiddler Title]]@space
{{{[[Link text|Tiddler Title]]@space}}} -- [[Link text|Tiddler Title]]@space
<<<
Links to tiddlers with a title begining with an "@" remain as tiddlyLinks:
<<<
{{{[[@tiddler]]}}} -- [[@tiddler]]
<<<
and these may be changed into a space link using {{{@@}}}:
<<<
{{{[[@@space]]}}} -- [[@@space]]
{{{[[Link to an another space|@@space]]}}} -- [[Link to another space|@@space]]
{{{[[@space|@@space]]}}} -- [[@space|@@space]]
<<<
TiddlySpace includes the [[TiddlySpaceLinkPlugin]] which provides WikiText markup for linking to other spaces on the same server. For example @glossary is a link to the {{{glossary}}} space and [[Small Trusted Group]]@glossary a link to an individual tiddler in the @glossary space. Prefixing the link with a tilde escapes the link, for example {{{~@space}}}.
Email addresses, for example joe.bloggs@example.com and mary@had.a.little.lamb.org should be unaffected.
!!Features
The plugin provides external links decorated so that other plugins may be included to add features such as the ability to dynamically pull externally linked tiddlers into the current TiddlyWiki.
Wikitext linking to a space on another server, for example from a tiddler in a space on tiddlyspace.com to a tiddler or a space on example.com, isn't currently supported.
!!Code
***/
//{{{
/*jslint onevar: false nomen: false plusplus: false */
/*global jQuery config createTiddlyText createExternalLink createTiddlyLink */
function createSpaceLink(place, spaceName, title, alt, isBag) {
var link, a, currentSpaceName, label;
try {
if (spaceName === config.extensions.tiddlyspace.currentSpace.name) {
title = title || spaceName;
a = createTiddlyLink(place, title, false);
jQuery(a).text(alt || title);
return a;
}
} catch (ex1) {
currentSpaceName = false;
}
a = jQuery("<a />").addClass('tiddlySpaceLink externalLink').appendTo(place)[0];
if(title) {
jQuery(a).attr('tiddler', title);
}
if(isBag) {
jQuery(a).attr('bag', spaceName);
} else {
jQuery(a).attr('tiddlyspace', spaceName);
}
config.extensions.tiddlyweb.getStatus(function(status) {
link = status.server_host.url;
if (title) {
label = alt || title;
link = link + "/" + encodeURIComponent(title);
} else {
label = alt || spaceName;
}
// assumes a http URI without user:pass@ prefix
if(!isBag) {
link = link.replace("http://", "http://" + spaceName.toLowerCase() + ".");
} else {
link += "/bags/" + spaceName + "/tiddlers.wiki";
}
jQuery(a).attr("href", link).text(label);
});
return a;
}
(function ($) {
config.textPrimitives.spaceName = "[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9]";
config.textPrimitives.spaceNameStrict = "[a-z][a-z0-9-]*";
config.textPrimitives.bareTiddlerLetter = config.textPrimitives.anyLetterStrict;
config.formatters.splice(0, 0, {
name: "spacenameLink",
match: config.textPrimitives.unWikiLink + "?" + config.textPrimitives.bareTiddlerLetter + "*@" + config.textPrimitives.spaceName + "\\.?.?",
lookaheadRegExp: new RegExp(config.textPrimitives.unWikiLink + "?(" + config.textPrimitives.bareTiddlerLetter + "*)@(" + config.textPrimitives.spaceName + ")", "mg"),
handler: function (w) {
if (w.matchText.substr(w.matchText.length - 2, 1) === '.' && w.matchText.substr(w.matchText.length - 1, 1).match(/[a-zA-Z]/)) {
w.outputText(w.output, w.matchStart, w.nextMatch);
return;
}
if (w.matchText.substr(0, 1) === config.textPrimitives.unWikiLink) {
w.outputText(w.output, w.matchStart + 1, w.nextMatch);
return;
}
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
createSpaceLink(w.output, lookaheadMatch[2], lookaheadMatch[1]);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: "tiddlySpaceLink",
match: "\\[\\[[^\\|\\]]*\\|*@@" + config.textPrimitives.spaceName + "\\]",
lookaheadRegExp: new RegExp("\\[\\[(.*?)(?:\\|@@(.*?))?\\]\\]", "mg"),
handler: function (w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
var alt = lookaheadMatch[2] ? lookaheadMatch[1] : lookaheadMatch[1].replace(/^@@/, "");
var space = lookaheadMatch[2] || alt;
createSpaceLink(w.output, space, "", alt);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: "tiddlyLinkSpacenameLink",
match: "\\[\\[[^\\[]*\\]\\]@",
lookaheadRegExp: new RegExp("\\[\\[(.*?)(?:\\|(.*?))?\\]\\]@(" + config.textPrimitives.spaceName + ")", "mg"),
handler: function (w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
var title = lookaheadMatch[2] || lookaheadMatch[1];
var alt = lookaheadMatch[1] || lookaheadMatch[2];
createSpaceLink(w.output, lookaheadMatch[3], title, alt);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
});
// ensure space links don't appear as missing links
config.textPrimitives.brackettedLink = "\\[\\[([^\\]][^@\\]][^\\]]*)\\]\\](?=[^@])";
config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\](?=[^@])";
// reevaluate derrived expressions ..
config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
config.textPrimitives.brackettedLink + ")|(?:" +
config.textPrimitives.urlPattern + ")","mg");
config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
config.textPrimitives.titledBrackettedLink + ")|(?:" +
config.textPrimitives.brackettedLink + ")|(?:" +
config.textPrimitives.urlPattern + ")","mg");
// treat space links in titledBracketedLink as external links
var missingTiddlySpaceLink = new RegExp("^@@" + config.textPrimitives.spaceName + "$", "");
var isExternalLink = config.formatterHelpers.isExternalLink;
config.formatterHelpers.isExternalLink = function(link) {
return missingTiddlySpaceLink.test(link) || isExternalLink(link);
};
}(jQuery));
//}}}
This message is displayed by Firefox whenever some javascript is taking a long time to run. It can happen with a TiddlyWiki file if you have a lot of tiddlers or are using some plugins that do some extra work that takes a long time. You can get rid of the messages by making Firefox's maximum script run time a little longer. Here's how it's done:
* Type about:config in the address bar and press enter.
* Scroll down until you see dom.max_script_run_time
* Double click it and type in 20 seconds (the default is 5 seconds)
By default, selecting 'save changes' will also create a backup copy (by default) of the TiddlyWiki in the same folder as the TiddlyWiki file itself. To avoid the folder filling up with copious backup files, you can create a folder for them.
* Go to 'options' on the right-hand top menu ([[Sidebar]]),
* Click on '[[AdvancedOptions]]',
* Where it says 'name of folder to use for backups', type in a name for the folder (not the address of the folder),
* Close the AdvancedOptions tiddler.
Go to the folder you keep your TiddlyWiki in. You should now see a new folder with the name you just specified. From now on backups will be stored in this new folder.
The path is relative to the directory where the wiki is saved. For Windows computers, use the Windows backslash path separator (\).
To turn off the automatic backup function, got to 'options' and untick [[AutoSave]].
'' See Also ''
* [[AdvancedOptions]]
* [[AutoSave]]
* [[Sidebar]]
[[Category:FAQ]]
[[Category:Using TiddlyWiki]]
Following is a mechanism in TiddlySpace that allows you to monitor [[tiddlers|Tiddler]] from spaces of interest without [[including|Including]]. To follow a space foo create a tiddler called {{{@foo}}} tagged with follow in your [[Home Space]].
See [[What is following?]]@faq
!Ordered Lists
Lists can be ordered with numbers and letters:
{{{
#List item one
##List item two
###List item three
}}}
Displays as:
#List item one
##List item two
###List item three
!Unordered Lists
Lists can be unordered:
{{{
*Unordered List Level 1
**Unordered List Level 2
***Unordered List Level 3
}}}
Displays as:
*Unordered List Level 1
**Unordered List Level 2
***Unordered List Level 3
!Definition Lists
Definition lists can also be created:
{{{
;Title 1
:Definition of title 1
;Title 2
:Definition of title 2
}}}
Displays as:
;Title 1
:Definition of title 1
;Title 2
:Definition of title 2
See also [[Tagging Macro]]
Startup parameters (also called "paramifiers") are invoked from the URL when opening a [[TiddlyWiki]] document.
They are marked by a preceding hash character (#).
|! Name|! Key|! Description|
|permalink|list of tiddler names|cf. [[Permaview]], [[Permalink]]|
|[[Safe Mode]]|<nowiki>start:safe</nowiki>|opens the document in [[Safe Mode]]|
|[[readOnly]] mode|<nowiki>readOnly:[yes|no]</nowiki>|enable or disable [[readOnly]] mode|
|display tiddler|open:[title]|opens the tiddler with the specified title|
|select [[theme]]|theme:[name]|selects the specified theme|
|display tagged tiddlers|tag:[name]|displays tiddlers tagged with the specified tag|
|display filtered tiddlers|filter:[expression]|displays tiddlers matching the specified [[filter]] expression|
|search|search:[text]|performs a search for the specified text|
|new tiddler|newTiddler:[title]|creates a new tiddler with the specified title, opening it in [[edit mode]]|
|new journal entry|newJournal:[dateFormat]|creates a new journal entry with the specified [[timestamps|date format]]|
'' External Resources ''
* [[StartupParameters|http://www.tiddlywiki.com/#StartupParameters]]
The current places of discussions are google groups:
* [[TiddlyWiki|http://groups.google.com/group/tiddlywiki]] -- for TiddlyWiki users (general issues and progress)
* [[TiddlyWikiDev|http://groups.google.com/group/tiddlywikidev/]] -- for extensions and core developers and contributors (and other coding)
* [[TiddlySpace|http://groups.google.com/group/tiddlyspace]] -- for TiddlySpace users
* [[TiddlyWeb|http://groups.google.com/group/tiddlyweb]] -- for TiddlySpace, TiddlyWeb and TiddlyWeb extensions' developers and contributors
This is a method of the TiddlyWiki class.
It takes 1 parameter, the name of a tiddler. E.g.
{{{
story.tiddlerId('getOrphans()');
}}}
It will return the HTML tiddler element's id. More often than not this is the name of the tiddler prepended with ''tiddler''. E.g.
{{{
"tiddlergetOrphans()"
}}}
The HtmlCss tiddler overrides the default css of the html [[serialization]] of a space. For this to work it must have the [[custom field|Custom Fields]] ''server.content-type'' set to ''text/css'' and must contain recognised css definitions.
Note [[transclusions]] cannot be used in the HtmlCss tiddler.
The //chooseTemplateForTiddler// method of the [[Story class]] returns the name of a template for a tiddler view. It takes two parameters:
* the title of the tiddler
* a constant corresponding to the type of template to use
The second parameter may be omitted, in which case //~DEFAULT_VIEW_TEMPLATE// is assumed.
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
The global function ''createTiddlyElement'' creates a DOM element. This function takes five parameters:
* the parent DOM element to add the new element to
* the type of element to create. This is a lowercase string matching the name of the HTML tag you'd like to create -- so, for example, to create a div element, you'd pass 'div'.
* the DOM id to give the element.
* the CSS class to give the element.
* text to put inside the element.
Any of these parameters may be null. This function returns the created DOM element.
The ''permaView'' method of the [[Story]] class changes the browser's address bar so that it is a permalink to all open tiddlers. This method takes no parameters.
For example, if we hit the permaview button whilst having just this tiddler open the address bar will change from
{{{
http://tiddlywikidev.tiddlyspace.com/
}}}
to
{{{
http://tiddlywikidev.tiddlyspace.com/#Permaview
}}}
<<list filter [server.content-type[text/html]]>>
Many of [[TiddlyWiki]]'s default configuration settings are stored in built-in "shadow" tiddlers.
These are tiddlers that are "preloaded" with default contents.
A list of all shadow tiddlers is available through the [[sidebar]]'s ''More'' > ''Shadowed'' tab (using the [[list]] macro). (In [[mGSD]]'s sidebar, the list is under ''More...'' > ''TW'' > ''More'' > ''Shad''.)
Regular tiddlers take precedence over shadow tiddlers.
Thus default contents can be modified or overridden by editing the respective shadow tiddler (which automatically creates a regular tiddler of the same name).
A shadow tiddler's default contents can be restored by deleting or renaming the respective regular tiddler.
'' Default Shadow Tiddlers ''
|Shadow Tiddler|Default value|Description|h
|>|>|User Setup|h
|[[SiteTitle]]|My TiddlyWiki|Defines the first part of the page title|
|[[SiteSubtitle]]|a reusable non-linear personal web notebook|Defines a SubTitle for the page This shadow tiddler is used as the second part of the page title|
|[[WindowTitle]]<br>(new in v.2.6)|<nowiki><<tiddler SiteTitle>> - <<tiddler SiteSubtitle>></nowiki>|Defines the title of the browser window|
|[[SiteUrl]]|http://www.tiddlywiki.com/|Identifies the full target URL for publication|
|[[DefaultTiddlers]]|[[GettingStarted]]|The tiddlers listed in this shadow tiddler will be automatically displayed when TiddlyWiki starts up|
|[[GettingStarted]]|See [[GettingStarted]]|Provides basic usage instructions for setting up a TiddlyWiki page|
|[[MainMenu]]|[[GettingStarted]]|Defines the contents of the main menu, by default in the left-hand column of the screen|
|>|>|Advanced Setup|h
|[[MarkupPreHead]]|<nowiki><link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/></nowiki>|The contents of this tiddler are inserted at the top of the <head> section of the TiddlyWiki HTML file|
|[[MarkupPostHead]]||The contents of this tiddler - empty by default - are inserted at the bottom of the <head> section of the TiddlyWiki HTML file|
|[[MarkupPreBody]]||The contents of this tiddler - empty by default - are inserted at the top of the <body> section of the TiddlyWiki HTML file|
|[[MarkupPostBody]]||The contents of this tiddler - empty by default - are inserted at the bottom of the <body> section of the TiddlyWiki HTML file|
|>|>|Import & Plugins|h
|[[ImportTiddlers]]|<nowiki><<importTiddlers>></nowiki>|This shadow tiddler provides access to [[Importing Tiddlers|importing tiddlers]]|
|[[PluginManager]]|<nowiki><<plugins>></nowiki>|Provides access to the plugin manager|
|>|>|Templates & Style Sheets|h
|[[PageTemplate]]|See [[PageTemplate]]|The HTML template in this shadow tiddler determines the overall TiddlyWiki layout|
|[[ViewTemplate]]|See [[ViewTemplate]]|The HTML template in this shadow tiddler determines how tiddlers look|
|[[EditTemplate]]|See [[EditTemplate]]|The HTML template in this shadow tiddler determines how tiddlers look while they are being edited|
|[[ColorPalette]]|See [[ColorPalette]]|These values in this shadow tiddler determine the colour scheme of the TiddlyWiki user interface|
|[[StyleSheetLayout]]|See [[StyleSheetLayout]]|This shadow tiddler contains CSS definitions related to the layout of page elements. DO NOT EDIT THIS TIDDLER, instead make your changes in the [[StyleSheet]] shadow tiddler.|
|[[StyleSheetColors]]|See [[StyleSheetColors]]|This shadow tiddler contains CSS definitions related to the color of page elements. DO NOT EDIT THIS TIDDLER, instead make your changes in the [[StyleSheet]] shadow tiddler.|
|[[StyleSheet]]||This tiddler - empty by default - can contain custom CSS definitions|
|[[StyleSheetPrint]]|See [[StyleSheetPrint]]|This shadow tiddler contains CSS definitions for printing|
|[[StyleSheetLocale]]|See [[StyleSheetLocale]]|This shadow tiddler contains CSS definitions related to the translation locale|
|>|>|SideBar Tabs|h
|[[SideBarOptions]]|See [[SideBarOptions]]|Used as the contents of the option panel in the right-hand sidebar|
|[[OptionsPanel]]|See [[OptionsPanel]]|Used as the contents of the options panel slider in the right-hand sidebar|
|[[AdvancedOptions]]|<nowiki><<option>></nowiki>>|Provides access to several advanced options|
|[[SideBarTabs]]|<nowiki><<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "Morelists" TabMore>></nowiki>|Used to define the tabs panel in the right-hand sidebar|
|[[TabTimeline]]|<nowiki><<timeline>></nowiki>|Displays all tiddlers in reverse chronological order, and by default is displayed as the 'Timeline' tab in the right-hand [[SideBar]]|
|[[TabAll]]|<nowiki><<list all>></nowiki>|Displays alphabetical list of all tiddlers - except for unedited [[Shadow Tiddlers]] and is included in [[SideBarTabs]] in the right-hand sidebar|
|[[TabTags]]|<nowiki><<allTags excludeLists>></nowiki>|Displays a list of all [[Tags]], and is included in [[SideBarTabs]] in the right-hand sidebar|
|[[TabMore]]|<nowiki><<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadowed" "Shadowedtiddlers" TabMoreShadowed>></nowiki>|Contains the contents of the 'More' tab in the right-hand sidebar|
|[[TabMoreMissing]]|<nowiki><<list missing>></nowiki>|Displays [[Missing Tiddlers]], and is included in [[TabMore]], displayed in the right-hand sidebar|
|[[TabMoreOrphans]]|<nowiki><<list orphans>></nowiki>|Displays [[Orphan Tiddlers]], and is included in [[TabMore]], displayed in the right-hand sidebar|
|[[TabMoreShadowed]]|<nowiki><<list shadowed>></nowiki>|Displays [[Shadow Tiddlers]], and is included in [[TabMore]], displayed in the right-hand sidebar|
'' See Also ''
* [[HTML Templates]]
* [[Style Sheets]]
* [[SiteTitle]] / [[SiteSubtitle]]
* [[Configuration Options]]
A ''getHours12'' method has been added to the Date object. Any date object will be able to return the current hour using a 12 hour clock.
The function can be use like this:
//{{{
var date = new Date();
date.getHour12();
//}}}
It would return {{{4}}}.
A [[space|Space]] may be thought of as a TiddlyWiki hosted on TiddlyWeb. Each space has a [[Space Name]] and comprises of tiddlers stored in two [[TiddlyWeb]] [[bags|Bag]]:
# A [[Private]] [[Bag]] named {{{spacename_private}}}
# A [[Public]] [[Bag]] named {{{spacename_public}}}
A [[Space]] may belong to an individual [[user]], such as the [[Home Space]] which is automatically generated when registering with TiddlySpace, or belong to a [[Small Trusted Group]] of [[Members|Member]].
A [[User]] and [[Plugin]] is at liberty to access and manipulate [[tiddlers|Tiddler]], [[recipes|Recipe]], [[bags|Bag]], using the [[TiddlyWeb]] [[HTTP API]].
This document will introduce you to TiddlyWiki and get you up to speed.
* [[About TiddlyWiki|TiddlyWiki]]
* [[Screencast: Introduction to TiddlyWiki|http://www.osmosoft.com/introduction]]
! What is TiddlyWiki?
{{annotation{TiddlyWiki is a single-file, self-contained wiki for managing micro-content, written in ~JavaScript.}}}
If you completely understand all of that sentence, you should go straight on to the next section. For the rest of us, read on for the longer explanation.
;It's a single file
:A complete TiddlyWiki is stored in a single file on your computer, and thus belongs to the class of [[Single Page Applications|http://en.wikipedia.org/wiki/Single_page_application]]. That makes it super-easy to move your TiddlyWiki around on a USB stick or by emailing it to yourself.
;It's self-contained
:The single file that is a TiddlyWiki contains not only all of your data, but all the machinery to edit and manipulate it. All you need is a modern web browser, like Mozilla Firefox, Google Chrome or Safari. You don't need to have any other special programs installed on your computer, and you don't need to be connected to the Internet.
:The same TiddlyWiki file will work on just about any computer: Windows PCs, Apple Macs, Linux and BSD boxes...
;It's a wiki
:A wiki is a collection of web pages, like a normal web site, except that every page can be edited, easily and immediately. Wiki systems are often used to collaboratively manage documentation for large projects, and also sometimes used by a single user as a kind of personal notebook.
;It manages micro-content
:Most web sites and wikis manage information as pages. TiddlyWiki is different -- it saves your stuff in smaller chunks (each chunk is called a 'tiddler'). Information in small chunks like this is called 'micro-content', and once you start usingTiddlyWiki, you realize that micro-content is a natural fit to a lot of the stuff you deal with every day.
To really get an idea of what TiddlyWiki can do for you, you're going to have to try it out. Don't worry -- it's a single file, remember. So go on to the next section and we will get started.
! Getting TiddlyWiki
Here's how to get TiddlyWiki:
''Step 1: Download the latest version''
The latest TiddlyWiki can be gotten by going to the [[download page|downloading TiddlyWiki]]. Follow the instructions to save it to your computer where it can be used.
Like it says on the page you're downloading from, if your browser lets you save pages in various formats, make sure you choose the plain HTML option. Remember where you saved it.
''Step 2: ?''
With apologies to [[Instiki|http://instiki.org/]], there //''is no step 2''// -- your TiddlyWiki is ready! Wanna see it? Go to the HTML file you saved in Step 1 and open it in your web browser. See? Ready to go. Leave it on screen, and you can jump right into the next section.
{{annotation{this thing about "no step 2" needs to be replaced with a walkthrough on getting TW past various security checks, like the unlock thing that you need to do with WinXP SP2, with a particular focus on win/IE. If anyone can post me the steps required for particular os/browser combinations, I'd be much obliged :)}}}
''Step 3: Profit!''
cf. [[Wikipedia|http://en.wikipedia.org/wiki/Gnomes_%28South_Park_episode%29#The_Gnomes]]
!Using TiddlyWiki
* [[TiddlyWiki User's Guide|http://danielbaird.com/tiddlywikiguides/userguide-sample.html#"TiddlyWiki User's Guide"]]
* [[Introduction to TiddlyWiki|http://www.slideshare.net/guest102a23/an-introduction-to-tiddlywiki-revised/]] (slides)
/***
|''Name''|ServerSideSavingPlugin|
|''Description''|server-side saving|
|''Author''|FND|
|''Version''|0.6.5|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/ServerSideSavingPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.3|
|''Keywords''|serverSide|
!Notes
This plugin relies on a dedicated adaptor to be present.
The specific nature of this plugin depends on the respective server.
!Revision History
!!v0.1 (2008-11-24)
* initial release
!!v0.2 (2008-12-01)
* added support for local saving
!!v0.3 (2008-12-03)
* added Save to Web macro for manual synchronization
!!v0.4 (2009-01-15)
* removed ServerConfig dependency by detecting server type from the respective tiddlers
!!v0.5 (2009-08-25)
* raised CoreVersion to 2.5.3 to take advantage of core fixes
!!v0.6 (2010-04-21)
* added notification about cross-domain restrictions to ImportTiddlers
!To Do
* conflict detection/resolution
* rename to ServerLinkPlugin?
* document deletion/renaming convention
!Code
***/
//{{{
(function($) {
readOnly = false; //# enable editing over HTTP
var plugin = config.extensions.ServerSideSavingPlugin = {};
plugin.locale = {
saved: "%0 saved successfully",
saveError: "Error saving %0: %1",
saveConflict: "Error saving %0: edit conflict",
deleted: "Removed %0",
deleteError: "Error removing %0: %1",
deleteLocalError: "Error removing %0 locally",
removedNotice: "This tiddler has been deleted.",
connectionError: "connection could not be established",
hostError: "Unable to import from this location due to cross-domain restrictions."
};
plugin.sync = function(tiddlers) {
tiddlers = tiddlers && tiddlers[0] ? tiddlers : store.getTiddlers();
$.each(tiddlers, function(i, tiddler) {
var changecount = parseInt(tiddler.fields.changecount, 10);
if(tiddler.fields.deleted === "true" && changecount === 1) {
plugin.removeTiddler(tiddler);
} else if(tiddler.isTouched() && !tiddler.doNotSave() &&
tiddler.getServerType() && tiddler.fields["server.host"]) { // XXX: server.host could be empty string
delete tiddler.fields.deleted;
plugin.saveTiddler(tiddler);
}
});
};
plugin.saveTiddler = function(tiddler) {
try {
var adaptor = this.getTiddlerServerAdaptor(tiddler);
} catch(ex) {
return false;
}
var context = {
tiddler: tiddler,
changecount: tiddler.fields.changecount,
workspace: tiddler.fields["server.workspace"]
};
var serverTitle = tiddler.fields["server.title"]; // indicates renames
if(!serverTitle) {
tiddler.fields["server.title"] = tiddler.title;
} else if(tiddler.title != serverTitle) {
return adaptor.moveTiddler({ title: serverTitle },
{ title: tiddler.title }, context, null, this.saveTiddlerCallback);
}
var req = adaptor.putTiddler(tiddler, context, {}, this.saveTiddlerCallback);
return req ? tiddler : false;
};
plugin.saveTiddlerCallback = function(context, userParams) {
var tiddler = context.tiddler;
if(context.status) {
if(tiddler.fields.changecount == context.changecount) { //# check for changes since save was triggered
tiddler.clearChangeCount();
} else if(tiddler.fields.changecount > 0) {
tiddler.fields.changecount -= context.changecount;
}
plugin.reportSuccess("saved", tiddler);
store.setDirty(false);
} else {
if(context.httpStatus == 412) {
plugin.reportFailure("saveConflict", tiddler);
} else {
plugin.reportFailure("saveError", tiddler, context);
}
}
};
plugin.removeTiddler = function(tiddler) {
try {
var adaptor = this.getTiddlerServerAdaptor(tiddler);
} catch(ex) {
return false;
}
var context = {
host: tiddler.fields["server.host"],
workspace: tiddler.fields["server.workspace"],
tiddler: tiddler
};
var req = adaptor.deleteTiddler(tiddler, context, {}, this.removeTiddlerCallback);
return req ? tiddler : false;
};
plugin.removeTiddlerCallback = function(context, userParams) {
var tiddler = context.tiddler;
if(context.status) {
if(tiddler.fields.deleted === "true") {
store.deleteTiddler(tiddler.title);
} else {
plugin.reportFailure("deleteLocalError", tiddler);
}
plugin.reportSuccess("deleted", tiddler);
store.setDirty(false);
} else {
plugin.reportFailure("deleteError", tiddler, context);
}
};
plugin.getTiddlerServerAdaptor = function(tiddler) { // XXX: rename?
var type = tiddler.fields["server.type"] || config.defaultCustomFields["server.type"];
return new config.adaptors[type]();
};
plugin.reportSuccess = function(msg, tiddler) {
displayMessage(plugin.locale[msg].format([tiddler.title]));
};
plugin.reportFailure = function(msg, tiddler, context) {
var desc = (context && context.httpStatus) ? context.statusText :
plugin.locale.connectionError;
displayMessage(plugin.locale[msg].format([tiddler.title, desc]));
};
config.macros.saveToWeb = { // XXX: hijack existing sync macro?
locale: { // TODO: merge with plugin.locale?
btnLabel: "save to web",
btnTooltip: "synchronize changes",
btnAccessKey: null
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
createTiddlyButton(place, this.locale.btnLabel, this.locale.btnTooltip,
plugin.sync, null, null, this.locale.btnAccessKey);
}
};
// hijack saveChanges to trigger remote saving
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
if(window.location.protocol == "file:") {
_saveChanges.apply(this, arguments);
} else {
plugin.sync(tiddlers);
}
};
// override removeTiddler to flag tiddler as deleted -- XXX: use hijack to preserve compatibility?
TiddlyWiki.prototype.removeTiddler = function(title) { // XXX: should override deleteTiddler instance method?
var tiddler = this.fetchTiddler(title);
if(tiddler) {
tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"];
tiddler.text = plugin.locale.removedNotice;
tiddler.fields.deleted = "true"; // XXX: rename to removed/tiddlerRemoved?
tiddler.fields.changecount = "1";
this.notify(title, true);
this.setDirty(true);
}
};
// hijack ImportTiddlers wizard to handle cross-domain restrictions
var _onOpen = config.macros.importTiddlers.onOpen;
config.macros.importTiddlers.onOpen = function(ev) {
var btn = $(resolveTarget(ev));
var url = btn.closest(".wizard").find("input[name=txtPath]").val();
if(window.location.protocol != "file:" && url.indexOf("://") != -1) {
var host = url.split("/")[2];
var macro = config.macros.importTiddlers;
if(host != window.location.host) {
btn.text(macro.cancelLabel).attr("title", macro.cancelPrompt);
btn[0].onclick = macro.onCancel;
$('<span class="status" />').text(plugin.locale.hostError).insertAfter(btn);
return false;
}
}
return _onOpen.apply(this, arguments);
};
})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceToolbar|
|''Description''|augments tiddler toolbar commands with SVG icons|
|''Author''|Osmosoft|
|''Version''|0.6.6|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceToolbar.js|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.0|
|''Requires''|ImageMacroPlugin|
|''Keywords''|toolbar icons SVG|
!Description
replaces tiddler toolbar commands with SVG icons if available
!Notes
requires [[ImageMacroPlugin|http://svn.tiddlywiki.org/Trunk/contributors/JonRobson/plugins/ImageMacroPlugin/plugins/ImageMacroPlugin.tid]]
SVG icons are drawn from tiddlers titled {{{<command>.svg}}}
In readonly mode a tiddler called {{{<command>ReadOnly.svg}}} will be used if it exists.
!TODO
* rename (IconToolbarPlugin?)
* support more than one more popup menu in the toolbar.
!Code
***/
//{{{
(function($) {
if(!config.macros.image) {
throw "Missing dependency: ImageMacroPlugin";
}
var macro = config.macros.toolbar;
macro.icons = {
cloneTiddler: "editTiddler"
};
var _handler = macro.handler;
macro.handler = function(place, macroName, params, wikifier,
paramString, tiddler) {
var toolbar = $(place);
toolbar.attr({
refresh: "macro",
macroName: macroName
}).data("args", arguments);
var status = _handler.apply(this, arguments);
if(tiddler.isReadOnly()) {
toolbar.addClass("toolbarReadOnly");
} else {
toolbar.removeClass("toolbarReadOnly");
}
var parsedParams = paramString.parseParams("name")[0];
if(parsedParams.icons && parsedParams.icons == "yes") {
this.augmentCommandButtons(place);
}
if(parsedParams.more && parsedParams.more == "popup") {
// note we must override the onclick event like in createTiddlyButton
// otherwise the click event is the popup AND the slider
$(".moreCommand", place).each(function(i, el) {
el.onclick = macro.onClickMorePopUp;
});
// buttons that are after a less command should not be in more menu.
$(".lessCommand ~ .button", place).appendTo(place);
$(".lessCommand", place).remove();
}
return status;
};
macro.refresh = function(place, params) {
var args = $(place).empty().data("args");
this.handler.apply(this, args);
};
var imageMacro = config.macros.image;
macro.augmentCommandButtons = function(toolbar) {
$(".button", toolbar).each(function(i, el) {
var cmd = $(el).attr("commandname");
cmd = cmd ? cmd : "moreCommand"; // XXX: special-casing of moreCommand due to ticket #1234
var icon = store.tiddlerExists(cmd) ? cmd : macro.icons[cmd];
var text = $(el).text();
if(readOnly) {
var readOnlyAlternative = "%0ReadOnly".format([icon]);
if(store.tiddlerExists(readOnlyAlternative)) {
icon = readOnlyAlternative;
}
}
if(store.tiddlerExists(icon)) {
$(el).css({display: "inline-block"}).empty();
imageMacro.renderImage(el, icon, { alt: text });
}
});
};
// provide onClickMore to provide extra commands in a popup
macro.onClickMorePopUp = function(ev) {
ev = ev || window.event;
var sibling = this.nextSibling;
if(sibling) {
var commands = sibling.childNodes;
var popup = Popup.create(this);
$(popup).addClass("taggedTiddlerList");
for(var i = 0; i < commands.length; i++) {
var li = createTiddlyElement(popup, "li", null);
var oldCommand = commands[i];
var command = oldCommand.cloneNode(true);
command.onclick = oldCommand.onclick;
li.appendChild(command);
}
Popup.show();
}
ev.cancelBubble = true;
if(ev.stopPropagation) {
ev.stopPropagation();
}
return false;
};
})(jQuery);
//}}}
<<tabs txtFavourite
tags "First tab" "tags macro"
tag "Second tab" "tag macro"
>>
''Answer''
TiddlyWiki is a little different to other Wikis you may have encountered before. Most wikis run on a server and the code to save your changes is server code. TiddlyWiki is different. It runs entirely in your web browser. All the code to save your changes is written in Javascript and contained in the TiddlyWiki file. To save changes your browser must be able to write to local disk using javascript. This means you can only edit and save changes to a TiddlyWiki file that is on a local disk. If you put your TiddlyWiki file on your web site any changes made to it can't be saved.
(TODO, explain the "HideEditFeaturesOverHttp" or link to explanation)
(This can be a useful way to publish a web site. You can edit and save your site to your local TiddlyWiki file on your local disk. When it's finished simply upload the file for the rest of the world to see).
The above information applies to a standard, off-the-shelf TiddlyWiki. However, there ''are'' some ways you can get an editable/saveable TiddlyWiki via the web.
'' Options for making TiddlyWiki editable/saveable via the web ''
There are a [[Multi-User Collaboration|number]] of [[Server-Side_Implementations|server-sides]] that make it possible to save over HTTP.
Alternatively, a hosted service like [[Tiddlyspot]] can be used for convenience.
[[Category:FAQ]]
[[Category:Getting Started]]
TiddlyWiki provides document authors with a relatively ubiquitous yet surprisingly malleable and extensible means of organizing content.
At a very simple level, [[tiddlers|Tiddler]] are named chunks of document content (information), potentially with some tags on them for cross-reference.
Think "named, tagged digital 3-by-5 cards", if you wish; it's almost that straightforward. Unless artificially restricted by dumbed-down view and/or edit templates, [[tiddler|Tiddler]] content is normally malleable within an open TiddlyWiki document.
TiddlyWiki documents are relatively unique in that respect; the TW core allows end-users - document viewers - to actually modify the content they're viewing.
When you're viewing a TW document "server side" - with an http colon-slash-slash not a file-colon-slash-slash - the question then becomes, how can someone save any changed tiddlers they've created - where can they be put? There are a few possibilities; TiddlyTools save-from-web can work in many cases, as can using an online server type TW document such as a TiddlySpot document, or using server-sides such as [[ccTiddly]] or [[TiddlyWeb]].
Tiddler importing and exporting is quite a bit more powerful and capable when you think about applying filters such as by-tag to inter-document tiddler transfers.
! Information in a tiddler
There are several optional information holders in a tiddler, i.e holders that allows access to the information from other tiddlers.
* Tags: Data entered in the tags field
* Slices: Data entered into a simple two column table. The first column lists the field name and the second column the respecive data. The typical example is the table in the beginning of plugins listing Name, Version etc.
* Sections: Are what are defined and separated by headings, i.e the "!" mark (!, !!, !!!)
* Fields: Can be seen when clicking the tiddler menu more>fields. This typically contains meta information about the tiddler but can contain any information.
!Faces
<<view modifier SiteIcon>> <<view modifier link>>
[[AdaptorBase.js|http://tiddlywikidocco.tiddlyspace.com/AdaptorBase]]
[[Animator.js|http://tiddlywikidocco.tiddlyspace.com/Animator]]
[[Backstage.js|http://tiddlywikidocco.tiddlyspace.com/Backstage.js]]
[[BasicTypes.js|http://tiddlywikidocco.tiddlyspace.com/BasicTypes]]
[[Commands.js|http://tiddlywikidocco.tiddlyspace.com/Commands]]
[[Config.js|http://tiddlywikidocco.tiddlyspace.com/Config]]
[[ConfigBrowser.js|http://tiddlywikidocco.tiddlyspace.com/ConfigBrowser]]
[[Crypto.js|http://tiddlywikidocco.tiddlyspace.com/Crypto]]
[[Dates.js|http://tiddlywikidocco.tiddlyspace.com/Dates]]
[[Dom.js|http://tiddlywikidocco.tiddlyspace.com/Dom]]
[[FileAdaptor.js|http://tiddlywikidocco.tiddlyspace.com/FileAdaptor]]
[[FileSystem.js|http://tiddlywikidocco.tiddlyspace.com/FileSystem]]
[[Filters.js|http://tiddlywikidocco.tiddlyspace.com/Filters]]
[[Formatter.js|http://tiddlywikidocco.tiddlyspace.com/Formatter]]
[[FormatterHelpers.js|http://tiddlywikidocco.tiddlyspace.com/FormatterHelpers]]
[[Guide.js|http://tiddlywikidocco.tiddlyspace.com/Guide]]
[[Http.js|http://tiddlywikidocco.tiddlyspace.com/Http]]
[[Import.js|http://tiddlywikidocco.tiddlyspace.com/Import]]
[[Lingo.js|http://tiddlywikidocco.tiddlyspace.com/Lingo]]
[[ListView.js|http://tiddlywikidocco.tiddlyspace.com/ListView]]
[[LoaderSaver.js|http://tiddlywikidocco.tiddlyspace.com/LoaderSaver]]
[[Macros.js|http://tiddlywikidocco.tiddlyspace.com/Macros]]
[[Manager.js|http://tiddlywikidocco.tiddlyspace.com/Manager]]
[[Messages.js|http://tiddlywikidocco.tiddlyspace.com/Messages]]
[[Morpher.js|http://tiddlywikidocco.tiddlyspace.com/Morpher]]
[[NewTiddler.js|http://tiddlywikidocco.tiddlyspace.com/NewTiddler]]
[[Numbers.js|http://tiddlywikidocco.tiddlyspace.com/Numbers]]
[[Options.js|http://tiddlywikidocco.tiddlyspace.com/Options]]
[[Paramifiers.js|http://tiddlywikidocco.tiddlyspace.com/Paramifiers]]
[[Popup.js|http://tiddlywikidocco.tiddlyspace.com/Popup]]
[[RGB.js|http://tiddlywikidocco.tiddlyspace.com/RGB]]
[[Refresh.js|http://tiddlywikidocco.tiddlyspace.com/Refresh]]
[[Saving.js|http://tiddlywikidocco.tiddlyspace.com/Saving]]
[[SavingRSS.js|http://tiddlywikidocco.tiddlyspace.com/SavingRSS]]
[[Scroller.js|http://tiddlywikidocco.tiddlyspace.com/Scroller]]
[[Search.js|http://tiddlywikidocco.tiddlyspace.com/Search]]
[[Slider.js|http://tiddlywikidocco.tiddlyspace.com/Slider]]
[[Sparkline.js|http://tiddlywikidocco.tiddlyspace.com/Sparkline]]
[[Story.js|http://tiddlywikidocco.tiddlyspace.com/Story]]
[[Strings.js|http://tiddlywikidocco.tiddlyspace.com/Strings]]
[[Sync.js|http://tiddlywikidocco.tiddlyspace.com/Sync]]
[[TW21Loader.js|http://tiddlywikidocco.tiddlyspace.com/TW21Loader]]
[[TW21Saver.js|http://tiddlywikidocco.tiddlyspace.com/TW21Saver]]
[[Tabs.js|http://tiddlywikidocco.tiddlyspace.com/Tabs]]
[[Tiddler.js|http://tiddlywikidocco.tiddlyspace.com/Tiddler]]
[[TiddlerFields.js|http://tiddlywikidocco.tiddlyspace.com/TiddlerFields]]
[[TiddlyWiki.js|http://tiddlywikidocco.tiddlyspace.com/TiddlyWiki]]
[[Toolbar.js|http://tiddlywikidocco.tiddlyspace.com/Toolbar]]
[[Upgrade.js|http://tiddlywikidocco.tiddlyspace.com/Upgrade]]
[[Utilities.js|http://tiddlywikidocco.tiddlyspace.com/Utilities]]
[[UtilitiesPopup.js|http://tiddlywikidocco.tiddlyspace.com/UtilitiesPopup]]
[[Version.js|http://tiddlywikidocco.tiddlyspace.com/Version]]
[[Wikifier.js|http://tiddlywikidocco.tiddlyspace.com/Wikifier]]
[[Wizard.js|http://tiddlywikidocco.tiddlyspace.com/Wizard]]
[[Zoomer.js|http://tiddlywikidocco.tiddlyspace.com/Zoomer]]
[[main.js|http://tiddlywikidocco.tiddlyspace.com/main]]
The slider macro allows embedding tiddlers within another tiddler, with the option to toggle the visibility of the [[transclusion|transcluded]] content:
{{{
<<slider cookie tiddler label tooltip>>
}}}
* {{{cookie}}}: variable to save the state of the slider (e.g. {{{chkFooSlider}}})
* {{{tiddler}}}: name of the tiddler to include in the slider
* {{{label}}}: title text of the slider
* {{{tooltip}}}: tooltip text of the slider
For example:
{{{
<<slider chkTestSlider [[OptionsPanel]] "Options" "Open advanced options">>
}}}
<!--{{{-->
<div class='toolbar'
macro='toolbar [[ToolbarCommands::EditToolbar]] icons:yes'>
</div>
<div class='heading editorHeading'>
<div class='editor title' macro='edit title'></div>
<div class='tagClear'></div>
</div>
<div class='annotationsBox' macro='annotations'>
<div class='editSpaceSiteIcon'
macro='tiddlerOrigin height:16 width:16 label:no interactive:no'>
</div>
<div class="privacyEdit" macro='setPrivacy label:no interactive:no'></div>
<div class='tagClear'></div>
</div>
<div class='editor' macro='edit text'></div>
<div class='editorFooter'>
<div class='tagTitle'>tags</div>
<div class='editor' macro='niceTagger'></div>
<div class='tagAnnotation'>
<span macro='message views.editor.tagPrompt'></span>
<span macro='tagChooser excludeLists'></span>
</div>
</div>
<div macro="editFields"></div>
<!--}}}-->
/***
|''Name''|RandomColorPalettePlugin|
|''Description''|Adds a random color palette to TiddlyWiki|
|''Author''|Jon Robson|
|''Version''|1.4.0|
|''Status''|stable|
|''Source''|https://github.com/jdlrobson/TiddlyWikiPlugins/raw/master/plugins/RandomColorPalettePlugin/RandomColorPalettePlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<RandomColorPalette>>
}}}
Sets and saves a random color palette on execution
{{{
<<RandomColorPaletteButton>>
}}}
Creates a button, which when clicked will change the color palette
More information at http://macros.tiddlyspace.com/#%5B%5BRandomColorPaletteButton%20macro%5D%5D
!Code
***/
//{{{
RGB.prototype.toRGBString = function() {
return "rgb(%0,%1,%2)".format(parseInt(this.r * 255, 10),
parseInt(this.g * 255, 10), parseInt(this.b * 255, 10))
}
function HSL_TO_RGB(h, s, l) { // h (hue) between 0 and 360, s (saturation) & l (lightness) between 0 and 1
var c = l <= 0.5 ? 2 * l * s : ( 2 - (2 * l)) * s;
var h1 = h / 60;
var x = c * (1 - Math.abs((h1 % 2) - 1));
var r, g, b;
if(typeof(h) == 'undefined') {
r = 0;
g = 0;
b = 0;
} else if(0 <= h1 && h1 < 1) {
r = c;
g = x;
b = 0;
} else if(1 <= h1 && h1 < 2) {
r = x;
g = c;
b = 0;
} else if(2 <= h1 && h1 < 3) {
r = 0;
g = c;
b = x;
} else if(3 <= h1 && h1 < 4) {
r = 0;
g = x;
b = c;
} else if(4 <= h1 && h1 < 5) {
r = x;
g = 0;
b = c;
} else if(5 <= h1 && h1 < 6) {
r = c;
g = 0;
b = x;
}
m = l - (0.5 * c);
return new RGB(r + m, g + m, b + m);
}
(function($){
var macro = config.macros.RandomColorPalette = {
messagesOn: false,
changedPaletteText: "We have assigned you a random theme by adjusting the [[ColorPalette]] tiddler.\nDon't like it? Click <<RandomColorPalette>> for another one.",
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
paramString = paramString || "";
var options = macro.getOptions(paramString);
macro.generatePalette(options, true);
},
optionTypes: {
floats: ["hue", "saturation", "darkest", "lightness", "huevariance", "dark", "pale", "light", "mid",
"saturation_light", "saturation_pale", "saturation_mid", "saturation_dark"
]
},
getOptions: function(paramString) {
var args = paramString.parseParams("name", null, true, false, true)[0];
var options = {};
var numbers = macro.optionTypes.floats;
for(var i in args) {
options[i] = numbers.indexOf(i) > -1 ? parseFloat(args[i][0], 10) : args[i][0];
}
return options;
},
generateRandomNumber: function(min, max, info) {
var num = (Math.random() * 1);
info = !info ? { attempts:0 } : info;
info.attempts += 1;
var good = true;
if(min == max) {
return max;
}
if(min && num < min) {
good = false;
} else if(max && num > max) {
good = false;
}
if(!good) {
if(info.attempts < 5) {
return macro.generateRandomNumber(min, max, info);
} else {
if(max) {
return max;
} else if(min) {
return min;
} else {
return 1;
}
}
}
return num;
},
getExistingPalette: function(asJSON) {
var title = "ColorPalette";
var tiddlerText;
if(store.tiddlerExists(title)) {
tiddlerText = store.getTiddlerText(title);
} else if(store.isShadowTiddler(title)){
tiddlerText = config.shadowTiddlers[title];
}
if(asJSON) {
var json = {};
if(tiddlerText) {
var lines = tiddlerText.split("\n");
for(var i = 0; i < lines.length; i++) {
var definition = lines[i].split(":");
if(definition.length == 2) {
var name = definition[0].trim();
var value = definition[1].trim();
json[name] = value;
}
}
}
return json;
} else {
return tiddlerText;
}
},
generatePalette: function(options, save) {
var outputRGB = options.rgb;
var palette = macro.getExistingPalette(true);
var hue = options.hue || Math.floor(Math.random() * 359);
var saturation = options.saturation || macro.generateRandomNumber(0.3, 0.7);
var dark = options.dark || options.darkest || macro.generateRandomNumber(0, 0.10);
var pale = options.pale || options.lightness || macro.generateRandomNumber(0.90, 1);
var delta = ( ( pale - dark ) / 3 );
var mid = options.mid || dark + delta;
var light = options.light || dark + (delta * 2);
var lightness_values = {Dark: dark, Mid: mid, Light: light, Pale: pale};
var saturation_values = {};
for(i in lightness_values) {
if(true) {
saturation_values[i] = options["saturation_" + i.toLowerCase()] || saturation;
}
}
var opposite_hue = (hue + 180) % 360;
var seed = options.huevariance || Math.floor((85 * Math.random()) + 5); // we want it to be at least 5 degrees
var huetwo = (opposite_hue + seed) % 360;
var huethree = (opposite_hue - seed) % 360;
if(huetwo < 0) {
huetwo = 360 + huetwo;
}
if(huethree < 0) {
huethree = 360 + huethree;
}
for(var j in lightness_values) {
if(true) {
var saturation = saturation_values[j];
palette["Primary" + j] = HSL_TO_RGB(hue, saturation, lightness_values[j]);
palette["Secondary" + j] = HSL_TO_RGB(huetwo, saturation, lightness_values[j]);
palette["Tertiary" + j] = HSL_TO_RGB(huethree, saturation, lightness_values[j]);
}
}
palette.Background = HSL_TO_RGB(hue, saturation, 0.92);
palette.Foreground = HSL_TO_RGB(hue, saturation, 0.08);
palette.ColorPaletteParameters = ["HSL([", hue, "|", seed, "], [", saturation_values.Pale, "|",
saturation_values.Light, "|", saturation_values.Mid, "|", saturation_values.Dark, "],",
"[", dark, "|", mid, "|", light, "|", pale, "])"].join("");
// construct new ColorPalette
var text = ["/*{{{*/\n"];
var colorcode;
for(var id in palette) {
if(true) {
var color = palette[id];
colorcode = outputRGB ? color.toRGBString() : color.toString();
text.push("%0: %1\n".format(id, colorcode));
}
}
text.push("/*}}}*/");
text = text.join("");
if(save) {
macro.saveColorPalette(text);
}
return text;
},
saveColorPalette: function(text) {
var tid = store.getTiddler("ColorPalette");
if(!tid) {
tid = new Tiddler("ColorPalette");
tid.fields = merge({}, config.defaultCustomFields);
} // TODO: detect that the ColorPalette in the space comes from outside recipe
tid.fields["server.page.revision"] = "false"; // edit conflicts dont matter
// save the color palette in tid
tid = store.saveTiddler(tid.title, tid.title, text, tid.modifier, tid.modified,
tid.tags, tid.fields, false, tid.created, tid.creator);
// an interval is used to cope with users clicking on the palette button quickly.
if(macro._nextSave) {
window.clearTimeout(macro._nextSave);
}
macro._nextSave = window.setTimeout(function() {
autoSaveChanges(null, [tid]);
}, 2000);
// temporary workaround for IE.
$.twStylesheet.remove({ id: "StyleSheetColors" });
$.twStylesheet.remove({ id: "StyleSheet" });
refreshAll();
macro.reportChange();
return tid;
},
reportChange: function() {
if(macro.messagesOn) { // only display message once..
var msgPlace = getMessageDiv();
if(!$(".changedPalette", msgPlace)[0]) {
var tempPlace = document.createElement("div");
wikify("{{changedPalette{" + macro.changedPaletteText + "}}}", tempPlace);
msgPlace.appendChild(tempPlace);
}
}
}
};
var btnMacro = config.macros.RandomColorPaletteButton = {
text: "New ColorPalette",
tooltip: "Generate a random colour scheme for your TiddlyWiki",
makeButton: function(place, options) {
var btnHandler = function(ev) {
var t = $(ev.target);
var options = t.data("options");
macro.generatePalette(options, true);
ev.preventDefault();
return false;
};
var btn = createTiddlyButton(place, this.text, this.tooltip, btnHandler);
$(btn).data("options", options);
return btn;
},
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var options = macro.getOptions(paramString);
btnMacro.makeButton(place, options);
}
};
})(jQuery);
//}}}
{{{
This page is still incomplete. You can help by contributing to its expansion.
Please improve the article, or discuss the issue on the talk page.
This page's contents need to be reviewed and/or refactored to comply with TiddlyWiki.org's quality standards.
Please improve the article, or discuss the issue on the talk page.
}}}
!Introduction
This is a summary of the macros provided by TiddlyWiki in the core grouped by category. Additional macros (Custom Macros) can be added by the user, either by copying them into the TiddlyWiki from a repository or by coding them.
!Information
Macros that provide system information.
*[[Today|Today (macro)]]
*[[Version|Version (macro)]]
!Listings
Macros that provided lists of information from the Tiddlers.
*[[Timeline|Timeline (macro)]]
*[[Alltags|Alltags (macro)]]
*[[List|List (macro)]]
!Tagging
Macros to query and manipulate tags.
*[[Tag|Tag (macro)]]
*[[Tags|Tags (macro)]]
*[[Tagging|Tagging (macro)]]
!Transclusion
Macros to include the contents of other Tiddlers (Transclusion).
*[[Slider|Slider macro]]
*[[Tabs|Tabs (macro)]]
*[[Tiddler|Tiddler (macro)]]
!Editing
Macros to aid in editing Tiddlers.
*[[NewTiddler|NewTiddler (macro)]]
*[[NewJournal|NewJournal (macro)]]
*[[SaveChanges|SaveChanges (macro]]
!Navigation
Macros to navigate through the TiddlyWiki.
*[[Search|Search (macro)]]
*[[CloseAll|CloseAll (macro)]]
*[[Permaview|Permaview (macro)]]
!Special Effects
Macros to provide special visual effects.
*[[Gradient|Gradient (macro)]]
!Internal
Macros used by TiddlyWiki to provide core functionality.
*[[Annotations|Annotations (macro)]]
*[[Edit|Edit (macro)]]
*[[Message|Message (macro)]]
*[[Refreshdisplay|Refreshdisplay (macro)]]
*[[View|View (macro)]]
*[[Toolbar|Toolbar (macro)]]
*[[Tagchooser|Tagchooser (macro)]]
* Scripts are regular tiddlers that can contain a mix of wiki syntax PLUS javascript code, embedded "inline", in between <script>...</script> markers.
* Scripts are performed each time the tiddler in which they are embedded is rendered.
* Scripts are typically used to generate and return wiki syntax that is automatically rendered to insert dynamic content into the tiddler display.
* Scripts can also make small 'on-the-'fly' adjustments to the attributes of rendered elements contained within the same tiddler using 'relative DOM references' (e.g., place.lastChild, place.parentNode, etc.)
* Scripts can also be used to create link handlers that are invoked "onclick" to trigger javascript functions in response to user actions.
* Scripts need http://www.TiddlyTools.com/#InlineJavascriptPlugin
!Example Scripts
* [[Tagging Linked Tiddlers]]
* [[Convert List to Wikilinks]]
* [[Hour Based Greetings]]
* [[What Time is It?]]
* [[numbered list to table]]
{{{
createTiddlyError(place,title,text)
}}}
The createTiddlyError global function creates a [[button|createTiddlyButton()]] that alerts the user to an error. It takes three parameters:
; place
: the DOM element where the error button will be placed.
; title
: the error button label.
; text
: the text displayed when the error button is clicked.
Category:Adaptations
This page is still incomplete. You can help by contributing to its expansion.
Please improve the article, or discuss the issue on the talk page.
Adaptations (also called verticals or editions) are variants of TiddlyWiki created for specific purposes.
In earlier versions of TiddlyWiki, the term "adaptations" used to describe modifications of the TiddlyWiki core.
More recent versions support plugins though, so that adaptations now tend to consist of a collection of plugins on top of the standard TiddlyWiki core code.
Pages in category "Adaptations"
The following 17 pages are in this category, out of 17 total.
A
AndTidWiki
E
Editions
I
IWantABlog
M
MGSD
MPTW
R
RippleRap
S
Server-Side Implementations
T
TbGTD
TeamTasks
TiddlyChatter
TiddlyFolio
T cont.
TiddlyTimeJournal
TiddlyWiki Address Book
V
Vertical
W
WebOS
Y
YourFormBuilder
YourTimeSheets
[[allTags|allTags macro]]
[[closeAll|closeAll macro]]
[[list|list macro]]
[[newJournal|newJournal macro]]
[[newTiddler|newTiddler macro]]
[[permaview|permaview macro]]
[[saveChanges|saveChanges macro]]
[[search|search macro]]
[[slider|slider macro]]
[[tabs|tabs macro]]
[[tag|tag macro]]
[[tagging|tagging macro]]
[[tags|tags macro]]
[[tiddler|tiddler macro]]
[[timeline|timeline macro]]
[[today|today macro]]
[[version|version macro]]
[[view|view macro]]
/***
|''Name''|SerializerLinks|
|''Description''|TiddlySpace plugin creating links to the different serialization forms.|
|''Version''|0.8.1|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var tweb = config.extensions.tiddlyweb;
var macro = config.macros.serializerLinks = {
available: ["atom", "html", "json", "txt", "wiki"],
separator: " / ",
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
if(!tiddler) {
return;
}
var container = $("<span />").appendTo(place);
var bag = tiddler.fields["server.bag"]
var space = tiddlyspace.resolveSpaceName(bag);
tweb.getStatus(function(status) {
var host = status.server_host;
var base = tiddlyspace.getHost(host, space);
for(var i = 0; i < macro.available.length; i++) {
var serializer = macro.available[i];
$("<a />").addClass("sLink").text(serializer).attr("href", "%0/bags/%1/tiddlers/%2.%3".format([
base, bag, encodeURIComponent(tiddler.title), serializer
])).appendTo(container);
if(i < macro.available.length - 1) {
$("<span />").text(macro.separator).appendTo(container);
}
}
});
}
};
})(jQuery);
//}}}
// chrjs UI extension
// v0.5.1
(function($) {
tiddlyweb.Recipe.prototype.render = function() {
var lbl = $("<h3 />");
$("<a />").attr("href", this.route()).text(this.name).appendTo(lbl);
var desc = $("<p />").text(this.desc);
this.policy.constraints = ["read", "manage", "owner"];
var policy = this.policy.render();
var content = $.map(this.recipe, function(item, i) {
return item[1] ? item[0] + "?" + item[1] : item[0];
}).join("\n");
content = $("<pre />").text(content);
var container = $("<article />").data("entity", this).
append(lbl).append(desc).append(policy).append(content);
editable("p, pre", container[0], tiddlyweb.Recipe.onChange);
return container;
};
tiddlyweb.Recipe.onChange = function(ev) {
var el = $(this);
var recipe = el.closest("article").data("entity");
switch(this.nodeName.toLowerCase()) {
case "p": // TODO: enforce single line
recipe.desc = el.text();
break;
case "pre":
var lines = el.html().split("\n");
recipe.recipe = $.map(lines, function(item, i) {
var arr = item.split("?");
var bag = arr.shift();
var filter = arr.join("?"); // NB: components expected to be URI-encoded
return [[bag, filter]]; // nested array prevents flattening
});
break;
default:
break;
}
};
tiddlyweb.Bag.prototype.render = function() {
var lbl = $("<h3 />");
$("<a />").attr("href", this.route()).text(this.name).appendTo(lbl);
var desc = $("<p />").text(this.desc);
var policy = this.policy ? this.policy.render() : null;
var container = $("<article />").data("entity", this).
append(lbl).append(desc).append(policy);
editable("p, pre", container[0], tiddlyweb.Bag.onChange);
return container;
};
tiddlyweb.Bag.onChange = function(ev) { // TODO: DRY (cf. Recipe)
var el = $(this);
var bag = el.closest("article").data("entity");
switch(this.nodeName.toLowerCase()) {
case "p": // TODO: enforce single line
bag.desc = el.text();
break;
default:
break;
}
};
tiddlyweb.Tiddler.prototype.render = function() {
var lbl = $("<h3 />");
$("<a />").attr("href", this.route()).text(this.title).appendTo(lbl);
// TODO: tags
var txt = $("<pre />").text(this.text);
var container = $("<article />").data("entity", this).
append(lbl).append(txt);
editable("p, pre", container[0], tiddlyweb.Tiddler.onChange);
return container;
};
tiddlyweb.Tiddler.onChange = function(ev) { // TODO: DRY (cf. Recipe)
var el = $(this);
var tiddler = el.closest("article").data("entity");
switch(this.nodeName.toLowerCase()) {
case "pre": // TODO: enforce single line
tiddler.text = el.html();
break;
default:
break;
}
};
tiddlyweb.Policy.prototype.render = function() {
var self = this;
var specialValues = tiddlyweb.Policy.specialValues;
// TODO: templating
var table = $('<table class="policy"><thead><tr><th /></tr></thead></table>').
data("policy", this);
$("<caption />").text("owner: " + this.owner).prependTo(table); // XXX: inelegant -- XXX: i18n
var row = table.find("tr:first");
var users = [];
var roles = [];
$.each(this.constraints, function(i, constraint) {
if(constraint != "owner" && self[constraint]) {
$("<th />").text(constraint).appendTo(row); // XXX: i18n
$.each(self[constraint], function(i, item) {
if(item.indexOf("R:") == 0) {
pushUnique(item, roles);
} else if($.inArray(item, specialValues) == -1) {
pushUnique(item, users);
}
});
}
});
var tbody = $("<tbody />").appendTo(table);
var entries = specialValues.concat(users).concat(roles);
$.each(entries, function(i, entry) {
var row = $("<tr />").appendTo(tbody);
if($.inArray(entry, specialValues) != -1) {
row.addClass("special"); // XXX: rename
}
$("<td />").text(entry).appendTo(row);
$.each(self.constraints, function(i, constraint) {
if(constraint != "owner" && self[constraint]) {
var cell = $('<td><input type="checkbox" /></td>').appendTo(row);
if(self[constraint].length == 0) {
var column = $.inArray(constraint, self.constraints) + 1;
cell = cell.closest("table").find("tbody tr:first td").eq(column);
cell.find("input").attr("checked", "checked");
} else if($.inArray(entry, self[constraint]) != -1) {
cell.find("input").attr("checked", "checked");
}
}
});
});
$("input[type=checkbox]", tbody[0]).live("change", tiddlyweb.Policy.onChange);
var addRow = function(ev, cell) { // XXX: use as both event handler and regular function hacky?
var el = cell || $(this);
if(cell || el.val().length > 0) {
var field = $('<input type="text" placeholder="new user/role" />'). // XXX: i18n
change(addRow).hide();
var tbody = el.closest("tbody");
el.closest("tr").clone().
find("td:first").empty().append(field).end().
find("input[type=checkbox]").removeAttr("checked").end().
appendTo(tbody);
field.fadeIn(); // slideDown preferable, but problematic for TRs
}
};
addRow(null, $("tr:last td:first", tbody));
return table;
};
tiddlyweb.Policy.specialValues = ["anonymous", "ANY", "NONE"]; // XXX: rename -- XXX: i18n
tiddlyweb.Policy.onChange = function(ev) {
var el = $(this);
var cell = el.closest("td");
var tbody = cell.closest("tbody");
var table = tbody.closest("table");
var policy = table.data("policy");
var entry = cell.closest("tr").find("td:first");
var field = entry.find("input");
entry = field.length ? field.val() : entry.text();
var colIndex = cell.prevAll().length;
var constraint = table.find("thead th").eq(colIndex).text(); // XXX: brittle (i18n)
var entries = policy[constraint];
var checked = $(el).attr("checked");
if($.inArray(entry, tiddlyweb.Policy.specialValues) == -1) {
if(!checked) {
removeItem(entry, entries || []);
} else {
if(entries && entries.length) {
pushUnique(entry, policy[constraint]);
} else {
policy[constraint] = [entry];
}
}
// reset special values
$.each(tiddlyweb.Policy.specialValues, function(i, item) {
removeItem(item, entries || []);
});
$("tr.special", tbody).
find("td:nth-child(" + (colIndex + 1) + ") input[type=checkbox]").
removeAttr("checked"); // XXX: redraw entire table instead?
} else {
policy[constraint] = entry == "anonymous" ? [] : [entry];
// reset all entries -- XXX: DRY (see above)
cell.closest("tr").siblings().
find("td:nth-child(" + (colIndex + 1) + ") input[type=checkbox]").
removeAttr("checked");
}
};
var editable = function(selector, context, onChange) {
$(selector, context).attr("contentEditable", "true"). // XXX: inserting line breaks sometimes leads to new paragraph elements being created
live("focus", function(ev) {
$(this).addClass("active");
}).live("blur", function(ev) {
var el = $(this).removeClass("active");
var txt = el.html().replace(/<br>|<div>/g, "\n").replace(/<\/div>/g, ""); // XXX: sometimes can contain " "
el.html(txt);
onChange.apply(this, arguments);
});
};
var pushUnique = function(val, arr) {
if($.inArray(val, arr) == -1) {
arr.push(val);
}
};
var removeItem = function(val, arr) {
var pos = $.inArray(val, arr);
if(pos != -1) {
arr.splice(pos, 1);
}
};
})(jQuery);
The [[Tiddler]] class represents a single tiddler. Instances of this class are created as the user opens tiddlers; they are not deleted if an user closes the corresponding tiddler. Changing an instantiated object does not affect the tiddler as saved by the author; to make changes to the tiddler that will be saved the next time the [[TiddlyWiki|TiddlyWiki Class]] is saved, call ''store.saveTiddler''.
!! Properties
Instead of setting these manually, use the [[set|set]] method.
; title
: a string with the tiddler's name
; text
: the source code of the tiddler
; modifier
: a string with the modifier of the tiddler's name
; modified
: a Date object corresponding to when the tiddler was last changed
; links
: an array of strings, one per link in the tiddler's source code
; tags
: an array of strings, one per tag assigned to the tiddler
; created
: a Date object corresponding to when the tiddler was created
; creator
: a string with the creator of the tiddler's name (TW core 2.6)
; linksUpdated
: a boolean corresponding to whether the links property is up-to-date
!! Methods
* [[autoLinkWikiWords|Tiddler.prototype.autoLinkWikiWords]]: returns whether the tiddler should have WikiWords linked.
* [[changed|Tiddler.prototype.changed]]: a hook to be called after the Tiddler object has been modified.
* [[escapeLineBreaks|Tiddler.prototype.escapeLineBreaks]] and [[unescapeLineBreaks|Tiddler.unescapeLineBreaks]]: converts line breaks from textual and HTML representations.
* [[generateFingerprint|Tiddler.prototype.generateFingerprint]]: return a SHA-1 hash of the tiddler's text.
* [[getLinks|Tiddler.prototype.getLinks]]: returns an array of links contained in the tiddler. Should be used instead of accessing the links property directly.
* [[getSubtitle|Tiddler.prototype.getSubtitle]]: returns a subtitle with author name and modification date.
* [[getTags|Tiddler.prototype.getTags]]: returns a single string of the tiddler's tags.
* [[isTagged|Tiddler.prototype.isTagged]]: returns whether the tiddler has been assigned a specific tag.
* [[isReadOnly|Tiddler.prototype.isReadOnly]]: returns whether the tiddler can be edited.
* [[Tiddler.LoadFromDiv|Tiddler.prototype.loadFromDiv]]: instantiate a Tiddler from HTML.
* [[saveToDiv|Tiddler.prototype.saveToDiv]]: render HTML for storing the tiddler.
* [[set|Tiddler.prototype.set]]: changes many properties of the tiddler. Should be used instead of changing tiddler properties like text directly. TW 2+
!! Modifying Tiddler Contents
<<<
[[Eric|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/44edde8c58e99892/]]:
assigning directly to the "tiddler.text" property of a retrieved
tiddler object *can* be tricky:
Normally, the TW core functions, {{{store.saveTiddler()}}} or
{{{tiddler.set()}}} (for low-level internal operations) are used to
change the value in the tiddler data, and these functions trigger side-
effect processing, such as refreshing the display or even auto-saving
the file in response to changes in tiddler content.
In addition, lots of plugins hijack these functions in order to add
system-level extensions that are triggered whenever a tiddler is
changed. Directly setting the value of {{{tiddler.text}}} completely
bypasses these functions, preventing all add-on ''and'' core side-effects
behaviors from being triggered.
<<<
!! Storage
Within TiddlyWiki's store area, each tiddler is recorded in the following format:
{{{
<div title="tiddler title" modifier="author/editor" modified="YYYY0MM0DD0hh0mm" created="YYYY0MM0DD0hh0mm" tags="foo bar [[lorem ipsum]]">
<pre>
Body of the tiddler
</pre>
</div>
}}}
This question gets asked regularly on the mailing list. The answer is complicated. I'm going to attempt to write a definitive answer here.
''Standard TiddlyWiki''
Imagine you have a local shared network drive with a TiddlyWiki file on it. Now suppose in the morning you open the TiddlyWiki file and make some changes then save them. Then in the afternoon someone else opens the file and makes some more changes and saves them. This all works fine. If you have set your user name cookies, it will even show who edited each tiddler.
But now suppose you both open the file at the same time. If you edit some tiddlers then save the other user won't know about those edits. Then when she saves her TiddlyWiki it will overwrite your edits. This is obviously a major limitation and means that multi-user with a standard TiddlyWiki is not very useful. (see [[TiddlyLock|Can I use TiddlyWiki as a multi-user/collaborative/server based wiki?#TiddlyLock]] below for a simple solution to this problem)
''Server-side adaptations of TiddlyWiki''
There are a number of server side adaptations of TiddlyWiki. See [[here|http://tiddlywiki.com/#ServerSide]] for more information. These server-side adaptations require that you setup and configure the appropriate web servers and databases to store tiddlers on the server, like a conventional wiki. Then as the adminstrator you can create users who must authenticate in order to edit tiddlers.
Depending on the version there might be additional features like access control settings and version history. The advantage of this type of setup is that you have a proper multi-user collaborative environment. The disadvantage is that there's quite a bit more work and technical skill required to setup, configure and administer the system, and you lose the ability to work offline, eg on a USB drive.
{{Quote|1=DaveG|2=
If I recall correctly in this situation you can use the export plugin (from Eric Shulman see [[ExportTiddlersPlugin|http://www.TiddlyTools.com/#ExportTiddlersPlugin]] ) which can make a static html exported file for offline reading
}}
The two most active server-side adaptations seem to be [[TiddlyWeb]], which runs on Python, and [[ccTiddly]], which runs on PHP and MySQL.
''Standard TiddlyWiki via http, using UploadPlugin''
[[BidiX|http://tiddlywiki.bidix.info]] has written a plugin that lets you upload your TiddlyWiki to a web server. You need to copy a single PHP file onto your web server, so there is less setup than a full serverside.
This situation is basically the same as a standard TiddlyWiki -- when there are multiple users editing, whoever saves last will overwrites any previous saves. [[Tiddlyspot|http://tiddlyspot.com]] uses the UploadPlugin, so this applies for Tiddlyspot sites as well as sites where you use UploadPlugin on your own web server.
''Standard TiddlyWiki via http, using UploadPlugin and GroupAuthoringPlugin''
BidiX, the creator of UploadPlugin, has also written a tool called GroupAuthoringPlugin that can be used for allowing multi-user editing on a standard TiddlyWiki via http using UploadPlugin. The way it works is that if you want to do some editing you first "lock" the TiddlyWiki file. This creates a lock file on the server which prevents anyone else from uploading until you release the lock. For more information see [[here|http://tiddlywiki.bidix.info]]. GroupAuthoringPlugin requires that you install some scripts on your web server (as does UploadPlugin) to handle the locking.
(Currently GroupAuthoringPlugin is not available on Tiddlyspot but there are plans to make it available some time in the future).
''Other Solutions to Investigate''
'' [[MiniTiddlyServer|http://minitiddlyserver.com]] ''
[[MiniTiddlyServer|http://minitiddlyserver.com]] (Project no longer available on this link) is a lightweight php based server side that is similar to UploadPlugin in that the TiddlyWiki on the server is a stock-standard TiddlyWiki, but includes some more advanced saving techniques, for example it can save only changed tiddlers. There is also some support for preventing overwritten data in a multi-user situation.
'' [[TiddlyHome|http://tiddlyhome.bidix.info]] ''
[[TiddlyHome|http://tiddlyhome.bidix.info]] from BidiX is based on UploadPlugin but allows easy creation of entire new sites and provides a way to provide update access to groups of users.
'' [[TiddlyLock|http://www.minormania.com/tiddlylock/tiddlylock.html]] ''
[[TiddlyLock|http://www.minormania.com/tiddlylock/tiddlylock.html]], by Richard Hobbis, uses a simple lock file mechanism to allow a TiddlyWiki to be stored on a shared network drive and viewed & edited by multiple users without fear of overwriting other users' changes or losing their own!
It works by maintaining a simple lock file (by default, in the same location as the TiddlyWiki file) that identifies who locked the TiddlyWiki, and when. Whilst the TiddlyWiki is being edited, other users are automatically put into Read-Only mode. As soon as the editing user has saved the TiddlyWiki it becomes available to other users for editing again, although they do have to reload the TiddlyWiki in order to see the changes made.
The location of the lock file can now be changed so that it is stored in a location separate from the TiddlyWiki file.
'' [[ServerLockPlugin|http://www.gentleknowledge.com/tiddlyplugins#ServerLockPlugin]] ''
[[TiddlyLock|http://www.minormania.com/tiddlylock/tiddlylock.html]] (see website for differences) but prevents overwriting when editing a wiki over http.
''Note''
Multi-user collaboration is not really TiddlyWiki's strong point. Many of the solutions mentioned above are experimental. If you need a serious multi-user wiki then perhaps you should consider using something other than TiddlyWiki, eg MediaWiki.
'' See Also ''
* [[Server-Side Solutions]]
[[Category:FAQ]]
[[Category:Basics]]
The ''search'' method of a [[TiddlyWiki class|TiddlyWiki Class]] object returns an array of [[Tiddler]] objects whose source code contains a string. This method takes three parameters:
* a regular expression to search for
* the field to sort results by. This can be any property of a [[Tiddler]] object.
* a tag to exclude from search results.
If no tiddlers match the search, an empty array is returned.
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
Transcluded tiddlers are rendered inside a span like this:
{{{
<span refresh="content" tiddler="SomethingOrOther">
...wikified content
</span>
}}}
-- [[Jeremy Ruston, Google Groups|https://mail.google.com/mail/?ui=2&shva=1#inbox/12e97211750da57c]]
A TiddlySpace [[space|Space]] comprises of two collections of [[tiddlers|Tiddler]]: a [[Public]] [[bag|Bag]] and a [[Private]] [[bag|Bag]]. Only a [[member|Member]] of the [[space|Space]] may read, change or delete a private tiddler, though this is default [[Access Control]] may be changed by a member of a space using the TiddlyWeb [[HTTP API]].
// TiddlyWeb adaptor
// v0.10.6
//
// TODO:
// * ensure all routes are supported
// * documentation
(function($) {
tiddlyweb = {
routes: {
// host is the TiddlyWeb instance's URI (including server_prefix)
// placeholders "_type" & "name" refer to the respective bag/recipe
root : "{host}/",
bags : "{host}/bags",
bag : "{host}/bags/{name}",
recipes : "{host}/recipes",
recipe : "{host}/recipes/{name}",
tiddlers : "{host}/{_type}s/{name}/tiddlers",
tiddler : "{host}/{_type}s/{name}/tiddlers/{title}",
revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
search : "{host}/search?q={query}"
}
};
// host (optional) is the URI of the originating TiddlyWeb instance
tiddlyweb.Resource = function(type, host) {
if(arguments.length) { // initialization
this._type = type;
if(host !== false) {
this.host = host !== undefined ? host.replace(/\/$/, "") : null;
}
}
};
$.extend(tiddlyweb.Resource.prototype, {
// retrieves resource from server
// callback is passed resource, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
// filters is a filter string (e.g. "select=tag:foo;limit=5")
get: function(callback, errback, filters) {
var uri = this.route();
if(filters) {
var separator = uri.indexOf("?") == -1 ? "?" : ";";
uri += separator + filters;
}
var self = this;
return $.ajax({
url: uri,
type: "GET",
dataType: "json",
success: function(data, status, xhr) {
var resource = self.parse(data);
resource.etag = xhr.getResponseHeader("Etag");
callback(resource, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
});
},
// sends resource to server
// callback is passed data, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
put: function(callback, errback) {
var self = this;
var uri = this.route();
var data = {};
$.each(this.data, function(i, item) {
var value = self[item];
if(value !== undefined) {
data[item] = value;
}
});
var options = {
url: uri,
type: "PUT",
contentType: "application/json",
data: $.toJSON(data),
success: function(data, status, xhr) {
callback(self, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
};
if(this.ajaxSetup) {
this.ajaxSetup(options);
}
return $.ajax(options);
},
// deletes resource on server
// callback is passed data, status, XHR (cf. jQuery.ajax success)
// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
"delete": function(callback, errback) {
var self = this;
var uri = this.route();
var options = {
url: uri,
type: "DELETE",
success: function(data, status, xhr) {
callback(self, status, xhr);
},
error: function(xhr, error, exc) {
errback(xhr, error, exc, self);
}
};
if(this.ajaxSetup) {
this.ajaxSetup(options);
}
return $.ajax(options);
},
// returns corresponding instance from raw JSON object (if applicable)
parse: function(data) {
return data;
},
// list of accepted keys in serialization
data: [],
// returns resource's URI
route: function() {
return supplant(tiddlyweb.routes[this._type], this);
}
});
var Container = function(type, name, host) {
if(arguments.length) { // initialization
tiddlyweb.Resource.apply(this, [type, host]);
this.name = name;
this.desc = "";
this.policy = new tiddlyweb.Policy({});
}
};
Container.prototype = new tiddlyweb.Resource();
$.extend(Container.prototype, {
tiddlers: function() {
return new TiddlerCollection(this);
},
parse: function(data) {
var type = tiddlyweb._capitalize(this._type);
var container = new tiddlyweb[type](this.name, this.host);
data.policy = new tiddlyweb.Policy(data.policy);
return $.extend(container, data);
},
data: ["desc", "policy"]
});
// attribs is an object whose members are merged into the instance (e.g. query)
tiddlyweb.Collection = function(type, host, attribs) {
if(arguments.length) { // initialization
tiddlyweb.Resource.apply(this, [type, host]);
$.extend(this, attribs);
}
};
tiddlyweb.Collection.prototype = new tiddlyweb.Resource();
var TiddlerCollection = function(container, tiddler) {
if(arguments.length) { // initialization
tiddlyweb.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
this.container = container || null;
this.tiddler = tiddler || null;
}
};
TiddlerCollection.prototype = new tiddlyweb.Collection();
$.extend(TiddlerCollection.prototype, {
parse: function(data) {
var container = this.container;
return $.map(data, function(item, i) {
var tiddler = new tiddlyweb.Tiddler(item.title, container);
var bag = item.bag;
tiddler = tiddlyweb.Tiddler.prototype.parse.apply(tiddler, [item]);
if(!tiddler.bag && bag) { // XXX: bag always present!?
tiddler.bag = new tiddlyweb.Bag(bag, container.host);
}
if(!tiddler.recipe && item.recipe) {
tiddler.recipe = new tiddlyweb.Recipe(item.recipe, container.host);
}
delete item.recipe;
return $.extend(tiddler, item);
});
},
route: function() {
if(this.tiddler) {
var container = this.tiddler.bag || this.tiddler.recipe;
var params = {
_type: container._type,
host: container.host,
name: container.name,
title: this.tiddler.title
};
} else {
params = this.container;
}
return supplant(tiddlyweb.routes[this._type], params);
}
});
tiddlyweb.Search = function(query, host) {
tiddlyweb.Collection.apply(this, ["search", host]);
this.query = query;
};
tiddlyweb.Search.prototype = new tiddlyweb.Collection();
$.extend(tiddlyweb.Search.prototype, {
parse: function(data) {
this.container = { // XXX: hacky
_type: "bag",
host: this.host
};
var tiddlers = TiddlerCollection.prototype.parse.apply(this, arguments);
delete this.container;
return tiddlers;
}
});
// title is the name of the tiddler
// container (optional) is an instance of either Bag or Recipe
tiddlyweb.Tiddler = function(title, container) {
tiddlyweb.Resource.apply(this, ["tiddler", false]);
this.title = title;
this.bag = container && container._type == "bag" ? container : null;
this.recipe = container && container._type == "recipe" ? container : null;
var self = this;
$.each(this.data, function(i, item) {
self[item] = undefined; // exposes list of standard attributes for inspectability
});
};
tiddlyweb.Tiddler.prototype = new tiddlyweb.Resource();
$.extend(tiddlyweb.Tiddler.prototype, {
revisions: function() {
return new TiddlerCollection(this.bag || this.recipe, this);
},
route: function() {
var container = this.bag || this.recipe;
var params = $.extend({}, this, {
host: container ? container.host : null,
_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
name: container ? container.name : null
});
return supplant(tiddlyweb.routes[this._type], params);
},
parse: function(data) {
var tiddler = new tiddlyweb.Tiddler(this.title);
var container = this.bag || this.recipe;
tiddler.bag = new tiddlyweb.Bag(data.bag, container.host);
delete data.bag;
delete data.recipe;
tiddler.created = convertTimestamp(data.created);
delete data.created;
tiddler.modified = convertTimestamp(data.modified);
delete data.modified;
if(this.recipe) {
tiddler.recipe = this.recipe;
}
return $.extend(tiddler, data);
},
data: ["modifier", "tags", "fields", "text", "type"],
ajaxSetup: function(options) {
var self = this;
if(this.etag && (options.type == "PUT" || options.type == "DELETE")) {
options.beforeSend = function(xhr) {
xhr.setRequestHeader("If-Match", self.etag);
};
}
if(options.type == "PUT") {
var callback = options.success;
options.success = function(data, status, xhr) {
var loc = xhr.getResponseHeader("Location");
var etag = xhr.getResponseHeader("Etag");
if(loc && etag) {
self.etag = etag;
if(!self.bag) {
var bag = loc.split("/bags/").pop().split("/")[0];
self.bag = new tiddlyweb.Bag(bag, self.recipe.host);
}
callback(self, status, xhr);
} else { // IE
self.get(callback, options.error);
}
};
}
}
});
tiddlyweb.Revision = function(id, tiddler) {
var container = tiddler.bag || tiddler.recipe;
tiddlyweb.Tiddler.apply(this, [tiddler.title, container]);
this._type = "revision";
this.revision = id;
};
tiddlyweb.Revision.prototype = new tiddlyweb.Tiddler();
$.extend(tiddlyweb.Revision.prototype, {
revisions: false,
data: false,
put: false,
"delete": false
});
tiddlyweb.Bag = function(name, host) {
Container.apply(this, ["bag", name, host]);
};
tiddlyweb.Bag.prototype = new Container();
tiddlyweb.Recipe = function(name, host) {
Container.apply(this, ["recipe", name, host]);
this.recipe = [];
};
tiddlyweb.Recipe.prototype = new Container();
$.extend(tiddlyweb.Recipe.prototype, {
data: ["recipe"].concat(Container.prototype.data)
});
tiddlyweb.Policy = function(constraints) { // TODO: validation?
var self = this;
$.each(this.constraints, function(i, item) {
self[item] = constraints[item];
});
};
tiddlyweb.Policy.prototype.constraints = ["read", "write", "create", "delete",
"manage", "accept", "owner"];
/*
* utilities
*/
tiddlyweb._capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
// convert YYYYMMDDhhmmss timestamp to Date instance
var convertTimestamp = function(t) {
return new Date(Date.UTC(
parseInt(t.substr(0, 4), 10),
parseInt(t.substr(4, 2), 10) - 1,
parseInt(t.substr(6, 2), 10),
parseInt(t.substr(8, 2), 10),
parseInt(t.substr(10, 2), 10),
parseInt(t.substr(12, 2) || "0", 10),
parseInt(t.substr(14, 3) || "0", 10)
));
};
// adapted from Crockford (http://javascript.crockford.com/remedial.html)
var supplant = function(str, obj) {
return str.replace(/{([^{}]*)}/g, function (a, b) {
var r = obj[b];
r = typeof r === "string" || typeof r === "number" ? r : a;
return $.inArray(b, ["host", "query"]) != -1 ? r : encodeURIComponent(r); // XXX: special-casing
});
};
})(jQuery);
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="364 157 64 51" width="30" height="30"><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><g><path class="glyph" d="M 364.50006 184.50061 L 386.99985 207.00037 L 396 198.00002 L 373.50003 175.50066 Z M 403.02295 181.97704 C 400.38693 179.34099 396.11307 179.34099 393.47702 181.97704 C 390.841 184.61307 390.841 188.88695 393.47702 191.52298 C 396.11307 194.15903 400.38693 194.15903 403.02295 191.52298 C 405.65906 188.88695 405.65906 184.61307 403.02295 181.97704 M 414.27298 170.72704 C 411.63693 168.091 407.36307 168.091 404.72702 170.72704 C 402.091 173.36308 402.091 177.63693 404.72702 180.27296 C 407.36307 182.90901 411.63693 182.90901 414.27298 180.27296 C 416.90903 177.63693 416.90903 173.36308 414.27298 170.72704 M 425.523 159.47705 C 422.88696 156.841 418.6131 156.841 415.97705 159.47705 C 413.341 162.11308 413.341 166.38695 415.97705 169.02295 C 418.6131 171.65903 422.88696 171.65903 425.523 169.02295 C 428.15906 166.38695 428.15906 162.11308 425.523 159.47705" fill="#020202"/></g></g></svg>
TiddlySpace is built on TiddlyWeb, web-friendly hosting for TiddlyWiki documents. Individual [[tiddlers|Tiddler]] are accessed using ~RESTful HTTP interactions. Some examples:
*http://glossary.tiddlyspace.com#TiddlySpace — a TiddlyWiki [[permalink|Permalink]]
*http://glossary.tiddlyspace.com/TiddlySpace — a TiddlySpace short link
*http://glossary.tiddlyspace.com/bags/glossary_public/tiddlers — the TiddlyWeb [[bag|Bag]] of tiddlers
Different representations of each resource may be exchanged though [[content negotiation|http://en.wikipedia.org/wiki/Content_negotiation]] or by appending a suffix to the URI, for example:
*http://glossary.tiddlyspace.com/TiddlySpace
*http://glossary.tiddlyspace.com/TiddlySpace.html
*http://glossary.tiddlyspace.com/TiddlySpace.txt
*http://glossary.tiddlyspace.com/TiddlySpace.json
*http://glossary.tiddlyspace.com/TiddlySpace.atom
*http://glossary.tiddlyspace.com/TiddlySpace.wiki
For more details see the [[TiddlyWeb documentation|http://tiddlyweb.peermore.com/wiki/#%5B%5BHTTP%20API%5D%5D]].
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
overflow: hidden; /* hide excessive height due to box-model math (borders) */
}
header,
footer,
nav,
section,
article {
display: block; /* XXX: required for legacy browsers */
}
.pane {
border-bottom: 1px solid #AAA;
}
.pane {
height: 45%;
overflow: auto;
}
.pane:first-child {
height: 10%;
}
nav.pane {
height: 40%;
}
footer.pane {
height: 5%;
}