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
/*{{{*/
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]];}

#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]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.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]];}

#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 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}

.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:0em 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 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 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 0em;}
.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 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 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 0em 14em;}

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

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

.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:0em 0.25em; padding:0em 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:0px 3px 0px 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 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

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

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.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 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 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 use a logographic writing system and 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;}

.htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
#displayArea {margin: 1em 1em 0em 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<div class='header' 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' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></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>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></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'></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>>
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
8/11/07 - We are not doing peer-to-peer file sharing

Problem: what can we do without using the Internet? Can we do peer-to-peer or base a server on the W-LAN?

6/11/07 - spoke to Andrew Back
Talked about adding zero-conf server to W-LAN, and also getting static IP from organisers to accommodate PC users without zero-conf. We'd want a web server, a database server running ccTiddly and a backup on the Internet (which can be a client backup too, should the server go down).
<<options>>
| ''Spike'' | ''Phase'' | ''Gut feeling'' | ''Status'' |
| [[Pre-population - decoupling agenda from empty TW]] | 1 | OPML? | 9/11/07 - working solution |
| [[Current session - best way]] | 1 | simple compare of all session times to now() - is there a better way? | 8/11/07 - working solution with caveat |
| [[Browser detection]] | 1 | config.browser.is____ set during load | 8/11/07 - confidence |
| [[How to write shadow tiddlers]] | 1 | extend config.shadows | 9/11/07 - solved |
| [[Naming of tiddlers]] | 2 | hidden title/consistent title | 9/11/07 - solved |
| [[Uniqueness of usernames]] | 2 | unique usernames served back from server and flag to user - but what if network is not up when you put your username in? | 14/11/07 - decision made to use php script on server to create user accounts on the fly |
| [[Network connection detection]] | 2 | Can we detect presence of network? Can we recover mid-transaction from network dropout? | ? |
| [[Ability of browser to get under the skin of network file sharing]] | 2 | Web server running on W-LAN to avoid this; or mac web sharing exposing URL - this has scaling issues | 9/11/07 - solved |
| [[TiddlyBloat]] | 2 | When auto-subscribing, what does this mean for size of a TiddlyWiki? If we don't auto-subscribe, needs a user story around subscribing to people | ? |
| [[Bloating the airwaves]] | 2 | break up feeds into smaller sections | 12/11/07 - provisional solution in dev |
| [[Pushing files to server]] | 2 | WebDAV | 14/11/07 - confident |
| [[Upgrading]] | 2 | Separate admin feed | 12/11/07 - provisional solution prototyped; Q still over how to upgrade core |
| [[Queue]] | 3 | Flag tiddlers for upload by tag | 14/11/07 - prototype built |
Problem is the traffic associated with sending and downloading feeds of everything that is going on
! Sending
Put by tiddler
! Downloading
Break up full feed into feed-by-session (the client needs to know where to look for these, so base the feed name on the session title?)
~RippleRap includes a plugin which allows you to compose a blog or microblog posting off-line, and publish it when you have a web connection. You can either publish your conference notes to your blog (by clicking on the 'post to blog' link at the bottom of your notes), or create a fresh blog posting below and publish that instead.

For this to work you'll first need to enter the credentials for your blogging services in this ~TiddleLeWeb, by filling in the relevant forms. Go to 
[[configure blogging|Configure blogging]] to get this set up.

Don't forget to blog about ~RippleRap! Our URL is http://www.RippleRap.com/ (please use the tags RippleRap, Osmosoft or TiddlyWiki)

Heading: (free text)
Post: (free text)
Submit: (button)

Click on this link to find out [[how blog posting from TiddlyWiki works|How blog posting from TiddlyWiki works]].
''Getting started''

~RippleRap is based on TiddlyWiki, which is a wiki packaged into a single html file. You can use this file from your USB stick if you like, but we recommend you move the file to your computer to avoid damaging the USB key. Once you've done that, and opened that version, to start writing conference notes click on an item in the conference agenda. Click 'done' when you're finished, which will save your file.

Important: Because TiddlyWiki is browser based, there are a few browser issues which can stop it working. If you want to save your work, make sure you click on "save changes" on the right hand side, rather than selecting "Save As" from the browser file menu. And if you're using Safari or Opera you'll need to do [[a little reconfiguration|Safari and Opera configuration]] for ~RippleRap to work (you might find it's easier just using Firefox).
config.browser is an array with a lot of booleans inside of the form isBrowser or isOS.
| ''Date'' | ''Phase'' | ''Description'' | ''Status'' |
| 19/11/07 | 1 | agendaMenu not re-painted on reload after save | 19/11/07 - fixed |
| 9/11/07 | 1 | agendaMenu not sorted by time | 9/11/07 - fixed |
| 9/11/07 | 1 | need to accommodate HTML structure provided by PhilH for agendaItem | 14/11/07 - fixed; 9/11/07 - PhilH working on this |
| 13/11/07 | 2 | changing polling checkbox doesn't have an effect once it's started; also, I think checking the box doesn't have an effect once the first refresh period has passed | 14/11/07 - fixed |
| 13/11/07 | 1 | current session detection needs to check date as well as time | turns out it's not a bug |
| 13/11/07 | 2/3 | MainMenu doesn't refresh currentSession and showQueue macros - showQueue needs refreshing on saveTiddler and currentSession probably needs refreshing on a Timer? | 13/11/07 - emailed MartinBudden and PhilHawksworth for advice |
| 13/11/07 | 2 | webDAV plugin doesn't handle errors related to directories not being present - complication if there is a file with the same name as the directory you want to reference (that isn't there) | 15/11/07 - apparently it is a "feature" of WebDAV - handle by making sure the user shelves are there, and handle error if not; 14/11/07 - flagged to Saq |
CamelCase describes a word containing an upper case letter. The first word in this paragraph is written in camel case. If you write a word in camel case in a TiddlyWiki, it creates a link. Click on the link, and you'll find an empty tiddler ready to populate with content. It's a quick way of writing linked content. The other way of creating links is by using [[Double square brackets]].
To start taking notes, click on a speaker name. 

To subscribe to the notes that other people are writing on a particular session, check the relevant 'Subscribe' checkbox. When you'd like to read the notes after other people have published them, come back to this page and click on the speaker's names, and their notes will appear there.

