Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
<<importTiddlers>>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<!--{{{-->
<div class='header' role='banner' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' role='navigation' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' role='navigation' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' role='complementary' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea' role='main'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected {color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {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 */
}
/*}}}*/
<!--{{{-->
<div class='toolbar' role='navigation' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
This page identifies standard errors, along with possible causes and fixes. The ID for each error is shown in parentheses; it corresponds to the config.messages hash.

!Problems were encountered loading plugins. See PluginManager for details (customConfigError)

!Error: ... (pluginError)

todo list all errors with possible causes/fixes (see lingo.js)
Shows a button which, when clicked, will close all tiddlers in the [[story]].

!Usage

{{{
<<closeAll>>
}}}

!Example

The basic usage will output:

<<closeAll>>
The fragement Identifier (the portion of the URL following #) may be used to control a number of parameters used when starting TiddlyWiki:

{{{#[open:]}}}//WikiWord//
{{{#[open:]}}}//WikiWord//{{{%20}}}//WikiWord//&#x2026;
{{{#start:safe}}}
{{{#search:}}}//text//
{{{#tag:}}}//text//
{{{#newTiddler:}}}//WikiWord//
{{{#newJournal:}}}//format//
todo explain macros

<<list filter [tag[macro]]>>
Shows content allowing user to import tiddlers from a URL or uploaded file. In a [[vanilla]] [[TiddlyWiki]], the content for this tiddler is simply the options macro.
Shows a search input field, which will allow the user to type a term and see all matching tiddlers.

The search will be affected by the chkCaseSensitiveSearch and chkRegExpSearch options, and you may wish to place checkboxes for those (using the [[option macro]] beside the search macro.

!Usage

{{{
<<search [defaultText [accessKey]]
}}}

(To include access key, you must also specify defaultText.)

|defaultText|default text shown in the search field|
|accessKey|an [[access key]] users can enter to focus keyboard handling on the search field|

!Examples

!!Basic Usage

{{{
<<search>>
}}}

shows a search field:

<<search>>
<<search "suche" x>>
!With Parameters

<<search "search the tiddlywiki" Q>>

EXPERT why does "search" label show?
The name for a TiddlyWiki paragraph, a block of text with a title, [[fields|field]] and [[tags]] from the [[store]] a selection of which are displayed in the [[story]].
Introduces a linebreak element.
Deprecated, use {{{<br />}}} instead.

!Usage

{{{
<<br>>
}}}

!Example

{{{
Hello<<br>>World
}}}

outputs:

{{{
Hello
World
}}}
In a [[vanilla]] TiddlyWiki, the content you put in MainMenu will appear on the left sidebar,by virtue of the fact it appears in the [[vanilla]] [[PageTemplate shadow]].

Link MainMenu
config.paramifiers.theme.onconfig

A theme is a tiddler tagged <<tag systemTheme>> containing a series of [[slice]] for [[shadow]] such as the [[Stylesheet shadow]] or the [[PageTemplate shadow]]. The current theme is set using the {{{txtTheme}}} [[option]].

|<<option txtTheme>>|<<message config.optionsDesc.txtTheme>>|
Includes a list of missing tiddlers, using the [[list macro]], and is included from the [[vanilla]] [[TabMore shadow]].
/***
|''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);
//}}}
Includes a subtitle, typically a slogan or catchphrase, for the TiddlyWiki.
Shadows are similar to [[options|option]] in that they control the configuration of the TiddlyWiki, but are used for settings that need to be expressed in a large body of text instead of a single input field or checkbox.

They are also referred to as shadow tiddlers, although they are quite different from regular tiddlers in two senses:

* Shadows are only text strings with a title - they have no tags, modifier, custom fields, etc.
* Shadows may be overridden by a regular tiddler of the same name. It will be processed the same way as the shadow and if you delete (or rename) it, the original shadow will again be "restored" and come into effect. For example, the default ~SiteTitle shadow is "TiddlyWiki". If you create a new tiddler called ~SiteTitle and insert "~MyWiki" in its text, the title will now be rendered as "~MyWiki:". And if you look at the list of shadows in the sidebar tabs control, you'll notice ~SiteTitle is shown in bold to indicate it's been overridden. You can't see the original value anymore, but it's still there; delete your SiteTitle tiddler, and you will see the original shadow again containing "TiddlyWiki", and in the same vein, the site title will revert to "TiddlyWiki".

Tags relating to default content:
<<list filter [tag[DefaultContentShadow]]>>
Tags relating to tiddler presentation:
<<list filter [tag[TiddlerShadow]]>>
Tags relating to stylesheets:
<<list filter [tag[StyleSheetShadow]]>>
Tags relating to HTML markup:
<<list filter [tag[MarkupShadow]]>>
Tags relating to page presentation:
<<list filter [tag[PageShadow]]>>
Tags relating to page title (a subset of page presentation):
<<list filter [tag[TitleShadow]]>>
Tags relating to sidebar tabs (a subset of page presentation):
<<list filter [tag[TabShadow]]>>
Shows a [[sparkline|http://en.wikipedia.org/wiki/Sparkline]] graphic, rendered using pure CSS (no image).

!Usage

{{{
<<sparkline [number1] [number2] ... [numberN]>>
}}}

!Example
{{{
<<sparkline 1 1 2 3 5 8>>
}}}
<<sparkline 1 1 2 3 5 8>>

will show a sparkline depicting the specified data points.
Includes a list of orphan tiddlers, using the [[list macro]] , and is included from [[vanilla]] [[TabMore shadow]].
[[Welcome]]
todo explain

|''formatter''|''purpose''|''example of matched text''|
|table|todo|todo|

see also: http://www.tiddlytools.com/insideTW/#config.formatters
In [[vanilla]] TiddlyWiki, includes several tabs for "special" tiddlers: missing, orphans, and shadowed. It works by including the shadows [[TabMoreMissing shadow]], [[TabMoreOrphans shadow]], and [[TabMoreShadowed shadow]] and is included from the [[SideBarTabs shadow]].
A keyboard shortcut.

Access keys are defined by a single character, e.g. "n" to create a new tiddler. ''However'', each browser and operating system has a different mechanism for activating it, e.g. on Firefox, you'll need to type "ctrl-n".

Following is a list of known browsers and shortcuts:

|Chrome||
|Firefox|Ctrl|
|IE||
|Opera||
|Safari|~Ctrl-Alt|

@ EXPERT - need to fill this in for mac and windows
A shadow is a default [[tiddler]] used by TiddlyWiki to define content such as the Stylesheet and ColorPalette. By default shadow tiddlers are tagged <<tag shadow>> -- see [[Shadows]]. In addition a set of built-in shadow tiddlers define functions the SideBarTabs and values such as the SiteTitle, SiteUrl, etc: 

<<list shadowed>>
Shows a list of tiddlers. Depending on the parameter, it can show all tiddlers in the document or a particular subset of them.

!Usage

{{{
<<list [type]>>
}}}

|type|Optional parameter indicating which tiddlers to show (see below). If omitted, all tiddlers will be shown.|

type can be one of:

|all|Matches every tiddler; hence shows all tiddlers and is equivalent to using the macro without any arguments.|
|missing|Tiddler titles which are referenced, but for which no tiddler yet exists|
|orphans|Tiddlers which are not referenced by any other tiddler|
|shadowed|Shows all tiddlers corresponding to [[Shadows]]. This is true whether or not the tiddler exists, i.e. whether or not a tiddler is overriding the shadow. If it's not overriding the shadow, it will be linked to the underlying shadow and shown (by default) as italic to indicate it's a missing tiddler.|
|touched|Tiddlers which have been updated since they were created or downloaded (checks if changeCount field is greater than zero).|
|filter|Performs filtering and sorting. Matches one or more custom filters, which are declared as subsequent parameters beyond this //type// parameter. A special "sort" parameter may also be included, but it only works if other filters are provided too. See [[Filters]] and examples below.|

!Examples

!Basic

{{{
<<list>>
}}}

or 

{{{
<<list all>>
}}}

will output a list of all tiddlers, linking to the underlying tiddler:

[[AdvancedOptions]]
[[Commands]]
...
...

!With standard "type" argument

{{{
<<list shadowed>>
}}}

shows, for the current document:

<<list shadowed>>

!With filter argument

{{{
<<list filter [tag[definition]]>>
}}}

will show tiddlers tagged as //definition//:

<<list filter [tag[definition]]>>

!With sort argument:

{{{
<<list filter [tag[definition]] [sort[-modified]]>>
}}}

will show tiddlers tagged as //definition// and sorted on modified, in reverse order (most recently modified tiddlers first):

<<list filter [tag[definition]] [sort[-modified]]>>

!With multiple filter arguments

{{{
<<list filter [tag[macro]] [tag[internal]]>>
}}}

will combine tiddlers tagged as //macro// and tiddlers tagged as //internal//:

<<list filter "[tag[internal]] [tag[deprecated]]">>

!With negative filter arguments
{{{
<<list filter "[tag[macro]] [!tag[internal]]">>
}}}
<<list filter "[tag[macro]] [!tag[internal]]">>

@EXPERT - mentioned here -http://lewcid.org/2007/10/23/how-to-list-tiddlers-by-tags-the-filter-tipped-way/
did it happen?

!References

[How To List Tiddlers By Tags: The Filter Tipped Way|http://lewcid.org/2007/10/23/how-to-list-tiddlers-by-tags-the-filter-tipped-way/]
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
The goal of this document is to be as comprehensive TiddlyWiki  reference as possible. It would be of particular interest to people who are already familiar with the basics of TiddlyWiki.

See http://tiddlywiki.com for more general info about TiddlyWiki and links to other resources.

Right now, it's just a skeleton document so we can divvy up the work.
----
User question: Is it OK to edit this document??

Test Type the text for 'New Tiddler'

Includes the definitions for what appears in the tiddler toolbars. It works using the [[slice]] mechanism: this shadow contains a slice for the value of the View toolbar (invoked from the [[vanilla]] [[ViewTemplate shadow]]) and a separate slice for the value of the Edit toolbar (invoked from the [[vanilla]] [[EditTemplate shadow]]).

|~ViewToolbar|revisions closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
/***
|''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);
//}}}
This term is only used in this documentation to denote [[Shadows]] relating to page content.
Shows a button for a tag which, when clicked, will present a popup menu enabling the user to open: any tiddler with that tag; all tiddlers with that tag; or "the tag itself", i.e. the tiddler whose title is that tag.

!Usage

{{{
<<tag tagName [label] [tooltip]>>
}}}

|tagName|The tag on which the popup menu will be based|
|label|The label shown on the button|
|tooltip|Tooltip shown when the mouse hovers over the button|

!Example

!!Basic Usage

{{{
<<tag systemConfig>>
}}}

will show a button with popup menu about all tiddlers tagged systemConfig:

<<tag systemConfig>>

!!With All Parameters

{{{
<<tag systemConfig plugins "browse tiddlywiki plugins">>
}}}

will show a button with popup menu about all tiddlers tagged systemConfig, with the button label and tooltip specified.

<<tag systemConfig plugins "browse tiddlywiki plugins">>
/***
|''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);
//}}}
You should set this to the URL your site is located at. It's used for saving [[RSS]].
Background: #fff
Foreground: #000
PrimaryPale: #1ff
PrimaryLight: #78f
PrimaryMid: #029
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Type the text for 'Movie Review'
Outputs the TiddlyWiki version number.

!Usage

{{{
  <<version>>
}}}

!Example

The basic usage shows, for the present document:
<<version>>
The contents of this tiddler are included at the start of the head section in the TiddlyWiki HTML, i.e. just after the <head> tag. See MarkupShadow for more info.
Includes a list of shadow tiddlers, using the [[list macro]], and is included from the [[vanilla]] [[TabMore shadow]].
<<options>>
This term is only used in this documentation to denote [[Shadows]] relating to HTML markup.
Shows a list of links to each tiddler tagged with a certain tag name.

!Usage

{{{
<<tagging [tag] [sep:separator]>>
}}}

|tag|Tag name. If omitted, will default to the title of the corresponding tiddler.|
|separator|Separator. Shown between each tiddler title.|

!Examples

!Basic Usage

{{{
<<tagging>>
}}}

if included in a tiddler called [[systemConfig]], will show all tiddlers marked systemConfig:

!Tag Parameter

{{{
<<tagging systemConfig>>
}}}

will show all tiddlers tagged systemConfig (regardless of where this macro is used):

<<tagging systemConfig>>

!Separator and Tag Parameter

{{{
<<tagging sep:------ systemConfig>>
}}}

will show all tiddlers tagged systemConfig with the "--------" separator:

<<tagging sep:------ systemConfig>>
This term is only used in this documentation to denote [[Shadows]] relating to default content.
A slice refers to a key-value pair inside the tiddler. Any tables inside the tiddler are able to be used as slice sources, and only the first two columns are considered for this purpose. The first column is the name of the slice; the second column is its value. For examples see the [[tiddler macro]]. You can also use a colon notation which is how the StyleSheet shadows use slices to take color values from the [[ColorPalette|ColorPalette shadow]].

ColorPalette
{{{
Background: #fff
Foreground: #000
PrimaryPale: #1ff
PrimaryLight: #78f
...
}}}
The usage can be seen in: StyleSheetColors shadow tiddler
Shows a button which, when clicked, will produce a new tiddler.

!Usage
{{{
<<newTiddler [param:value] [param:value] ...>>
}}}
where the optional parameter-value pairs are described below.

Parameters affecting button appearance and usage:
|label|button label|
|prompt|button tooltip|
|accessKey|single letter to use as an [[access key]] to trigger the button|

Parameters affecting default state of new tiddler:
|title|title for the new tiddler (defaults to "New Tiddler")|
|text|contents for the new tiddler|
|tag|tag to be applied to the new tiddler (parameter can be used repeatedly to specify multiple tags)|
|template|name of the HTML template used to display the new tiddler (defaults to EditTemplate)|
|fields|custom fields to be assigned to the new tiddler (space-separated list of key:value pairs; e.g. fields:"k1:v1 k2:v2")|

Parameters affecting interaction with new tiddler:
|focus|which of the editable fields will be focused when the new tiddler is first shown (e.g. "title", "text", "tags")|

!Examples
!!basic
{{{
<<newTiddler>>
}}}
will generate a standard New Tiddler button, which will generate a tiddler called "New Tiddler":

{{{
<<newTiddler label:"review new movie" prompt:"create a new movie review" title:"Movie Review">>
}}}

!!parameters affecting button appearance and usage

{{{
<<newTiddler label:"review new movie" prompt:"create a new movie review" accessKey:"m">>
}}}
will generate a button with label and prompt (tooltip) as defined and activated with the [[access key]] "m".

<<newTiddler label:"review new movie" prompt:"create a new movie review" accessKey:"m">>

!!parameters affecting state of new tiddler:

<<newTiddler title:"New Movie" fields:"status:incomplete rating:5" text:"!Movie Name

!Plot Synopsis

!Overall Recommendation" tag:Movie tag:Comedy>>

EXPERT this doesn't work properly!
!Generic Utilities

The following are generic utility files, with no or few references to any ~TiddlyWiki-specific concepts. They were written before mainstream libraries appeared in the Javascript world, and before one such library, jQuery, was incorporated into the TiddlyWiki core. You therefore ought to consider using the jQuery equivalent, if one exists in preference to any of these.

|''file''|''jQuery Equivalent''|''purpose''|
|Animation|todo||
|~BasicTypes|todo||
|Crypto|todo||
|Dates|||
|Dom|||
|Http|||
|RGB||
|Strings||
|Sparkline||
|Utilities||

todo complete
Shows a control (checkbox or text field) to let the user set an [[option]].

!Usage

{{{
<<option Option [className]>>
}}}

or

{{{
<<option name:Option [class:className]>>
}}}

where Option is the name of the [[option]] to be set and className is a CSS class name attached to the control. See [[Options]] for a list of all options.

!Example

{{{
<<option chkAnimate>>
}}}

Shows a checkbox to let the user set the animation option, defaulted to its current setting:

<<option chkAnimate>>

If you click on the checkbox and then open or close a tiddler, you'll notice it has an immediate effect on the animation setting.

!See Also
[[option macro]]
Shows a tiddler's. The field may be a standard field (e.g. "tags", "title", "text"), or a custom field.

This macro is typically used inside template, e.g. in the default ViewTemplate.

!Usage
{{{
<<view field [handler]>>
}}}

|field|a tiddler field (e.g. "tags", "title", "text")|
|handler|a handler which determines how the field is rendered (defaults to "text"); see below|

In the core, "handler" may be one of:

|text|raw field value|
|link|a link to a tiddler (i.e. the field value is interpreted as a tiddler title)|
|wikified|formatted as wiki text, based on standard [[TiddlyWiki markup]]|
|date|shown as a human-readable date, where the field value is interpreted as being in YYYYMMDDHHMM format|

!Examples
see [[Fields]]
!!Basic Usage

{{{
<<view text>>
}}}

will show the entire text for the present tiddler.

!!Text and Wikifier

{{{
<<view text wikified>>
}}}

Will show the entire text for the present tiddler, rendered using wiki markup. Do only use it with templates. If you use it in a tiddler it will casue a "too much recursion" error, because it renders itself, which is not possible!
A section refers to a section of text inside the tiddler. This is the text between one heading and another heading (or to the end of the document, in the case of the final section). The name of the section is the title. The level of heading (!, !!, !!!, i.e. heading level 1, 2, 3, etc.) is irrelevant for this purpose. See also [[slice]].

Sections can be transcluded with the tiddler macro. eg: {{{<<tiddler section##SectionStart>>}}} <<tiddler section##SectionStart>>
{{{
!SectionStart
>Some text inside a section
!end
This text is outside the section
}}}

Adds a button to invoke a task on backstage.

!Usage

{{{
  <<backstage task>>
}}}

|task|a task in config.tasks, e.g. if task is "foo", config.tasks["foo"] will be looked up to locate a task specification object|

EXPERT

is this actually used?
This term is only used in this documentation to denote [[Shadows]] relating to sidebar tabs (see [[SideBarTabs shadow]]).
A TiddlyWiki [[option]] which when set removes the [[commands|command]] for editing and deleting tiddlers and prevents saving. The option is automatically set when serving a TiddlyWiki from a http Url.
The contents of this tiddler are included at the end of the body section in the TiddlyWiki HTML, i.e. just before the <body/> tag. See MarkupShadow for more info.
Contains CSS definitions related to the page layout. You should generally leave this alone and change StyleSheet instead, for reasons described in StyleSheet shadow.
Identifies colours used in stylesheets.

There is no special magic in the core to perform substitutions on this particular shadow, because they are included using the regular slice mechanism; a stylesheet shadow tiddler says: <html>{ color: [[ColorPalette##PrimaryPale]]; }</html> for example, and the slice mechanism automatically converts it to ''color: #fff'' (assuming there's a line in the [[ColorPalette shadow]] that says '''~PrimaryPale: #fff''.

Link ColorPalette | <<slider chkColorPalette ColorPalette 'view ColorPalette shadow tiddler'>>
Shows a list of a tiddler's tags.

!Usage

<<tags [tiddler] [sep:separator]>>

|!parameter|!meaning|
|tiddler|Title of the tiddler (the containing tiddler by default).|
|separator|Separator shown between each tag.|

!Basic Usage

{{{
<<tags>>
}}}

will show the tags for the present tiddler:

<<tags>>

!Tiddler Parameter

{{{
<<tags "sparkline macro">>
}}}

will show the tags for the tiddler called "sparkline macro":

<<tags "sparkline macro">>

!Tiddler Parameter and Separator

{{{
<<tags "sparkline macro" sep:"------">>
}}}

will show the tags for the tiddler called "sparkline macro" with the specified separator:

<<tags "sparkline macro" sep:"------">>
Attention called to unclear explanations due to errors or other possibly faulty information.
(Tiddlers are tagged with @ sign)

<<list filter [tag[@]]>>
Type the text for 'New Tiddler'
Shows a form allowing the user to import tiddlers. Used internally for backstage implementation.

!Usage

{{{
<<importTiddlers>>
}}}

!Example

The basic usage will yield:

<<importTiddlers>>
Shows a table of all options (as defined in the config.options object), allowing each to be set.

!Usage

{{{
<<options [showUnknown:yesOrNo]>>
}}}

|showUnknown|optional parameter indicating whether to show unknown (not standard TiddlyWiki) options. Will be true if (and only if) showUnknown is "yes", i.e. showUnknown:yes|

!Example

{{{
<<options>>
}}}

shows:

<<options>>

!See Also
[[option macro]]
A list of space-separated [[tiddler links]] indicating the tiddlers that should be shown when the tiddlywiki  is first loaded. This may be ignored if  [[Paramifiers]] are present on the URL that cause an alternative list of tiddlers to be shown.

Link DefaultTiddlers| <<slider chkDefaultTiddlers DefaultTiddlers 'view DefaultTiddlers tiddler'>>

<<tiddler list [tag[definition]]>>
<<options>>
Contains CSS definitions used when printing the TiddlyWiki.
A [[tiddler]] containing Javascript code and tagged with <<tag systemConfig>> to add features or change behaviour, for example this TiddlyWiki contains the following plugins:
<<tagging systemConfig>>
which may be managed using the [[plugins macro]].
Shows the current date and time.

!Usage

{{{
  <<today [format]>>
}}}

|!parameter|!meaning|
|format|controls format of date ouput|

!Examples

!!Basic Usage

{{{
  <<today>>
}}}

will show, for the present document:
<<today>>

!!Date Format Parameter

{{{
  <<today "YYYY-0MM-0DD">>
}}}

will show, for the present document:
<<today "YYYY-0MM-0DD">>
description description description

!Usage

{{{
  <<macro [format]>>
}}}

|format|date format string|

!Examples

!!simple

{{{
  <<macro>>
}}}

outputs, for the present document:
<<today>>

!!param


{{{
  <<macro format>>
}}}

outputs, for the present document:
<<macro YYYY-MM-DD>>
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>
Similar to the [[tiddler macro]], shows text from other tiddlers. In this case, though, a tabbed interface is used to show multiple tiddler content in the same space, where the user switches tabs to see the different content.

!Usage

{{{
<<tabs cookieID [label1 tooltip1 tiddler1] [label2 tooltip2 tiddler2] ... [labelN tooltipN tiddlerN]>>
}}}

|cookieID|A unique ID to ensure the user's chosen tab setting is preserved the next time the user visits this tiddlywiki.|
|labelN|label shown on the tab itself|
|tooltipN|tooltip shown when mouse hovers over the tab|
|tiddlerN|title of the tiddler whose content is shown when user switches to this tab|

!Example

{{{
<<tabs definitionTab "story definition" "see what a story is" "story" "theme definition" "how to make a  theme" "theme" "shadow definition" "info on shadow tiddlers" "shadow">>
}}}

will show the tiddlers "story", "theme", and "shadow", with corresponding tab labels and tooltips. The unique ID "definitionTab" (unique for this tiddlywiki) ensures that when you switch to a tab, that tab will be open next time you view the TiddlyWiki.

<<tabs definitionTab "story definition" "see what a story is" "story" "theme definition" "how to make a  theme" "theme" "shadow definition" "info on shadow tiddlers" "shadow">>
This term is only used in this documentation to denote [[Shadows]] relating to default content.
Shows list of tags in the document, each linking to the tiddler whose title is the tag name.

!Usage

{{{
  <<allTags [excludeTag]>>
}}}

|excludeTag|a tag to be excluded from the results (only one excludeTag may be specified).|

!Examples

!!simple

{{{
  <<allTags>>
}}}

outputs, for the present document:
<<allTags>>

!!excludeTags


{{{
  <<allTags systemConfig>>
}}}

outputs, for the present document:
<<allTags systemConfig>>

(TODO this is buggy - shows systemConfig?)
[[Tags]]
[[Config Values]]
[[Options]]
[[Commands]]
[[Formatters]]
[[Paramifiers]]
[[Fields]]
[[Errors]]

![[Macros]]
<<list filter [tag[macro]]>>
![[Shadows]]
<<list filter [tag[shadow]]>>
![[Definitions]]
<<list filter [tag[definition]]>>

[[Code Utilities]]
[[Plugin Coding Style]]
[[Filters]]
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
/***
|''Name:''|DiffFormatterPlugin|
|''Description:''|Extension of TiddlyWiki syntax to support Diff text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#DiffFormatterPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/DiffFormatterPlugin.js |
|''Version:''|0.0.3|
|''Date:''|Sep 11, 2009|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.1.0|

This is an early release of the DiffFormatterPlugin, which extends the TiddlyWiki syntax to support Diff
text formatting.

The Diff formatter is different from the other formatters in that Tiddlers are not required to be
tagged: instead the Diff format adds formatting that augments TiddlyWiki's format.

The Diff formatter adds the following:
# ^+ for added
# ^- for removed
# ^"""@@ """, """--- """ and """+++ """ for special markers

Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
!StyleSheet
.viewer .removed { background: #fdd; }
.viewer .added { background: #dfd; }
!Code
***/
//{{{
// Ensure that the DiffFormatterPlugin is only installed once.
if(!version.extensions.DiffFormatterPlugin) {
version.extensions.DiffFormatterPlugin = {installed:true};

if(version.major < 2 || (version.major == 2 && version.minor < 1)) {
	alertAndThrow('DiffFormatterPlugin requires TiddlyWiki 2.1 or later.');
}

diffFormatter = {}; // 'namespace' for local functions

diffFormatter.init = function() {
	var stylesheet = store.getTiddlerText(tiddler.title + "##StyleSheet");
	if(stylesheet) { // check necessary because it happens more than once for some reason
		config.shadowTiddlers["StyleSheetDiffFormatter"] = stylesheet;
		store.addNotification("StyleSheetDiffFormatter", refreshStyles);
	}
};

diffFormatter.added = {
	name: 'diffAdded',
	match: '^\\+',
	termRegExp: /(\n)/mg,
	handler: function(w)
	{
		var e = createTiddlyElement(w.output,'span',null,'added');
		w.subWikifyTerm(e,this.termRegExp);
		createTiddlyElement(w.output,'br');
	}
};

diffFormatter.removed = {
	name: 'diffRemoved',
	match: '^-',
	termRegExp: /(\n)/mg,
	handler: function(w)
	{
		var e = createTiddlyElement(w.output,'span',null,'removed');
		w.subWikifyTerm(e,this.termRegExp);
		createTiddlyElement(w.output,'br');
	}
};

diffFormatter.charDiff = {
	name: 'diffChars',
	match: '^(?:@@|[+-]{3}) ',
	lookaheadRegExp: /^(?:@@|[+-]{3}) .*\n/mg,
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
};

// add new formatters
diffFormatter.init();
config.formatters.push(diffFormatter.added);
config.formatters.push(diffFormatter.removed);

diffFormatter.replaceFormatter = function()
{
	for(var i=0; i<config.formatters.length; i++) {
		if(config.formatters[i].name == 'characterFormat') {
			config.formatters.splice(i,0,diffFormatter.charDiff);
			break;
		}
	}
};
diffFormatter.replaceFormatter();

}// end of 'install only once'
//}}}
[[Welcome]]
[[Contents]]
[[attention]] (tag: @)

<<tiddler Contents>>
<<version>>
Shows advanced options. In the core, the content for this tiddler is simply the [[options macro]].
This is the fundamental definition of the TiddlyWiki user-interface. It defines the composition of the entire page. You can apply changes to the TiddlyWiki appearance, ranging from the subtle to the radical, by modifying this shadow.

There's one gotcha to be aware of if overriding this shadow: You do need to ensure the ~TiddlerDisplay div is present (which you would want to do anyway in most cases). If you don't want to show it, just add the following to the [[StyleSheet shadow]]:

.tiddlerDisplay { display: none; }

Link PageTemplate | <<slider chkPageTemplate PageTemplate 'view PageTemplate tiddler'>>
The Javascript config object contains a number of configurable parameters used to control TiddlyWiki. Most of these appear as [[Options]], the remainder may be changed using Javascript:

|!Name |!Default Value |!Description |
|animDuration | 400|Duration of UI animations in milliseconds |
|browser | |Information about the current browser, see below |
|cascadeFast | 20|Speed for cascade animations (higher == slower) |
|cascadeSlow | 60|Speed for ~EasterEgg cascade animations |
|cascadeDepth | 5|Depth of cascade animation |
|extensions | |Place for a [[plugin]] to store data |
|locale | "en"|Language attribute |
|macros |  |see [[Macros]] |
|numRssItems | 20|Number of items in the RSS feed |
|version | |Place for a [[plugin]] to store version information |

The {{{browser}}} value has the following boolean values, which may be useful for sniffing the current browser type:

|browser | variable | your settings |h
|isIE |{{{config.browser.isIE}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isIE}}>> |
|isGecko |{{{config.browser.isGecko}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isGecko}}>> |
|ieVersion |{{{config.browser.isVersion}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isVersion}}>> |
|isSafari |{{{config.browser.isSafari}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isSafari}}>> |
|isBadSafari |{{{config.browser.isBadSafari}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isBadSafari}}>> |
|firefoxDate |{{{config.browser.firefoxDate}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.firefoxDate}}>> |
|isOpera |{{{config.browser.isOpera}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isOpera}}>> |
|isLinux |{{{config.browser.isLinux}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isLinux}}>> |
|isUnix |{{{config.browser.isUnix}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isUnix}}>> |
|isMac |{{{config.browser.isMac}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isMac}}>> |
|isWindows |{{{config.browser.isWindows}}} | <<tiddler {{tiddler.title+'##echo'}} with: {{config.browser.isWindows}}>> |

/%
!echo
$1
!end
%/
!server.content-type

| server.content-type | description, what happens if field contains ?|h
|text/javascript| ?? |
|image/svg+xml| ?? |

Learn more about custom [[Fields]].

!!!Learn more
http://en.wikipedia.org/wiki/Internet_media_type
Shows a toolbar consisting of [[commands|command]] related to the current tiddler.

!Usage

{{{
<<toolbar [(+)command1] [(+) command2] ... [(+)commandN] [>] [commandJ] [commandK] ... [commandL]>>
}}}


The parameters are a list of commands. The commands of same name will activate when the user clicks on them.

One (at most) of the commands may be preceded by a "+" symbol, which indicates it's the default action, and will therefore be activated when the tiddler is double-clicked or the ctrl-enter combination is used.

The ">" symbol may optionally appear somewhere in the list. Any commands after this list are not shown by default; instead a "more" button appears, which the user must click to reveal those additional commands.

!Examples

!!Basic Usage

{{{
<<toolbar closeOthers editTiddler>>
}}}

<<toolbar closeOthers editTiddler>>

!!Default Action (+ symbol)

{{{
<<toolbar closeOthers +editTiddler>>
}}}

<<toolbar closeOthers +editTiddler>>

!!Revealing Further Actions (> symbol)

{{{
<<toolbar closeOthers +editTiddler > fields permalink>>
}}}

<<toolbar closeOthers +editTiddler > < * fields permalink > < * closeOthers  >>
The story is the name for the Javascript object of type {{{Story}}}, a list of tiddlers representing the displayArea, the portion of the page where tiddlers are displayed.
Type the text for 'New Tiddler'
Contains CSS definitions related to the current locale (used for internationalisation). You should generally leave this alone and change StyleSheet instead, for reasons described in [[StyleSheet shadow]].
todo explain tags

Certain tags have special significance in TiddlyWiki. They are:

|''tag''|''purpose''|
|''excludeLists''|indicates the tiddler should not show up in lists of tiddlers (used by the [[list macro]]|
|''excludeSearch''|indicates the tiddler should not show up in searches of tiddlers|
|''systemConfig''|a [[plugin]]|
|''systemTheme''|a [[theme]]|

@ expert any others?
Contains CSS definitions related to the color of page elements. You should generally leave this alone and change ~StyleSheet instead, for reasons described in [[StyleSheet shadow]].
<<option chkToBeDone>>''To Be Done'', <<option chkForwardedTo..>>''Forwarded To..'', <<option chkMaybe>>''Maybe'', <<option chkWishTo>>''Wish To'', <<option chkDone>>''__Done__''

{{{
<<option chkToBeDone>>''To Be Done'', 
<<option chkForwardedTo..>>''Forwarded To..'', 
<<option chkMaybe>>''Maybe'', 
<<option chkWishTo>>''Wish To'', 
<<option chkDone>>''__Done__''
}}}
Similar to [[list macro]], shows a list of all tiddlers. In this case, the tiddlers are always sorted by date, with a separate section for each unique day.

!Usage

{{{
<<timeline [dateField] [amount] [format]>>
}}}

|dateField|date field to sort by ("modified" by default; could also be "created")|
|amount|maximum amount of tiddlers to show (all by default)|
|format|date format|

!Examples

!!Basic Usage

{{{
<<timeline>>
}}}

will show a basic timeline of all tiddlers:

<<timeline>>

!!All Parameters

{{{
<<timeline "modified" "10" "ddd, YYYY-0MM-0DD">>
}}}

will sort on last modified date, showing a maximum of 10 tiddlers, in the specified date format.

<<timeline "modified" "10" "ddd, YYYY-0MM-0DD">>
<<today "DD-MMM-YYYY" >>
The store is the name of a Javascript variable of type TiddlyWiki which contains a copy of all of the tiddlers including those visible in the [[story]].
Commands are actions that may appear in the toolbar macro. See [[toolbar macro]] for more info.

|''command''|''purpose''|
|closeTiddler|close the tiddler|
|closeOthers|close all other tiddlers|
|editTiddler|edit the tiddler|
|saveTiddler|save changes to the tiddler (edit mode only)|
|cancelTiddler|undo any changes to the tiddler|
|deleteTiddler|delete the tiddler (edit mode only)|
|permalink|produce a permalink to the tiddler|
|references|popup to show tiddlers that link to the tiddler|
|jump|popup to jump to another open tiddler|
|syncing|popup to control synchronisation of the tiddler with a server or external file|
|fields|popup to show the extended fields of the tiddler|
A [[configuration value|Config Values]] which may be adjusted using the [[Options]] or [[AdvancedOptions]] panel whose value is typically saved as a browser cookie.

{{{
<<option chkChecker>> Check it !
}}}
<<option chkChecker>> Check it !
Will produce a cookie which can be found at {{{config.options.chkChecker}}}

{{{
<<option txtSomeText>> Enter some text!
}}}
<<option txtSomeText>> Enter some text!
Will produce a cookie which can be found at {{{config.options.txtSomeText}}}
Show button which, when clicked, will produce a new tiddler with a special title corresponding to today's date, ideal for a ~TiddlyWiki-powered journal/blog.

!Usage

{{{
<<newJournal params>>
}}}

The new tiddler will have a title in the form, "15 February 2010".

Shares parameters with [[newTiddler macro]].

!Example

{{{
<<newJournal>>
}}}

will generate a newJournal button:

<<newJournal>>

See [[newTiddler macro]] for additional parameters.
EXPERT -> please fill in

!Usage

{{{
  <<annnotations [param]>>
}}}

|param|does something|

!Examples

!!simple

{{{
  <<annotations>>
}}}

outputs, for the present document:
<<annotations>>

!!param


{{{
  <<macro param>>
}}}

outputs, for the present document:
<<macro param>>
Shows a control to edit a field of the tiddler. The field may be a standard field (e.g. "tags", "title", "text"), or a custom field.

This macro is typically used inside [[template]], e.g. in the default EditTemplate. Due to a bug in the implementation, it should not be included in the text as an double angle bracket macro. (Doing so makes the tiddler uneditable.)

!Usage

Inside a [[template]]:

{{{
<div class='editor' macro='edit [field]'></div>
}}}

|field|name of a tiddler field. If the field is "text", it's handled as a special case and will show a textarea instead of an input text field.|

!Example

Due to the bug mentioned above, there is no example using the double angle bracket macro. Following is an example of what you might include in an edit template, where this macro is indeed valid:

{{{
<div class='editor' macro='edit text'></div>
}}}

will allow the user to edit this tiddler's text field.

!See Also

[[view]]
This term is only used in this documentation to denote [[Shadows]] relating to tiddler appearance.
This shadow contains CSS to customise the TiddlyWiki and is left empty in the [[vanilla]] TiddlyWiki, so you can add any customisations. It's applied last, after applying the other StyleSheet shadows.

Generally speaking, you should only override this shadow and not any of the StyleSheet<something> shadows, as those are subject to change in future editions of TiddlyWiki, so changing those would require you to merge your changes when upgrading.
This term is only used in this documentation to denote Shadows relating to TiddlyWiki titles.
guidance for designing ~TiddlyWiki applications
Type the text for '15 February 2010'
In [[vanilla]] TiddlyWiki, this is included in Backstage. It simply contains the [[plugins macro]].
TiddlyWiki is a personal notebook which runs in the browser. You can save the tiddlywiki to your local filesystem or use one of several services to save it on a server.

For more info, please visit http://tiddlywiki.com.

Note: In the core code, "TiddlyWiki" refers to the store of tiddlers. For most intents and purposes, it's equivalent to "store". (In fact, the "store" is a global variable of type "TiddlyWiki", but since it is usually the *only* instance of TiddlyWiki, it is effectively synonomous with TiddlyWiki.)
A name used to describe an empty TiddlyWiki.
Includes a list of tiddler tags, using the [[list macro]], and is included from the [[vanilla]] [[SideBarTabs shadow]].
Shows a status of all [[plugins|plugin]] in the document, allowing users to disable them. Used in backstage.

!Usage

{{{
<<plugins>>
}}}

!Example

The basic usage shows all plugins in the present document:

<<plugins>>
/*{{{*/
#mainMenu { text-align: left; padding-left: 1em; }
#mainMenu h1 { font-size: 1em; border: 0; margin: 0; }
#mainMenu ul { list-style-type: none; padding: 0.1em 1em; margin: 0; font-size: x-small; }
/*}}}*/
A macro is a function which may be reference in wikitext between {{{<<braces>>}}} often provided by a [[plugin]]. See [[Macros]].

See http://tiddlywiki.org/wiki/TiddlyWiki_markup

TODO incorporate that page here.

This is a demo tiddler.

It contains some info about TiddlyWiki's history.

For example, TiddlyWiki was first conceived in 1805 and expressed as a series of matrices involving transformations of values in the complex number space. It was not until Javascript was invented that it became of practical value.
~TiddlyWiki Reference
This term is only used in this documentation to denote [[Shadows]] relating to default content.
The contents of this tiddler are included at the start of the head section in the TiddlyWiki HTML, i.e. just after the <head> tag. See MarkupShadow for more info.
Included via the [[vanilla]] [[SideBarTabs shadow]] and calls the [[list macro]].
A template is a tiddler containg HTML with embedded [[macros|macro]] which TiddlyWiki uses to guide the generation of the page and the display of tiddlers. See [[PageTemplate shadow]], [[ViewTemplate shadow]] and [[EditTemplate shadow]].
Shows some information for new users about how to get started with TiddlyWiki. This is what users see when they launch a [[vanilla]] TiddlyWiki, by virtue of the fact that "GettingStarted" is what appears in the [[DefaultTiddlers shadow]].
Shows contents of named tiddler.

!Usage

{{{
  <<tiddler [title] [with: "param1" "param2" ...]>>
}}}

|title|mandatory|Title of tiddler to include. This can be a title (//title//), a slice (//title::slice//), or a section (//title##section//).|
|with:|optional|Values substituted in through transclusion. A "$1" in the named tiddler will be replaced by "param1" here.|

A title refers to the entire tiddler; the entire tiddler's content will be included.

A [[slice]] refers to a key-value pair inside the tiddler. Any tables inside the tiddler are able to be used as slice sources, and only the first two columns are considered for this purpose. The first column is the name of the slice; the second column is its value. You can also use a colon notation. The possibilities are shown below:

{{{
theName: textSlice
|theName:| textSlice |
|theName| textSlice |
}}}

A [[section]] refers to a section of text inside the tiddler. This is the text between one heading and another heading (or to the end of the document, in the case of the final section). The name of the section is the title. The level of heading (!, !!, !!!, i.e. heading level 1, 2, 3, etc.) is irrelevant for this purpose. See the example below for more info.

!Examples

!!simple

The macro:
{{{
  <<tiddler DaVinciCode>>
}}}

where "~DaVinciCode" tiddler is:
{{{
The DaVinci Code, by Dan Brown.
}}}

will output:
{{{
The DaVinci Code, by Dan Brown.
}}}

!!sections

The macro:
{{{
  <<tiddler DaVinciCode##title>>

  About the author: <<tiddler DaVinciCode##author>>
}}}

where "DaVinciCode" tiddler is:
{{{
!title
The ~DaVinci Code

!publication date
2003

!author
Dan Brown, not to be confused with Ban Drown, wrote this book.

}}}

will output:

{{{
  The DaVinci Code

  About the author: Dan Brown, not to be confused with Ban Drown, wrote this book.
}}}

!!slices

The macro:
{{{
  The author <<tiddler [[DaVinciCode::author]]>> wrote the book, ''<<tiddler [[DaVinciCode::title]]>>''.
}}}

where "~DaVinciCode" tiddler is:
{{{
|author|Dan Brown|
|publication date|2003|
|title|The DaVinci Code|
}}}

will output:

{{{
  The author Dan Brown wrote the book, 'The DaVinci Code''.
}}}

!!transclusion

The macro:
{{{
  <<tiddler book with:"Dan Brown" "The DaVinci Code">>
}}}

where "book" tiddler is:
{{{
A work by $1 called:
- $2 -
}}}

will output:
{{{
A work by Dan Brown called:
- The DaVinci Code -
}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
Refreshes the display, ensuring shadow tiddlers are taken into account and tiddlers are transcluded correctly.

EXPERT please confirm ^

<<refreshDisplay>>

!Usage

{{{
<<refreshDisplay>>
}}}

!Example

The basic usage will yield a button which will refresh the display (clicking it will probably have no visible effect as the display is likely already refreshed).
<<today>>
<<refreshDisplay>>
From: http://tiddlyweb.peermore.com/wiki see: Documentation
<<<
TiddlyWeb is an open source web-based storage system with a robust HTTP API, making each record a directly addressable unit of micro-content. It operates, amongst other things, as a server side for TiddlyWiki.

Data collections can be accessed via recipes which combine bags, which in turn are collections of tiddlers (diagram).
<<<
/***
|''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);
//}}}
Shows a button which, when clicked, will produce a list of tags. Clicking on one of the tags will tag the containing tiddler accordingly.

!Usage

{{{
<<tagChooser [excludeTag]>>
}}}

|excludeTag|a tag which will not be shown in the list|

!Example

!!Basic Usage

{{{
<<tagChooser>>
}}}

will produce a button which, when clicked, will show all tags in this document:

<<tagChooser [excludeTag]>>

EXPERT not working? (also excludeTag is ignored?)
<<search>>
/***
|''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 = "&#8230;";
			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";

})();
//}}}
Content for Advanced Options block, which by default is linked from the bottom of the regular, solid-blue, options block on the right-hand sidebar.
todo explain general plugin coding style, and special fields (Name, Description, etc)
todo explain fields and custom fields

Following are the special fields set and used by the core TiddlyWiki code:

| ''field'' | ''purpose'' | macro call | value |h
|title |the tiddler title | {{{<<view title wikified>>}}} |<<view title wikified>>|
|tiddler |the tiddler title (as well) | {{{<<view tiddler wikified>>}}} |<<view tiddler wikified>>|
|text |the text of the tiddler | {{{<<view text wikified>>}}} | .. |
|modifier |the person who last modified it| {{{<<view modifier wikified>>}}} |<<view modifier wikified>>|
|modified |date&time of last modification | {{{<<view modified date>>}}} |<<view modified date>>|
|created |when it was created | {{{<<view created date>>}}} |<<view created date>>|
|creator |who initially created it | {{{<<view creator wikified>>}}} |<<view creator wikified>>|
|tags |the tiddler tags | {{{<<view tags wikified>>}}} |<<view tags wikified>>|
|fields |extended fields used for server side TW | eg: {{{<<view server.host wikified>>}}} |<<view server.host wikified>>|

eg: this tiddlers extended fields
|Field	| This tiddlers values |h
|server.bag	|<<view server.bag wikified>>|
|server.content-type |	see: [[server.content-type]]|
|server.host	|<<view server.host wikified>>|
|server.page.revision	|<<tiddler {{tiddler.title+'##echo'}} with: {{tiddler.fields['server.page.revision']}}>>|
|server.permissions	|<<view server.permissions wikified>>|
|server.recipe	|<<view server.recipe wikified>>|
|server.title	|<<view server.title wikified>>|
|server.type	|<<view server.type wikified>>|
|server.workspace	|<<view server.workspace wikified>>|

Learn more about the [[view macro]].


/%

<<view tags wikified>>
!echo
$1
!!end
%/
EXPERT how is this used?
todo
Defines the default [[template]] used to render the tiddler in view mode. In a [[vanilla]] TiddlyWiki, this is the main (read-only) view you see when you view tiddlers.

Link ViewTemplate | <<slider chkViewTemplate  ViewTemplate 'view ViewTemplate tiddler'>>
Includes a list of tiddlers, chronologically sorted, using the [[list macro]], and is included from the [[vanilla]] [[SideBarTabs shadow]].
Show a button to let the user save changes to the TiddlyWiki document. This will normally save them to the local file system, but may also save them elsewhere, e.g. to a TiddlyWeb server if the wiki was served by TiddlyWeb.

If the chkGenerateAnRssFeed option is set, it will save to a separate RSS file, in addition to the main TiddlyWiki HTML file.

This macro will not show anything if the TiddlyWiki is in [[read-only mode]].

!Usage

{{{
<<saveChanges [[label] title]>>
}}}
(To specify title, you must also specify label.)

|label|label text shown on the save changes button|
|title|tooltip title for the save changes button|
!Examples
!!Basic Usage
{{{
<<saveChanges>>
}}}
will show a basic saveChanges button:

<<saveChanges>>
!!With Parameters
{{{
<<saveChanges "Save The TiddlyWiki" "save">>
}}}
will show:

<<saveChanges "Save The TiddlyWiki" "save">>
Shows a prompt to upgrade TiddlyWiki.

!Usage
{{{
<<upgrade>>
}}}

!Example

The basic usage shows:

<<upgrade>>
Provides a control for exploring tiddlers in the current document, and appears in the right sidebar by virtue of being included in the [[vanilla]] [[PageTemplate shadow]]. The default shadow includes a tabbed interface, using the [[tabs macro]].

Development Process: The Happy Path
* [[Spiking]] mucking about with a live TiddlyWiki
* [[One-Click Create]] create...
* [[Cook]]
* [[Generic Plugins]] developing plugin with self-contained demo
* [[Testing]]
* [[Multi-User Deployment]]

Primitives
* [[Plugin Tiddler]] (reuse or new)
* [[Shadow Override Tiddler]]
* [[Content Tiddler]]
* [[Theme Tiddler]]
* [[User-Generated Tiddler]]

Design Task
* [[Blasting Appearance]] e.g. Overlay Plugin, TiddlySlidey
* [[Styling]] StyleSheet override
* [[Page Design]] PageTemplate, TitleShadows, [[Tiddler Design]]
* [[Tiddler Design]] EditTemplate, ViewTemplate, Toolbar
* [[Structured Data]] sections, slices
* [[Constrained Input]] Dropdowns etc
* [[Type Tag]] NewTiddler param; TaggedTemplateTweak; Browsing; Tag Cloud

Plugin Tiddlers
* [[Monkey-Patch Plugin]]
* [[Backstage Plugin]]
* [[Macro Plugin]]
* [[Configuration Plugin]]
* [[Library Plugin]] e.g. underscore.js.meta

Shadow Override Tiddlers
* [[StyleSheet Shadows]] StyleSheet* (but only override StyleSheet)
* [[DefaultTiddlers Shadow]]
* [[Tiddler UI Shadows]] EditTemplate, ViewTemplate
* [[Fixture Shadows]] PageTemplate, MainMenu, OptionsPanel,
* [[Markup Shadows]]

Coding Idioms
* [[jQuery Closure]]
Defines the default [[template]] used to render the tiddler in edit mode. In a [[vanilla]] TiddlyWiki, this is the view you see when you click to edit a tiddler.

Link EditTemplate| <<slider chkEditTemplate EditTemplate 'view EditTemplate tiddler'>>
Includes a site title, typically the name of the site, for the TiddlyWiki. This is used as the HTML document's title (so it typically appears in the browser window and is used in bookmarks), and is also included in the [[vanilla]] [[PageTemplate]] such that the title appears on the top of the page, with a gradient background.
todo
Contains controls allowing the user to update several often-used options (~AutoSave, ~RegExpSeaerch, ~CaseSensitiveSearch, and ~EnableOptions), along with a link to [[AdvancedOptions]].

In [[vanilla]] TiddlyWiki, this appears in the middle of the right sidebar, by virtue of the fact it's included by the [[SideBarOptions shadow]], which is itself included by the [[PageTemplate shadow]]. Note the [[SideBarOptions shadow]] includes [[OptionsPanel shadow]] as a slider element, i.e. it can be hidden and shown.
/***
|''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);
//}}}
The contents of this tiddler are included at the end of the head section in the TiddlyWiki HTML, i.e. just before the <head/> tag. See MarkupShadow for more info.
This is similar to the [[tiddler macro]], in that it embeds the entire text of another tiddler. The difference is that the slider control acts as a toggle device, allowing the user to show and hide the contents.

!Usage
<<slider option tiddler label tooltip>>

|option|ID of option to save the state of the slider as. Setting this to something unique will ensure the slider will be in the same state the next time the user views this TiddlyWiki.|
|tiddler|Name of the tiddler whose text will be embedded here.|
|label|The text of the slider, which is what the user will be clicking on to toggle the content on and off.|
|tooltip|Tooltip text of the slider.|

!Example

{{{
<<slider chkHistory history "History of TiddlyWiki" "toggle visibility of TiddlyWiki History">>
}}}

will create a slider to toggle on and off the contents of the "history" tiddler:

<<slider chkHistory history "History of TiddlyWiki" "toggle visibility of TiddlyWiki History">>


A newline is inserted after the macro, i.e when the slider is expanded it breaks the line:

Text before <<slider chkHistory history "History of TiddlyWiki" "togfgle visibility of TiddlyWiki History">>... and text after.
A function which may be used in the [[ViewTemplate]] or [[EditTemplate]] as a [[toolbar macro]] //editTiddler, closeTiddler, deleteTiddler, etc.// see the list of standard [[commands|Commands]].
TODO
The TiddlyWiki may optionally generate an [[RSS feed|http://en.wikipedia.org/wiki/RSS]] feed when saving under the control of the [[option]] {{{chkGenerateAnRssFeed}}}.

|<<option chkGenerateAnRssFeed>>|<<message config.optionsDesc.chkGenerateAnRssFeed>>|
In [[vanilla]] TiddlyWiki, this tiddler includes some useful macros: [[search macro]], [[closeAll macro]], [[permaview macro]], [[newTiddler macro]], [[newJournal macro]], [[saveChanges macro]], and also the [[SideBarOptions]] tiddler. It appears on the top of the right sidebar, by virtue of being included in the [[vanilla]] [[PageTemplate shadow]].