|''Speaker''|''Topic''|''Subscribe to notes''|
|[[Loic Le Meur]]|Welcome to the Evolution/Revolution|[img[http://www.oracle.com/technology/tech/blaf/specs/icons/application_specific/treeicons/tree_checkbox.gif]]|
|[[Evan Williams]]|Persistent communication and its impact on being social:|[img[http://www.oracle.com/technology/tech/blaf/specs/icons/application_specific/treeicons/tree_checkbox.gif]]|
Service: (blogger / wordpress / other)
Username: (free text)
Password: (free text, masked)
Anything else?
~TiddleLeWeb works with the following microblogging services. Click on the links to configure each one.

[[Configure for Twitter]]
[[Configure for Jaiku]]
[[Configure for Pownce]]
[[Configure for Facebook]]
!!Note all content has now been uploaded to subversion - no further updates or edits here please!

''Primary Nav''
[[Original Welcome|Bonjour!!]]
[[Welcome for Firefox users]]
[[Welcome for Opera or Safari users]]
[[Welcome for Internet Explorer users]]
[[Welcome for Camino users]]
[[Share notes]]
[[Mojo]] (need to tailor the end of this, to point at the code)
[[Help]]
[[FAQs]]

''Links to deeper content''
[[TiddlyWiki]]
[[REST]]
[[Safari and Opera configuration]]
[[CamelCase]]
[[Double square brackets]]
[[Formatting TiddlyWikis]]
[[How sharing works]]
[[TiddlySaver]]

''Phil's checklist''
Review the search functionality
Will non-French mobiles be charged because they're being called by a non-French service? Update [[Mojo]].
Need to update [[How sharing works]]
8/11/07 - The unsolved issue is that the agenda items need a timezone attached, otherwise the relative time can't be fixed
[[Development progress]]
[[The ingredients]]
9/11/07 - after code review with Phil Hawksworth and Martin Budden, changed approach:
* Not using shadows tiddlers for agenda items, having separate ordinary tiddlers instead
** These are identified with the tag "session"
* A session tiddler would be composed of:
** parent tiddler, which is the person's notes
** blurb tiddler, which are the tiddlers referred to above as agenda items
** shared tiddlers from other people
* The parent tiddler would have a custom viewTemplate to add in the other tiddlers around it using the TaggedTemplateTweak
* The agendaMenu is built from the agenda item tiddlers
* Question of having an agenda object is postponed until it becomes apparent whether we need one

----
//Previous approach//
Standard TW plus:
!Custom theme
Phil Hawksworth building this after widget Hothouse (6th, 7th, 8th Nov)
!Pre-population of agenda
The flow goes as follows:
* Agenda plugin loads, which runs {{{Agenda.init()}}}:
** checks isCurrent flag to see if agenda is up to date; if not,
** converts Agenda object to new shadow tiddlers
** sets the params array for the tabs macro in the agendaMenu
** initializes the selected tab option for the agendaMenu
!Agenda Menu
The agendaMenu div is created in the PageTemplate. This runs the {{{agendaMenu}}} macro, which calls the {{{tabs}}} macro with the params array set in init. The tiddlers populating the tabs each run the {{{agendaMenuByDay}}} macro, with a single paramter specifying which day to display the agenda items for
!"now" button to take you to current session
The currentSessionButton is placed in the MainMenu and collects an array of the sessions that have started but not finished.
* ''This assumes that the agenda lists session times in GMT; if they are not, the system will get the question of which sessions are on now wrong''
* If there are no sessions now, a message to that effect is displayed;
* If there is one session on, a message linking to that session is provided;
* If there are many sessions on, a drop-down list is provided with a message displayed initially
!hints for solving common browser-related problems, based on detecting browser at load time
Sharing of notes

!uniqueness of userID's
14/11/07 - we have gone with creating user accounts on the fly. See [[Uniqueness of usernames]] for more information.
----
This is going to be looked at as part of dealing with the server-side work.
The two prevailing sides of the argument are as follows:
* pre-population of the userID's and passwords by emailing out details in advance
* on-the-fly creation of userID's, directories and passwords as people start to use TiddleLeWeb
The things to consider are:
* should we try and make sure that JoeBloggs can't sign up as RobertScoble?
* what's the net benefit to swapping a coding problem (dynamically generated ID's) for a people problem (getting people to log in with the right ID and password)
* WebDAV doesn't support creating user permissions on-the-fly (we could batch it)
See [[Uniqueness of usernames]]
!tiddler uniqueness
9/11/07 - MartinBudden created plugins to structure view of a tiddler in to three sections:
* the annotations for the session (which has the session title as the tiddler title)
* your notes (tiddler title is the sessions title appended with "fromUserName")
* other people's notes (title title is as above)
!posting to server
14/11/07 - added support for pushing files to the server in the Poller
13/11/07 - using WebDAV (see [[Pushing files to server]]):
* when you hit "done" after editing a tiddler, add the tiddler to the [[Queue]] (stub pending DevPhase3) - override autosave to add extra function?
* Poller (see next item) checks the queue during its heartbeat and puts the items; if it does it successfully, it clears the item from the queue
We could also trigger a post as soon as you have put a file into the queue? Yes...
!retrieving from server (inc. polling)
14/11/07 - need to process feeds after download and create tiddlers that can be consumed by AgendaMenu
12/11/07 - created Poller, Timer and an example macro called testPoll. Poller chooses the right feeds by the principle that we always check the admin feed, the feed for the current session (assumes one feed per session) and one other session chosen by cycling through the other feeds.
!AgendaMenu enhancements
14/11/07 - need to look for other people's notes and display them in the menu
!Saving tiddlers
See [[Queue]]
13/11/07 - overridden saveTiddler to add "inqueue" field to tiddler before saving; created showQueue macro to show either a note about an empty queue, or a button to show a popup of the queue if it is not empty. Bug tracked about needing to get the MainMenu to refresh when tiddlers are saved, so the showQueue macro re-runs.
| ''Phase'' | ''User stories satisfied'' | ''Components'' |
| [[1|DevPhase1]] | [[Write notes]], [[Save]] | Themed TiddlyWiki, TaggedTemplateTweak, agendaMenu, currentSession finder, builder for session tiddlers |
Pre-populated, standalone TW, for conference note-taking
* empty for use elsewhere
* agenda as a separate object imported to populate agenda and create shadow tiddlers
----
| ''Phase'' | ''User stories satisfied'' | ''Components'' |
| [[2|DevPhase2]] | [[Publish]], [[Read other people's notes]] | Poller, Timer, view structure for a session tiddler, + ... |
Sharing of notes
* userID's
* tiddler uniqueness
* posting to server - ccTiddly in the backend
* retrieving from server (inc. polling)
----
| ''Phase'' | ''User stories satisfied'' | ''Components'' |
| [[3|DevPhase3]] | //not created yet// | ? |
Queueing system for flakey wi-fi
----
| 4,5 | [[Write a blog post]], [[Micro-blog]] | //we don't know yet// |
Post to blog
Post to micro-blog
22/11/07 - [[Hot House Hacks]] - a list of things that need reversing or changing after the UC Hot House

16/11/07 - PhilH and JonL created this to keep track of development stages and provide feedback for PhilW.

For design items, progress is Pending -> In progress -> Design done -> Turned into code
For code items, progress is Pending -> In progress -> Untested -> In testing -> Tested

Don't forget the [[Bug tracker]]


! To support the sharing of notes
!!! (see DevPhase3, DevPhase2 and DevPhase1)
|''Item'' | ''Feature'' | ''Status'' | ''Developer'' |
|[[Design logo for RippleRap]] | Brand | In progress | PhilH |
|[[Send logo to USB manufacturer]] | Brand | Pending | PhilH |
|[[Design colour palette]] | Brand | Pending | PhilH |
|[[Design and build RippleRap.com]] | Product website | Pending | PhilH |
|[[Design UI for start-up wizard]] | Start-up wizard | Pending | PhilH |
|[[Start-up wizard]] | Start-up wizard | Pending Martin's return w/c 19/11 | MartinBudden |
|[[Design UI for user creation]] | User creation | In progress | PhilH |
|[[Build server-side component for user creation]] | User creation | Untested | PaulD |
|[[Build user creation interface]] | User creation | Pending | PhilH |
|[[Creating user shelves]] | User creation | Pending | AndrewBack |
|[[Designing UI for session notes]] | Reading notes | Design done | PhilH |
|[[Build view for session, your notes and other people's notes]] | Reading notes | In progress | PhilH |
|[[Add support for a main session feed as well as the admin feed]] | Sharing notes | Tested | JonL |
|[[Design UI for sharing notes]] | Sharing notes | Design done | PhilH |
|[[Change sharing mark on tiddler to be a tag not an extended field]] | Sharing notes | Tested | JonL |
|[[Make publishing feature sensitive to whether notes are shared or not]] | Sharing notes | Tested | JonL |
|[[Change Collection to look for "inCollection" tag not extended field]] | Publishing notes | Tested | JonL |
|[[Put item in queue when sharing box is ticked if it is changed]] | Publishing notes | Pending | PhilH/JonL/MartinBudden |
|[[Trigger post on tiddler save]] (outside of heartbeat) | Publishing notes | Pending | JonL |
|[[Push tiddlers into queue on save]] | Publishing notes | Tested | JonL |
|[[Handling post error if user shelf not there]] | Publishing notes | Pending | JonL |
|[[Support usernames and passwords in post]] | Publishing notes | Pending | JonL / PhilH |
|[[Posting queue when network returns]] | Publishing notes | Tested | JonL |
|[[Create per-session rss feeds from per-user rss feeds]] | Server-side | Pending | PaulD |
|[[Heartbeat triggering polling for updates and checking queue]] | Heartbeat | Tested | JonL |
|[[Round-robin feed selection]] | Getting feeds | Untested | JonL |
|[[Processing Agenda updates after download]] | Getting feeds | Pending | JonL |
|[[Processing administrative updates after download]] | Getting feeds | Pending | JonL / PhilH |
|[[Process notes after download]] | Getting feeds | Tested | JonL / PhilH |
|[[Design UI for AgendaMenu]] | Agenda | Turned into code | PhilH |
|[[Enhancing AgendaMenu to take into account other people's notes]] | Agenda | Tested | JonL / PhilH |
|[[Build Agenda from session tiddlers]] | Agenda | Tested | JonL / PhilH |
|[[Highlight current session in Agenda]] | Agenda | Pending | PhilH |
|[[Jump to current session(s) button]] | Agenda | Tested | JonL |
|[[Create session tiddlers for LeWeb]] | Agenda | Pending | PhilW |
|[[Design UI for customer support]] | Support | Design done | PhilH |
|[[Build mojo plugin for customer click-to-call support]] | Support | In progress | PaulD |
|[[Standardise plugin naming]] | Documentation | Done | JonL |
|[[Standard TW.org plugin documentation in plugins]] | Documentation | Done | JonL |
|[[Extra background information and re-use guidelines in plugins]] | Documentation | In progress | JonL |

! Blogging and micro-blogging
|''Item'' | ''Feature'' | ''Status'' | ''Developer'' |
|[[Design UI for blogging feature]] | Blogging | Pending | PhilH |
|[[Build adaptors for different blog API's]] | Blogging | In progress | MartinBudden / CraigCook / PhilH |
|[[Build blogging interface]] | Blogging | Pending | PhilH / MartinBudden |
|[[Design UI for micro-blogging feature]] | Micro-blogging | Pending | PhilH |
|[[Build adaptors for different micro-blog API's]] | Micro-blogging | Pending | MartinBudden / PhilH |
|[[Build micro-blogging interface]] | Micro-blogging | Pending | PhilH / MartinBudden |
If you write words or sentences in TiddlyWiki that are surrounded by [[Double square brackets]], TiddlyWiki turns it into a link. If you double click this paragraph, you'll see how this has worked.

Once you've created the link, and then clicked 'done' to close the tiddler, you can click on the link, and you'll find an empty tiddler ready to populate with content. It's a quick way of writing linked content. The other way of creating links is by using CamelCase.
''Who created ~RippleRap?''

A company called [[Osmosoft|http://www.osmosoft.com]] created ~RippleRap. Osmosoft is a small open source innovation company owned by [[BT|http://www.bt.com]].

''What's the relationship between BT and Osmosoft?''

If you're attending the conference, you might have seen that BT and Osmosoft are sharing a stand. We're very friendly, so come and say hi! Osmosoft was bought by BT in May 2007, and our remit is to support BT in understanding and adopting open source solutions in a sensible, responsible fashion. BT decided that the best way to go about doing this was to hire people who already had experience of running a successful open source project, and they therefore hired Jeremy Ruston (through the acquisition of his company, Osmosoft) because of his experience creating and running the open source ~TiddlyWiki project.

''What's ~RippleRap based on?''

~RippleRap is based on the popular open source product, TiddlyWiki. ~TiddlyWiki is a wiki packaged within a single html file, complete with all the content, the editing and saving functionality, search and tagging capabilities and much more. It can run locally from your hard drive (so it's great for taking notes or organising personal information) or on a server. It's very extensible; there are over 400 plugins developed by the ~TiddlyWiki community. Several new ~TiddlyWiki plugins have been developed and combined to create ~RippleRap.

~TiddlyWiki is a very well established and stable piece of software. However the new code that was created to support the development of ~RippleRap is relatively new and untested. It is released under a BSD licence, which means we cannot provide the software with any warranties. The full text of the BSD licence can be found on the [[Open Source Initiative web site|http://www.opensource.org/licenses/bsd-license.php]].

''How does ~RippleRap work?''

*The product at the heart of ~RippleRap is ~TiddlyWiki. This product includes all the functionality required to create, edit and save notes locally. ~TiddlyWiki can run on a server, but ~RippleRap isn't intended to be used in this way at Le Web.
*The sharing of notes with other delegates is done via RSS. When you've [[authorised sharing|Share notes]], ~TiddlyWiki creates an RSS feed that sends your notes to our server. The notes are combined with everyone else's notes on the server, and the aggregated notes are re-published as an RSS feed for your local copy of ~RippleRap. Once they're downloaded, they're stored locally and can be searched within your copy of ~RippleRap.
*The 'click to call' functionality is provided by [[BT's 21C SDK|http://sdk.bt.com]]. As it happens, ~TiddlyWiki is a great platform for building custom applications for this SDK. 

''Why are you doing this?''

BT recognises the importance of being a good citizen in the open source arena, and wants to play their part in sustaining and growing the ~TiddlyWiki community as a whole. The more people who take an interest in ~TiddlyWiki, the better it is for everyone involved, which is why the product is being showcased by BT at Le Web.

We'd also like to use ~RippleRap to demonstrate the services being provided by the BT 21C SDK. It so happens that ~TiddlyWiki is a great platform for building custom applications for this SDK. 

All the rights to the ~TiddlyWiki code have been passed to a non-for-profit foundation called [[UnaMesa|http://www.uamesa.org]], these rights are not owned by BT.

''Do you plan to do something similar at future conferences?''

Our intention is to use ~RippleRap as a vehicle for meeting the above goals; if it is successful at Le Web we may do something similar at other conferences we attend. Hopefully we'll get some useful feedback and possibly code contributions that improve the product. The code and process are all open source anyway; anyone can take the product and improve it, and use it at future conferences if they wish.

''Can we learn more?''

More information is available on the Osmosoft website at [[http://www.osmosoft.com|http://www.osmosoft.com]] and the product page at [[http://www.ripplerap.com|http://www.ripplerap.com]].

And if you have any more questions while you're at the conference, you can call us using the [[SDK tool|Mojo]] embedded into ~RippleRap, which will set up a free call with an Osmosoftonian. Or just drop into the stall and we'll help you out!
TiddlyWiki supports all kinds of formatting options:
*You can create ''Bold'' text by enclosing it in pairs of single quotes:
{{{
''bold text''
}}}

*You can create ==Strikethrough== text by enclosing it in pairs of equal signs:
{{{
==strikethrough text==
}}}

*You can __Underline__ text by enclosing it in pairs of underscores:
{{{
__underlined text__
}}}

*You can create //Italic// text by enclosing it in pairs of forward slashes:
{{{
//italic text//
}}}

*You can create ^^superscript^^ text by enclosing it in pairs of carets:
{{{
^^superscript text^^
}}}

*You can create ~~subscript~~ text by enclosing it in pairs of tildes:
{{{
~~subscript text~~
}}}

*You can @@highlight text@@ by enclosing it in pairs of at-signs.
{{{
@@highlighted text@@
}}}

*You can also change many other CSS attributes by adding arguments to the highlight command. For example, you can change the text color to @@color:red;red@@ or give it a background-color of @@background-color:#0000FF;color:white;blue@@.
{{{
@@CSS attributes separated by semicolons;text@@
}}}

You can find out more about CSS from the excellent [[w3schools tutorial|http://w3schools.com/css/default.asp]].

*Finally, you can add new CSS classes to the Tiddlywiki so that you can style a number of items with the same CSS formatting. Simply add the new class to the StyleSheet [[ShadowTiddler|ShadowTiddlers]], such as:
{{{
.moveover{
margin-left:120px;
}
}}}
Then, when you want to use that CSS class, use the following formatting:
{{{
{{classname{text to be formatted}}}
}}}
{{moveover{So, for example, this paragraph has been formatted using the moveover CSS class.}}}
We have a few help options available to you:
*Come and visit the BT / Osmosoft stall at Le Web - we'll be happy to help.
*During the conference, we offer a [[click to call|Mojo]] feature - just enter your number, and we'll call you straight back free of charge!
*We've tried to anticipate the main problems people will have; see if yours is addressed below.

!!Common problems

''I'm having trouble saving!''

~TiddlyWiki has a few known idiosyncracies, many related to saving for the first time. The top tips are:
*Always make sure you click on the save button
*Do not try to use the File/Save command in your browser
*When saving for the first time, you may receive a warning saying that ~TiddlyWiki is trying to access your file system. This is necessary in order for the browser to accept the 'save' request.
*If you wish to rename the file, save your changes first, then close the file, rename the file (but keep the .HTML extension) and reopen the file
*We suggest you create a folder called backup in the same directory as your file, and then enable the backup functionality in the [[Advanced Options]].
''I'm still having problems''

Certain browsers misbehave when running ~TiddlyWiki files. You can find a list of them (including fixes) on the [[TiddlyWiki website|http://tiddlywiki.com/#SaveChanges]]. Unfortunate these problems cannot be fixed by changing ~TiddlyWiki, but they can often be overcome with some simple browser configuration. ~TiddlyWiki generally works best on Firefox.

If you're still having problems, drop by our stall at Le Web and we'll help get you sorted.

''Note sharing isn't working''

Have you checked the box that enables sharing on the [[Share notes]] section? This needs to be checked. Notes will be pulled down automatically after that, and this process can take a few minutes depending on the content.

Alternatively, it might be that the conference wi-fi is down. 

If you've checked the box, and you're sure the conference wi-fi is working, please come and visit us at the stall and we'll help get things moving for you.

''What happens if the conference wi-fi is down?''

If the conference wi-fi is down, the functionality that will still work is the ability to take notes and save these to your hard drive. When the connection comes back up, notes will be shared automatically (assuming you've enabled this functionality).

''How can I format my text?''

~RippleRap uses TiddlyWiki, which provides a [[simple convention for formatting|Formatting TiddlyWikis]].
An explanation of how blog posting from ~TiddlyWiki works appears here, together with links to the relevant code.
Jon's notes explaining how sharing works appears here, together with links to the relevant code.
9/11/07 - we've turned away from needing this now
7/11/07 - add to config.shadowTiddlers with a title and some text
9/11/07 - Si says why not have pictures for people too?
----
6/11/07 - From PhilW's transmission of Jeremy's feedback
#Security
** Permissions - what is the consequence for someone's computer of allowing TW access to the filesystem in a conference environment?
** What's the consequence of putting e.g. blog credentials into a tiddler and transmitting across the web?
** We should surface all this in TiddleLeWeb so that people can read about it
#Upgrading
** Have a generic upgrade procedure (we'd already considered how to implement an agenda upgrade)
#Graceful way to handle browser limitations when first opened
** Handle whether access is over file:// or http://
** Direct traffic to FireFox
#We should all get a knowledge of the Top 10 problems people have with TW
#"Setting up your own post-box"
** What can we offer when people are connected over computer-to-computer networks?
----
6/11/07 - Uber-vision - it's all about the total experience
* Stands
* Sticks
* TiddleLeWeb
* Website
** Full archive of notes
** Testimonies
** etc.
----
6/11/07 - need to create user stories for:
* search
* help
* troubleshooter
* create new session
* update agenda from central server - automated?
* SHARING YOUR NOTES
* enqueue and repeated publishing attempts
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
 major: 1, minor: 1, revision: 0, 
 date: new Date("mar 17, 2007"), 
 source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};

if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};

bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
 if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){ 
  url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
 }
 return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
[[The ingredients]]
[[Development progress]]
| ''Step'' | ''Problems'' |
| Open up micro-blogging section | Can't find it |
| Configure your micro-blogs | Don't have mine |
| | Don't have username and password |
| Write shout | Section closes mid-way through writing |
| Post shout | Network connection not there |
| | Network connection drops out mid-post |
Do you use microblogging tools, such as Twitter, Pownce or Jaiku? ~TiddleLeWeb includes a plugin which helps you to publish your notes to your microblogging accounts at once.

For this to work you'll first need to enter the credentials for your microblogging services in this ~TiddleLeWeb, by filling in the relevant forms. Go to 
[[configure microblogging|Configure microblogging]] to get this set up.

The standard convention for blogging from conferences is to precede microblogging messages with '#' followed by the conference name. If you'd like to precede your messages with this convention, you can check the box below.

Don't forget to twitter about ~TiddleLeWeb! Our URL is http://www.tiddleleweb.com/

Select microblogging service: Checkboxes for Twitter, Pownce, Jaiku, 
Precede message with "#LeWeb": <<option chkDummy>>
Message: (free text)
Number of characters (note each service has it's own limit. Twitter is limited to 140 characters)
Publish post: (button)

Click on this link if you'd like to learn more about [[how posting to Twitter from TiddlyWiki works]].
Mojo is a Web friendly ([[REST|http://en.wikipedia.org/wiki/Representational_State_Transfer]]) exposure of [[BT's Web21C SDK|http://web21c.bt.com]]. You can use this to initiate telephone calls and send SMS messages from Widgets, Gadgets, Web mashups, etc! Sign up for an account at [[http://mojo.bt.com|http://mojo.bt.com]], or come over to the stall for a demo in person.

We've created a simple click-to-call functionality into [[RippleRap|Bonjour!!]] using the [[Mojo API|http://mojo.bt.com/howtos]], so you can see it in action. Enter your phone number in the box below, click 'enter' and, if it's not engaged, the [[Bat Phone|http://en.wikipedia.org/wiki/Bat_phone]] on our stall at Le Web will ring. When we pick up the phone, the call will then be connected with your phone by the ~Web21C SDK. (BT will not charge you for this incoming call, but your mobile phone operator might, especially if you are roaming).

|Your mobile number in this format: +44 798...|<<option txtMojoTelno>>|

Obviously we may be busy serving customers at the time, so if it doesn't work please try later, or if you'd like to see the demo in person swing by our stall.

If you're a developer, then you'll be interested in seeing the code. One of the great aspects of TiddlyWiki is that the entire file - including content, the code which uses the SDK, and the code required for TiddlyWiki to function - can all be inspected. Have a play around and see what you think!
9/11/07 - tiddlers for a session have the session title as their name. Notes by people use the convention "SessionTitle from UserName".
/***
|''Name:''|NotesPlugin|
|''Description:''||
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#NotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0|
|''Date:''||
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
*
***/
// /%
//!BEGIN-PLUGIN-CODE

function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
	var e = document.createElement(theElement);
	if(theClass != null)
		e.className = theClass;
	if(theID != null)
		e.setAttribute("id",theID);
	if(theText != null)
		e.appendChild(document.createTextNode(theText));
	if(attribs){
		for(var n in attribs){
			e.setAttribute(n,attribs[n]);
		}
	}
	if(theParent != null)
		theParent.appendChild(e);
	return e;
}

function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
{
	var theButton = document.createElement("a");
	if(theAction) {
		theButton.onclick = theAction;
		theButton.setAttribute("href","javascript:;");
	}
	if(theTooltip)
		theButton.setAttribute("title",theTooltip);
	if(theText)
		theButton.appendChild(document.createTextNode(theText));
	if(theClass)
		theButton.className = theClass;
	else
		theButton.className = "button";
	if(theId)
		theButton.id = theId;
	if(attribs){
		for(var n in attribs){
			e.setAttribute(n,attribs[n]);
		}
	}
	if(theParent)
		theParent.appendChild(theButton);
	if(theAccessKey)
		theButton.setAttribute("accessKey",theAccessKey);
	return theButton;
}


config.macros.notes={
	
	cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
	addLabel: "add notes",
	editLabel: "edit notes",
	editTitle: "double click to edit",
	saveLabel: "save notes",
	saveTitle: "double click to save",
	cancelLabel: "cancel",
	heading: "Notes",
	suffix: "Notes"+config.options.txtUserName,
	tags: "Notes",
	
	saveNotes: function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		if (theTarget.nodeName.toLowerCase() == "textarea")
			return false;
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		story.setDirty(title,false);
		var box = document.getElementById("notesContainer"+title);
		// if 'save notes' is clicked on, notesBox is this.parentNode
		var notesBox = this.parentNode;
		if (this.getAttribute("noteCount")) {
			// if notesBox has been double-clicked, notesBox is this
			notesBox = this;
		}
		var noteCount = notesBox.getAttribute("noteCount");
		var textarea = document.getElementById("notesTextArea"+noteCount+title);
		if(textarea.getAttribute("oldText")!=textarea.value){
			var suffix = box.getAttribute("suffix");
			var t = store.getTiddler(title+"-"+suffix+noteCount);
			// this line changed to split the tags attribute
			store.saveTiddler(title+"-"+suffix+noteCount,title+"-"+suffix+noteCount,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tags").split(" "),t?t.fields:{});
		}
		story.refreshTiddler(title,1,true);
		return false;
	},
	
	editNotes: function(notesBox,box,tiddler){
		removeChildren(notesBox);
		story.setDirty(tiddler,true);
		notesBox.title = this.saveTitle;
		notesBox.ondblclick = this.saveNotes;
		// Q: this cancel button doesn't appear to work! Is this what you meant to do?
		createTiddlyButton(notesBox,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
		createTiddlyButton(notesBox,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
		wikify("!!"+box.getAttribute("heading")+"\n",notesBox);
		addClass(notesBox,"editor");
		var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
		var wrapper2 = createTiddlyElement(wrapper1,"div");
		var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+notesBox.getAttribute("noteCount")+tiddler);
		var v = store.getValue(tiddler+"-"+box.getAttribute("suffix")+notesBox.getAttribute("noteCount"),"text");
		if(!v) 
			v = "";
		e.value = v;
		e.setAttribute("oldText",v);
		var rows = 10;
		var lines = v.match(/\n/mg);
		var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
		if(lines != null && lines.length > rows)
			rows = lines.length + 5;
		rows = Math.min(rows,maxLines);
		e.setAttribute("rows",rows);
		notesBox.appendChild(wrapper1);
	},
	
	editNotesButtonOnclick: function(e){
		var title = story.findContainingTiddler(this).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		var notesBox = this.parentNode;
		config.macros.notes.editNotes(notesBox,box,title);
		return false;
	},
	
	addNotesButtonOnclick: function(e){
		var title = story.findContainingTiddler(this).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		var oldNoteCount = box.getAttribute("notesCount");
		var notesBox = createTiddlyElement(box,"div",null,"TiddlerNotes",null,{noteCount:oldNoteCount++});
		notesBox.ondblclick = config.macros.notes.ondblclick;
		removeNode(this);
		config.macros.notes.editNotes(notesBox,box,title);
		return false;
	},
	
	ondblclick : function(ev){
		e = ev? ev : window.event;
		var theTarget = resolveTarget(e);
		var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
		var box = document.getElementById("notesContainer"+title);
		var notesBox = this;
		config.macros.notes.editNotes(notesBox,box,title);
		e.cancelBubble = true;
		if(e.stopPropagation) e.stopPropagation();
		return false;
	},
	
	handler : function(place,macroName,params,wikifier,paramString,tiddler){
		
		params = paramString.parseParams("anon",null,true,false,false);
		var heading = getParam(params,"heading",this.heading);
		// tags can be a space-separated string of tags
		// this parameter allows you to specify an identiying tag for the note
		// then we inherit the parent's tags
		// when we create the Notes box, we use tags as its tags attribute
		var tags_string = getParam(params,"tags",this.tags);
		var tags = tags_string.split(" ");
		for (var i=0;i<tiddler.tags.length;i++) {
			if (!tags.contains(tiddler.tags[i])) {
				tags_string += " " + tiddler.tags[i].toString();
			}
		}
		var suffix = getParam(params,"suffix",this.suffix);
		// Get the notes tiddlers for this tiddler, count them, make the count an attribute on the box
		var notes_tiddlers = store.getTaggedTiddlers("notes");
		var notes = [];
		var notesCount = 0;
		for (var i=0;i<notes_tiddlers.length;i++) {
			if (notes_tiddlers[i].title != tiddler.title && notes_tiddlers[i].title.indexOf(tiddler.title) != -1) {
				notes.push(notes_tiddlers[i]);
				notesCount++;
			}
		}
		// sort the notes by modified date to get the most recent in notes[0]
		notes.sort(function(a,b){
			return a.modified > b.modified ? -1 : (a.modified == b.modified ? 0 : 1);
		});
		var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tags:tags_string,suffix:suffix,notesCount:notesCount});
		// if there aren't any notes, show "No notes"
		// if there are notes, show "Notes (latest by xxx)"
		// if you added the notes, show "Notes (latest by you)"
		// REMOVED: var notes_tiddler = store.fetchTiddler(tiddler.title+"-"+suffix);
		var heading_extension = "";
		if (notes[0] && notes[0].modifier) {
			if (notes[0].modifier != config.options.txtUserName) {
				heading_extension = " (latest by " + notes[0].modifier + ")";
			} else {
				heading_extension = " (latest by you)";
			}
			wikify("!!"+heading+heading_extension+"\n",box);
		} else {
			wikify("//No notes//\n",box);
		}
		box.title=this.editTitle;
		// These lines unnecessary with createTiddlyElement that takes an object of attributes
		//box.setAttribute("source",tiddler.title);
		//box.setAttribute("params",paramString);
		//box.setAttribute("heading",heading);
		//box.setAttribute("tags",tags_string);
		//box.setAttribute("suffix",suffix);
		// REMOVED: box.ondblclick = this.ondblclick;
		for (var i=0;i<notes.length;i++) {
			var notesBox = createTiddlyElement(box,"div",null,"TiddlerNotes",null,{noteCount:i});
			notesBox.ondblclick = this.ondblclick;
			wikify("<<tiddler [["+notes[i].title+"]]>>\n",notesBox);
			createTiddlyElement(notesBox,"span",null,"subtitle","at "+notes[i].modified+" by "+notes[i].modifier);
			createTiddlyButton(notesBox,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
		}
		// add 'add notes' button
		createTiddlyButton(box,this.addLabel,this.addLabel,this.addNotesButtonOnclick,"editNotesButton");	
	}		
};

/* CHANGE: 09/10/07 - not sure why this is needed
Story.prototype.old_notes_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused){
	if(story.isDirty(title)) {
		if(!confirm(config.macros.notes.cancelWarning.format([title])))
			return false;
	}
	return this.old_notes_closeTiddler.apply(this,arguments);
}
*/

setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");


//sliders
//keyboard shortcuts
// ids.. 
// ids.. 


//!END-PLUGIN-CODE
// %/
9/11/07 - After code review with Martin and PhilH, changed approach. See DevPhase1 for more details.
* We deferred the decision about what the source for pre-population is going to look like until we need it for administration purposes.
* We are using tiddlers to represent sessions.
----
7/11/07 - Created an agenda object, which is then mapped onto shadow tiddlers and used to populate the agenda panel.

{{{
// the list of agenda items
Agenda.agenda = [
	{
		title:"Why Vodafone rocks my world",
		date:"Day 1",
		start:"0900",
		end:"1000",
		speaker:"Dan Appelquist",
		blurb:"//Lots of fun//.\nHere is something\nthis too"
	},
	{
		title:"Why blogging is fun",
		date:"Day 1",
		start:"1000",
		end:"1100",
		speaker:"Robert Scoble",
		blurb:"Scobleizer\nWaaa!!!!"
	}
];
}}}
| ''Step'' | ''Problem'' | ''Remedy'' |
| Finish saving | Network connection not available | Enqueue item and tell user about it; when network comes back, try to publish again (new U.S.) |
| | Network connection cuts out mid-way through publish | cancel publish and proceed as above |
14/11/07 - weird things I've noticed about WebDAV:
* if you have a file "file.xml" and you try to create a directory using "MKCOL" called "file", the server thinks you're referring to file.xml and throws a "method not allowed" error
* when creating directories, you have to leave the trailing slash off the url
14/11/07 - SaqImtiaz has agreed to add username and password support into his plugin if we build the UI first
14/11/07 - SaqImtiaz has written a comprehensive WebDAV plugin, so we're going to use that: http://tiddlywiki.pastebin.com/d6f48ca47
13/11/07 - using http://garden.dachary.org for testing
13/11/07 - created testWebDAV macro and a few WebDAV utility functions
13/11/07 - discussed approach with PhilHawksworth; changed direction:
* on save, add tiddler to queue by setting field (cf. dirty tiddler)
* use the Poller's heartbeat to trigger queue to check itself (Poller is also checking the feeds)
** we get the queue to check itself so that it can be the queue that takes items off the queue after successfully pushing them to the server - this keeps the different objects more separate and so more re-usable
* Poller calls WebDAV PUT (or POST? or something else?) to push items up to server
* If successful, clear the item from the queue

12/11/07 - re-use timer from phase 2; tag tiddlers to put them in queue; poller also does uploading by checking queue, concatenating into a string whatever is in it and PUTting - this is basically transactional - ''is that going to be a problem? what if you have a really big queue and can't get it uploaded in the short time the network is up? would it be better to do it piecemeal?''; create new instance of Poller for this upload bit?
Put simply, REST gives direct access to data and services in a way that doesn't require an additional messaging layer. This is great for our customers (and the web in general), because it gives developers the flexibility to use these services in whatever way they like. Other claimed benefits include improved response times and server scalability.

The alternative way of exposing these services is over a messaging service such as SOAP. This service is also available if needed.

For a technical description of REST, along with a list of benefits, check out the [[Wikipedia entry|http://en.wikipedia.org/wiki/Representational_State_Transfer]].
| ''Step'' | ''Problem'' | ''Remedy'' |
| Find item on agenda | Item not there | see [[1. Write notes]] |
| | Can't find item | Offer search (new U.S.) (part of [[1. Write notes]]) |
| | | Auto-create entry after receiving notes from someone else about it |
| Find person's notes you want to read | No-one there | Auto-populate list so this means no-one is sharing |
| | | Display notice telling people to encourage their friends/neighbours to share |
| | | Produce a permalink to the session for sending to others as part of encouraging them to share |
| | The person you wanted is not there | Produce permalink to send to them, similar to above |
Safari and Opera can save changes using the ~TiddlySaver Java applet.

The ~TiddlySaver Java applet allows TiddlyWiki from a {{{file://}}} URL to save changes with Safari, Opera and other browsers.

It is a small file named [["TiddlySaver.jar"|http://www.tiddlywiki.com/TiddlySaver.jar]] that must be placed in the same directory as your TiddlyWiki file. Before you can use it, you need to give it the necessary privileges by editting your {{{.java.policy}}} file.

For Windows, the file will be at {{{C:\Documents and Settings\your-user-name\.java.policy}}}. Add the following lines (substituting the directory of your TiddlyWiki file as appropriate):
{{{
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
On Mac OS X, the file is found at {{{/Users/your-user-name/.java.policy}}}:
{{{
grant codeBase "file:${user.home}/Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
It can be tricky creating files whose name starts with a period, so you can use this [[pre-built .java.policy file|.java.policy]]. The same file is suitable for Macs too, just edit it and delete the "My " bit, leaving just "Documents". Make sure you save it in the right place for each operating system!

If you have trouble setting up the permissions correctly, you can try granting broader permissions to the applet like this:

{{{
grant codeBase "file://localhost/home/users/Desktop/
TiddlySaver.jar"
 { permission java.security.AllPermission; };
}}}

Note that there is currently [[a bug|http://trac.tiddlywiki.org/ticket/172]] that prevents TiddlySaver from working if you have specified a backup directory in AdvancedOptions.
| ''Step'' | ''Problem'' | ''Remedy'' |
| Finish editing a tiddler //or// Finish collecting updates | Problem with saving | Tell user about it and try to diagnose what went wrong; suggest solutions (new U.S.) |
| | | Check browser on load and flag potential problems and solutions (new U.S.) |
| | | Link to troubleshooter (new U.S.) |
You can SaveChanges if you're using FireFox, InternetExplorer, [[Opera]], [[Camino]] or [[Safari]]
* For [[Opera]] and [[Safari]], also see the additional TiddlySaver instructions.
* if you're using InternetExplorer on Windows you might run into XP ServicePack2Problems or VistaIssues
# right click on [[this link|empty.html]] and select 'Save link as...' or 'Save target as...'
** do ''not'' try to use the File/Save command in your browser because of SaveUnpredictabilities.
** choose where to save the file, and what to call it (but keep the .HTML extension)
# open the newly downloaded file in your browser
# click the 'options' button on the right to set your username
# edit, create and delete the tiddlers you want
** you can change the SpecialTiddlers to change the SiteTitle and MainMenu etc.
# click the 'save changes' button on the right to save your changes
# TiddlyWiki will make a backup copy of the existing file, and then replace it with the new version
If you're connected to the web, you can share your notes with others and receive theirs in return, all saved to your local ~RippleRap file, and all fully searchable!

To share your notes, check the below box and complete the form. You can turn this functionality off for a specific session or set of notes if you want - just uncheck the check box that appears when you're creating a new set of notes. Your username and password will ensure that your notes are assigned to you in other people's version of ~RippleRap.

Share notes: <<option chkDummy>> 
Username:
Password:

If you'd like to draw people's attention to your blog or twitter feed, include the relevant ~URLs at the bottom of your notes. This information will then appear on other people's copy of ~RippleRap so they can follow your words of wisdom after the event!

Once you've enabled sharing, to see notes that other people have shared, click on their names under the session you're interested in. These will be downloaded automatically.

Click on [[this link to find out how sharing works|How sharing works]].
the social conferencing tool
TiddleLeWeb
h1 {font-size: 1.5em;}
div.tiddler div.title {font-size: 2em;}
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|

The core function, "story.chooseTemplateForTiddler(title,template)" is essentially a "pass-thru" that returns the same template it was given, and is provided by the core so that plugins can customize the template selection logic to select alternative templates, based on whatever programmatic criteria is appropriate.  This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.'' 
!!!!!Usage
<<<
Each alternative template is associated with a specific tiddler tag value by using that tag value as a prefix added to the standard TiddlyWiki template titles, [[ViewTemplate]] and [[EditTemplate]].

For example, any tiddlers that are tagged with ''<<tag media>>'' will look for alternative templates named [[mediaViewTemplate]] and [[mediaEditTemplate]].  Additionally, in order to find templates that have proper WikiWord tiddler titles (e.g., [[MediaViewTemplate]] and [[MediaEditTemplate]]), the plugin will also attempt to use a capitalized form of the tag value (e.g., ''Media'') as a prefix.  //This capitalization is for comparison purposes only and will not alter the actual tag values that are stored in the tiddler.//

If no matching alternative template can be found by using //any// of the tiddler's tags (either "as-is" or capitalized), the tiddler defaults to using the appropriate standard [[ViewTemplate]] or [[EditTemplate]] definition.

''To add your own custom templates:''
>First, decide upon a suitable tag keyword to uniquely identify your custom templates and create custom view and/or edit templates using that keyword as a prefix (e.g., "KeywordViewTemplate" and "KeywordEditTemplate").  Then, simply create a tiddler and tag it with your chosen keyword... that's it!  As long as the tiddler is tagged with your keyword, it will be displayed using the corresponding alternative templates.  If you remove the tag or rename/delete the alternative templates, the tiddler will revert to using the standard viewing and editing templates.
<<<
!!!!!Examples
<<<
|Sample tiddler| tag | view template | edit template |
|[[MediaSample - QuickTime]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[MediaSample - Windows]]| <<tag media>> | [[MediaViewTemplate]] | [[MediaEditTemplate]] |
|[[CDSample]]| <<tag CD>> | [[CDViewTemplate]] | [[CDEditTemplate]] |
|<<newTiddler label:"create new task..." title:SampleTask tag:task text:"Type some text and then press DONE to view the task controls">> | <<tag task>> | [[TaskViewTemplate]] | [[EditTemplate]] |

//(note: if these samples are not present in your document, please visit// http://www.TiddlyTools.com/ //to view these sample tiddlers on-line)//
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
[[TaggedTemplateTweak]]
<<<
!!!!!Revision History
<<<
''2007.06.23 [1.1.0]'' re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
''2007.06.11 [1.0.0]'' initial release
<<<
!!!!!Credits
<<<
This feature was developed by Eric L Shulman / ELS Design Studios
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 1, revision: 0, date: new Date(2007,6,18)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var template=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler to be rendered doesn't exist yet, just return core result
	var tiddler=store.getTiddler(title); if (!tiddler) return template;

	// look for template whose prefix matches a tag on this tiddler
	for (t=0; t<tiddler.tags.length; t++) {
		var tag=tiddler.tags[t];
		if (store.tiddlerExists(tag+template)) { template=tag+template; break; }
		// try capitalized tag (to match WikiWord template titles)
		var cap=tag.substr(0,1).toUpperCase()+tag.substr(1);
		if (store.tiddlerExists(cap+template)) { template=cap+template; break; }
	}

	return template;
}
//}}}
@@color(red): Update 22/11/07@@ - added [[Hot House Hacks]] to keep track of what we had to mess around with to get RippleRap to work at the UC Hot House 19th - 21st November
@@color(red): Update 16/11/07@@ - created [[Development progress]] to replace this tiddler as the progress tracker
@@color(red): Update 15/11/07@@ - decided product name is "RippleRap"
@@color(red): Update 13/11/07@@ - [[DevPhase2]] has a lot more content, [[DevPhase3]] has begun, [[Bug tracker]] has the consolidated bug list, updates to [[Architectural spikes]]
@@color(red): Update 9/11/07@@ - [[DevPhase1]] updates, [[DevPhase2]] begun, extra [[spikes|Architectural spikes]] dealt with
@@color(red): Update 7/11/07@@ - [[DevPhase1]], more user stories and pre-population architectural spike prototyped
@@color(red): Update 6/11/07@@ - prioritised user stories, added remedies and split into self-contained phases; added area for [[Important undocumented things and ideas]]
@@color(red): Project commenced on 5/11/07@@

! Designing this beast!

[[Important undocumented things and ideas]]

User-centric design
* [[User stories]]
* [[Wireframes and mockups]]
Development process
* [[Bug tracker]]
* [[Development phases]]
** DevPhase1 - standalone
** DevPhase2 - social notes
** DevPhase3 - queue
* [[Architectural spikes]]

! Sample content

All content can be found on the [[Content]] tiddler.

12/11/07 - MartinBudden: we start going slow when we get to a few hundred tiddlers
The ~TiddlySaver Java applet allows a locally saved ~TiddlyWiki to save changes on Safari, Opera and other browsers. This is slightly complicated, and you might well find it more straightforward using ~RippleRap in Firefox.

The ~TiddlySaver Java applet is a small file named [["TiddlySaver.jar"|http://www.tiddlywiki.com/TiddlySaver.jar]] that must be placed in the same directory as your TiddlyWiki file. Before you can use it, you need to give it the necessary privileges by editting your {{{.java.policy}}} file.

For Windows, the file will be at {{{C:\Documents and Settings\your-user-name\.java.policy}}}. Add the following lines (substituting the directory of your TiddlyWiki file as appropriate):
{{{
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
On Mac OS X, the file is found at {{{/Users/your-user-name/.java.policy}}}:
{{{
grant codeBase "file:${user.home}/Documents/tiddlywiki-folder/*" {
  permission java.io.FilePermission "${user.home}${/}Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
It can be tricky creating files whose name starts with a period, so you can use this [[pre-built .java.policy file|.java.policy]]. The same file is suitable for Macs too, just edit it and delete the "My " bit, leaving just "Documents". Make sure you save it in the right place for each operating system!

If you have trouble setting up the permissions correctly, you can try granting broader permissions to the applet like this:

{{{
grant codeBase "file://localhost/home/users/Desktop/
TiddlySaver.jar"
 { permission java.security.AllPermission; };
}}}

Note that there is currently [[a bug|http://trac.tiddlywiki.org/ticket/172]] that prevents TiddlySaver from working if you have specified a backup directory in AdvancedOptions.
~RippleRap is based on the hugely popular TiddlyWiki product; an entire wiki product packaged into a single html file! TiddlyWiki is free, open source, and already has a loyal community of developers and enthusiasts helping to develop it and support new users. There are over 400+ plugins which can be used to configure ~TiddlyWiki in a multitude of ways. It can be used as a task management tool, a de-centralised collaboration tool, a platform for writing and de-bugging software, simply for organising notes or in many other ways.

The entire TiddlyWiki is made up of microcontent called tiddlers, including all the content and the code required to make it function. You're reading a tiddler right now - try double clicking on this text to send it into edit mode. If you have a working knowledge of javascript or css, you can immediately get under the hood, configuring it in any way you like! If you have questions, the TiddlyWiki community is incredibly helpful - there's a [[developer's group|http://groups.google.com/group/TiddlyWikiDev]] and a [[user's group|http://groups.google.com/group/TiddlyWiki]] on Google Groups.

~RippleRap was created by [[Osmosoft|http://www.osmosoft.com]], a small company owned by British Telecom. Osmosoft is run by the original creator of TiddlyWiki, Jeremy Ruston. You can find out more by looking in our [[FAQs]], or alternatively, if you're online, here are some relevant links:

Official ~TiddlyWiki website: http://www.tiddlywiki.com
~TiddlyWiki community: http://groups.google.com/group/TiddlyWiki
~TiddlyWiki developer community: http://groups.google.com/group/TiddlyWikiDev
Osmosoft website: http://www.osmosoft.com
~RippleRap: http://www.ripplerap.com
/***
Contains the stuff you need to use Tiddlyspot
Note you must also have UploadPlugin installed
***/
//{{{

// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'tiddleleweb';

// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)

// disable autosave in d3
if (window.location.protocol != "file:")
	config.options.chkGTDLazyAutoSave = false;

// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
	SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
	SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
	OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
	DefaultTiddlers = DefaultTiddlers.replace(/^/,"WelcomeToTiddlyspot]] ");
	MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}

// create some shadow tiddler content
merge(config.shadowTiddlers,{

'WelcomeToTiddlyspot':[
 "This document is a ~TiddlyWiki from tiddlyspot.com.  A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below.  Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
 "<<tiddler TspotControls>>",
 "See also GettingStarted.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick.  You can make changes and save them locally without being connected to the Internet.  When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]].  Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help.  If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
 "",
 "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site.  Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),

'TspotControls':[
 "| tiddlyspot password:|<<option pasUploadPassword>>|",
 "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<<br>>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
 "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),

'TspotSidebar':[
 "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . .  " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),

'TspotOptions':[
 "tiddlyspot password:",
 "<<option pasUploadPassword>>",
 ""
].join("\n")

});
//}}}
14/11/07 - after much debate, we settled on the following scheme allowing users to create accounts on the fly:
* user puts in username and password
* these are POSTed to a server-side php script (14/11/07 - psd wrote this)
* the script creates and permissions the user's directory
* if the username is taken, the script can respond accordingly and we can handle this
---------------
8/11/07 - feeling is that we will pre-populate usernames
12/11/07 - this is still up for discussion and AndrewBack is leading on this
14/11/07 - on the subject of batch, on-the-fly creation of user accounts (given that WebDAV doesn't support creation of user permissions):
<<<
saqimtiaz: have a public writeable dav drive
saqimtiaz: and use that as a go between for account creation
saqimtiaz: have each account creation request post a small file there
saqimtiaz: encrypted perhaps?
saqimtiaz: something like that
JayFresh: that is interesting...
saqimtiaz: have the batch file read and delete those files
11:50
saqimtiaz: its the best option you've got I think
saqimtiaz: the issue is that people will need to provide usernames and passwords
saqimtiaz: and those cant be readable by the world
saqimtiaz: so you need some kind of encryption
JayFresh: how would you see that working?
saqimtiaz: not sure really. Nothing will be 100% secure. That is the problem
saqimtiaz: have the cron run VERY regularly will help naturally
saqimtiaz: but its not fool-proof
saqimtiaz: could you use Sha1 encryption somehow? encryption is not something im very familiar with
11:55
JayFresh: I think psd is more familiar with that
JayFresh: he tweeted about  it this morning
saqimtiaz: psd?
JayFresh: Paul Downey
saqimtiaz: ah right
saqimtiaz: the kicker is this
saqimtiaz: you'd need some kind of key for encryption
saqimtiaz: but if the key is in the TiddlyWiki code...
saqimtiaz: then its not foolproof
JayFresh: oh balls
<<<
12/11/07 - Separate admin feed, always checked during polling. Agenda content + any tiddler upgrades in there. Question still remains about how to upgrade core.
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 26/11/2007 14:53:19 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
| 28/11/2007 11:57:06 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . | ok |
| 28/11/2007 11:57:24 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . | ok |
| 28/11/2007 12:00:39 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
| 29/11/2007 17:08:28 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
| 29/11/2007 17:33:48 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
| 29/11/2007 18:31:32 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . | ok |
| 29/11/2007 19:13:44 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
| 29/11/2007 19:17:27 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
| 29/11/2007 21:25:50 | PhilWhitehouse | [[/|http://tiddleleweb.tiddlyspot.com/#Content]] | [[store.cgi|http://tiddleleweb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://tiddleleweb.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}

/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.0|
|''Date:''|May 5, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (#3125)|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 0,
	date: new Date("May 5, 2007"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0 (#3125)'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	refreshOptions: function(listWrapper) {
		var uploadOpts = [
			"txtUploadUserName",
			"pasUploadPassword",
			"txtUploadStoreUrl",
			"txtUploadDir",
			"txtUploadFilename",
			"txtUploadBackupDir",
			"chkUploadLog",
			"txtUploadLogMaxLine",
			]
		var opts = [];
		for(i=0; i<uploadOpts.length; i++) {
			var opt = {};
			opts.push()
			opt.option = "";
			n = uploadOpts[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
}

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,null,null,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		bidix.upload.httpUpload(rssUploadParams,convertUnicodeToUTF8(generateRss()),callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == httpStatus.NotFound)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


/* don't want this for tiddlyspot sites

// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");

*/


//}}}


''To-do:'' add remedial action for each problem listed in user stories for phases 4 and 5
''To-do:'' add user story for "mini-note" - new tiddlers for ad-hoc note-taking

| ''Phase'' | ''User story'' |
| 1 | [[Write notes]] |
| 1 | [[Save]] |
| 2 | [[Read other people's notes]] |
| 2,3 | [[Publish]] |
| 4/5 | [[Write a blog post]] |
| 4/5 | [[Micro-blog]] |
| 4/5 | [[Mini-notes]] |

//Key - 1,2 means 1 ''and'' 2; 1/2 means uncertain about priority//
''Introduction''

~RippleRap is a social conferencing tool for managing your conference notes. It's a single html file which can be used to organise your notes offline!

When you get online you can [[share your notes|Share notes]] with other delegates (if you want to). Especially useful to receive other people's notes when you've missed a session.

Don't forget to check out BT's SDK - ~RippleRap provides a click to call function using this SDK, exposed using [[Mojo]], which you can use to call the BT stall for free and find out more.

''Setup instructions''
#Copy the ~RippleRap file to your desktop and open it in your browser from there
#Click on a session name in the conference agenda, create some dummy notes and click 'done' when you're finished, which will save your file automatically. Close the file in your browser, open it again and check to see if your notes were saved properly.
#If they were, you're ready to go! If not, come on by the stall and we'll help you out.
Note: Don't use the browser's File > Save As... function; ~RippleRap saves and backups your changes automatically.
''Introduction''

~RippleRap is a social conferencing tool for managing your conference notes. It's a single html file which can be used to organise your notes offline!

When you get online you can [[share your notes|Share notes]] with other delegates (if you want to). Especially useful to receive other people's notes when you've missed a session.

Don't forget to check out BT's SDK - ~RippleRap provides a click to call function using this SDK, exposed using [[Mojo]], which you can use to call the BT stall for free and find out more.

''Setup instructions''
#Copy the ~RippleRap file to your desktop and open it in your browser from there
#If you see dialog boxes asking your permission for the local file operations, allow these for ~RippleRap to work properly. You can select the //Remember this decision// option to avoid seeing the dialogs in future.
#Click on a session name in the conference agenda, create some dummy notes and click 'done' when you're finished, which will save your file automatically. Close the file in your browser, open it again and check to see if your notes were saved properly.
#If they were, you're ready to go! If not, come on by the stall and we'll help you out.
Note: Don't use the browser's File > Save As... function; ~RippleRap saves and backups your changes automatically.
''Introduction''

~RippleRap is a social conferencing tool for managing your conference notes. It's a single html file which can be used to organise your notes offline!

When you get online you can [[share your notes|Share notes]] with other delegates (if you want to). Especially useful to receive other people's notes when you've missed a session.

Don't forget to check out BT's SDK - ~RippleRap provides a click to call function using this SDK, exposed using [[Mojo]], which you can use to call the BT stall for free and find out more.

''Setup instructions''
#Copy the ~RippleRap file to your desktop and open it in your browser from there
#If you see dialog boxes asking your permission for the local file operations, allow these for ~RippleRap to work properly
#Click on a session name in the conference agenda, create some dummy notes and click 'done' when you're finished, which will save your file automatically. Close the file in your browser, open it again and check to see if your notes were saved properly.
#If they were, you're ready to go! If not, come on by the stall and we'll help you out.
Note: Don't use the browser's File > Save As... function; ~RippleRap saves and backups your changes automatically.
''Introduction''

~RippleRap is a social conferencing tool for managing your conference notes. It's a single html file which can be used to organise your notes offline!

When you get online you can [[share your notes|Share notes]] with other delegates (if you want to). Especially useful to receive other people's notes when you've missed a session.

Don't forget to check out BT's SDK - ~RippleRap provides a click to call function using this SDK, exposed using [[Mojo]], which you can use to call the BT stall for free and find out more.

''Setup instructions''
Note this file has detected that you're using Opera or Safari, and that the setup instructions are much more simple if you're using Firefox.
#Copy the ~RippleRap file to your desktop and open it in your browser from there
#Install the TiddlySaver java applet.
#Click on a session name in the conference agenda, create some dummy notes and click 'done' when you're finished, which will save your file automatically. Close the file in your browser, open it again and check to see if your notes were saved properly.
#If they were, you're ready to go! If not, come on by the stall and we'll help you out.
Note: Don't use the browser's File > Save As... function; ~RippleRap saves and backups your changes automatically.
Annotated mockups have been posted on Flickr at:
|version 1 |http://www.flickr.com/photos/philhawksworth/1876301233/ |
Nice job Phil!
| ''Step'' | ''Problems'' |
| Configure your blog | Don't know how |
| | Don't have details |
| Write blog post | Close tiddler whilst writing |
| Save draft | Tiddler doesn't save |
| Publish post | Network connection not up |
| | Network connection drops out during post |
| | Haven't got username and password right |
| ''Step'' | ''Problem'' | ''Remedy'' |
| Find item on agenda | Item not there | Offer means to create new (new U.S.) |
| | | Update list from central server (new U.S.) |
| | Can't find item |  Have a link to "what's on now" in navigation (new U.S.) |
| | | Offer search (new U.S.) |
| Open relevant tiddler | Can't see tiddler | Scroll down on open |
| Start editing | Don't know how | Clear explanation on tiddler |
| | | General help option (new U.S.) |
| Finish editing | Don't know how | Clear explanation on tiddler |
| | | General help option (new U.S.) |
The details you enter here will be included in the session notes that you share with other people. This will help them to identify you and follow your words of wisdom long after Le Web has finished!

Name: 
Company:
Company URL:
Blog: 
An explanation of how tweeting from ~TiddlyWiki works appears here, together with links to the relevant code.
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></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='viewer' macro='notes tags:"notes notes"'></div>
<div class='tagClear'></div>
<!--}}}-->