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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

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

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='toolbar' role='navigation' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
Group work : 
* [[creating groups in Moodle|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bGroup%20work%20with%20Moodle%5d%5d]]
Using Forums for :
* presenting in class
* students sharing files
* apply groups
!!OUWiki
* think of a wiki as a collaborative electronic whiteboard.
* example project -- joint web page. OUWiki will do a very successful joint web site with multiple pages
* advantages using one inside Moodle 
** groups can be easily applied
** only visible to course participants and so no worries with copyright
* Disadvantages :
** not visible outside moodle even if you wanted it to be
** setting things up to upload graphic images is complicated
Comprehensive documentation :
[[Using Moodle wiki -- OU Wiki|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bUsing%20Moodle%20Wiki%5d%5d]]
Workflow for using a wiki:
[[Wiki assignment workflow|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bWiki%20Assignment%20workflow%5d%5d]]

/***
|''Name''|RefreshTiddlerCommand|
|''Version''|0.3.0|
***/
//{{{
(function($) {

var cmd = config.commands.refreshTiddler = {
	text: "refresh",
	locale: {
		refreshing: "Refreshing tiddler..."
	},
	tooltip: "refresh this tiddler to be the one on the server",
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		if(!tiddler) {
			tiddler = new Tiddler(title);
			merge(tiddler.fields, config.defaultCustomFields);
		}
		$(story.getTiddler(title)).find(".viewer").
			empty().text(cmd.locale.refreshing);
		var dirtyStatus = store.isDirty();
		story.loadMissingTiddler(title, {
			"server.workspace": tiddler.fields["server.recipe"]  ? "recipes/" + tiddler.fields["server.recipe"] :
				tiddler.fields["server.workspace"] || "bags/"+tiddler.fields["server.bag"],
			"server.host": tiddler.fields["server.host"],
			"server.type": tiddler.fields["server.type"]
		}, function() {
			store.setDirty(dirtyStatus);
		});
	}
};

})(jQuery);
//}}}
[[Things we love about moodle2 pt2 – experimenting with themes|http://blogs.sussex.ac.uk/elearningteam/2011/01/24/things-we-love-about-moodle2-pt2-experimenting-with-themes/]]
refers to [[HTML 5 boilerplate|http://html5boilerplate.com/]]. Cool!
Majorly cool theme framework like [[this one|http://blogs.sussex.ac.uk/elearningteam/files/2011/01/Picture-17.png]]<<imagebox>>
[[moodle dashboard|http://blogs.sussex.ac.uk/elearningteam/2011/10/31/moodle-dashboard/]] -- what Sussex have done is to farm out all the admin functions into a separate interface they call the dashboard. Check out the video. It's very neat!
So, Dan Graves' Jazz History course needs to track attendance for 35  participants. Initial Settings for the Attendance activity:
|!Acronym|!Participation|!Grade %|
|PA | Active| 95|
|PN | Neutral| 85|
|PU | Unsatisfactory| 75|
|A | Absent | 0|
There are 31 total slots with 3 sessions missing (2/16 mid semester break, 3/13 & 3/15 Spring Break) so a total of ''28'' sessions.
We want to total for 28 sessions of PA grade to be 100%, so each PA session would be worth 100/28 = 3.57. But the module does not allow a decimal grade per session so we multiply by 100 to get 357 per session and a total of 10,000 per semester. Moodle will do the necessary arithmetic to scale it down. So applying the same principle to the neutral and unsatisfactory grades we get PN = 85/28 * 100 = 303, and PU = 75/28 * 100 = 267.
This now gives us:
|!Acronym|!Participation|!Grade/session|!Total/28|!overall %|
|PA | Active| 357| 9996| 100 (A)|
|PN | Neutral| 303| 8484| 85 (B)|
|PU | Unsatisfactory| 267| 7476| 75 (C)|
But how to handle absences?
Making an absent grade / session = 0 is rather harsh, so I suggest making it = 100. This would mean that for three (''3'') the student would get 300/1071. So, what would she need to make this up in the remainder of the semester? With three sessions missed through absence there are 25 remaining sessions with possibilities of Active, neutral and Unsatisfactory for each of these. Here's the breakdown:
|!Participation level|!grade/session|!# remaining sessions|!Total|!Add in absences|!overall %|
|Active| 357| 25| 8925| 9225| 92 (A-)|
|Neutral| 303| 25| 7575| 7875| 78 (C+)|
|Unsatisfactory| 267| 25| 6675| 6975| 70 (C-)|
Thus someone who misses 3 classes can pull his grade up to A- ''if'' all the rest of the classes are active participation. Anything else gives a C. Quite a good incentive methinks.
With this scheme the Attendance settings will look like this:
|!Acronym|!Participation|!Grade|
|PA | Active| 357|
|PN | Neutral| 303|
|PU | Unsatisfactory| 267|
|A | Absent | 100|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#B9B9FF" offset="0"/>
   <stop id="stop2" stop-color="#E8E8FF" offset="0.66462"/>
   <stop id="stop3" stop-color="#B9B9FF" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d">
  <path id="path3288" style="stroke-dasharray:none;" d="m31.328,58.508a1.2868,1.2868,0,1,1,-1.1862,1.1643" transform="matrix(4.67791, 0, 0, 4.67791, -119.332, -222.038)" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.342033" fill="none"/>
  <path id="path4348" d="m20.433,50.322,4.3207,0-1.3291,1.3291,6.1802,6.4735-1.687,1.687-6.3268-6.3268-1.158,1.158,0-4.3207z" stroke-linecap="butt" stroke-width="0.80000001px" fill="#4d4d4d"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
A [[SiteIcon|SiteIcon tiddler]]@glossary helps provide some identity to your space.  Ideally it'd be a square and a minimum of 48*48 pixels size.  You can upload your site icon using the uploader below.

<<binaryUploadPublic title:SiteIcon>>
!!Response Rate
Kenyon's experience is that there are two major factors influencing student response rate. (Remember that these evaluations are ''not'' done in class time.)
!!!#1 Communicating importance of Course Evaluation for both the teacher and the course
Making it clear to the students in class that their evaluations matter to both the teaching faculty and to how the next year's course is taught is the biggest factor. In fact, some profs use comments from last time's evaluation to show the current class how they have changed the course to work better. Can think of evaluations as a letter to next year's students.
So //give students a sense of involvement and longer term commitment//
!!!#2. Getting students to start the process
Students who complete their first evaluation almost always go on to finish them all.
Kenyon has been getting a 95% response rate!
!!Boosting response rate -- student motivation
Carrots work better than sticks at motivating students. What Kenyon does is to grant access to end of term grades two weeks early to students who have done evaluations. But then they merely move the "official" date of grade release back two weeks! So if you don't do your evaluations you have to wait another two weeks.
Paolo Oprandi from Uni Sussex demonstrates an interesting take on Google Docs and moodle integration [[here|http://blogs.sussex.ac.uk/elearningteam/2012/03/07/google-docs-and-moodle-integration/]]. Basically, it allows for view access or collaboration as options in the same Activity. Neat, simple and powerful.
In the past there have been some notorious issues with Firefox browser on the Mac and the TinyMCE javascript editor in Moodle. Firefox 11 (on the Mac only) broke the editor and while there was a clunky workaround the problem didn't get really fixed until the new version of Firefox, v12, and a new iteration of TinyMCE.
Now a new problem with Firefox v13 on OS X (10.6.8) has unexpectedly arisen. Here's a screenshot of the editor on Earlham's production moodle site:

[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/firefox-mac_moodle_production.png]]

You can see that the editor has failed to load itself properly and display the rendered html code.
But there's more.
Here's what the same site looks like as served up by the test server:

[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/firefox-mac_moodle_test.png]]

The display is fine. TinyMCE loads and renders correctly.
This is using the //same code// and the //same database// and ''//in an adjacent tab in the same browser//'' (Firefox v13).
!!!Other browsers
* On OS X 10.6 Safari and Chrome display the editor fine
* On Win XP Firefox v13 and Chrome also work fine.

One final point. This behaviour was brought to my attention by a teaching faculty person (Lori Watson) so it's not just a glitch in the configuration of my Mac.
Surely this issue must be a server thing.
----
!FIX
After consultation with Aaron we discovered that the fix is simply to empty the Firefox cache and then the editor loads fine.
From CLAMP Moodle Exchange [[How's performance on production 2.3?|http://cme.clamp-it.org/mod/forum/discuss.php?d=994]]:
+++[Joe Murphy (Kenyon)]>
We saw a big performance boost after installing eaccellerator. That's our biggest take-away.

(Also, in a relevant tangent, I'm convinced that teachers need to use up-to-date browsers to get acceptable performance.)
From our admin (and about 2 months old):
all of this is on VMWare
Web Server - FreeBSD 8.2 - 1GB RAM - 1 CPU (dedicated to moodle and moodle-pilot, moodle archive runs on another server)
Apache 2.2.22
PHP 5.4.3
eaccelerator 0.9.6.1
interesting php.ini settings
post_max_size = 325M
upload_max_filesize = 325M
mysql Server - CentOS 5.8 - 2GB RAM - 1 CPU (dedicated to moodle and moodle-pilot and moodle archive)
mysql server 5.0.95
Also, we run the web traffic, along with most of our other web sites, through a small nginx reverse proxy server.
=== 

+++[Dean Thayer (Hope)]>
Updating to the latest 2.3.1+ including the MDL-34212 fix was very important for us, but prior to doing so I was able to make great gains by increasing our virtual CPUs from 2 to 4 and our virtual RAM from 2 to 6 GB (we run Moodle in VMware) and setting these variables in my.cnf:

innodb_buffer_pool_size = 1024M
innodb_flush_method=O_DIRECT

If you have never run http://www.day32.com/MySQL/tuning-primer.sh and http://mysqltuner.pl before, I would recommend them.
=== 
I had a look at Mary Evan's [[Custom corners]] which I have already but I judged that this was also too finicky to hack with.
Then looked at [[Cafelite-WR|http://moodle.org/mod/data/view.php?d=26&rid=4617&filter=1]] which looked rather good.
I changed the logo:

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/logo-5.png]]

And then removed the excess menu options and hacked the +++[cafelite-wr-menu.php]
{{{
<?php
echo '<ul>';
echo '<li class="home"><a href="'.$CFG->wwwroot.'/"><img width="18" height="17" src="'.
$CFG->httpswwwroot.'/theme/'.current_theme().'/img/home_icon.png" alt="Home" title="Home" /></a>
	</li>';
if (!isloggedin() or isguestuser()) {
echo '<li><a href="'.$CFG->wwwroot.'/login/index.php">'.get_string('login').'</a></li></ul>';
} else {
echo '<li><a href="'.$CFG->wwwroot.'/login/logout.php">'.get_string('logout').'</a></li>';
echo '<li><a href="'.$CFG->wwwroot.'/user/edit.php?id='.$USER->id.'&amp;course='.$COURSE->id.'">'.get_string('updatemyprofile').'</a></li>';
echo '<li><a href="'.$CFG->wwwroot.'/my">'.get_string('mycourses').'</a><li>';
echo '</ul>';
} 
?>
<?php
	echo '<ul class="menu-date">';
	echo '<li><a href="'.$CFG->httpswwwroot.'/calendar/view.php" title="Calendar">';
	echo userdate(date('U'));
	echo '</a></li></ul>';
?>
}}}
===  to validate properly.

The [[end result|http://legacy.earlham.edu/~markp/moodledocs/graphics/theme_cafelite-prodmoodle.png]]<<imagebox>> is rather nice methinks.

+++[Other cafelite links]
* [[Cafelite-WR Theme for Moodle 1.9|http://moodle.org/mod/forum/discuss.php?d=170377]]
* [[dropdown menus|http://moodle.org/mod/forum/discuss.php?d=166703]]
* [[Moodle themes using YUI display-zooming "tears apart" the theme-body|http://moodle.org/mod/forum/discuss.php?d=185162]]
=== 
When looking at myCourses block there's an annoying extra piece in the way -- [[screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/theme_cafe-light-fix-course-menu.png]]<<imagebox>>. Renaming //one.gif// makes it disappear! 
{{{cafelite-wr/pix/i]$ mv one.gif one-move.gif}}} 
Except that in Chrome you see a broken image graphic. Clearly it has to be there.
The real problem is the alignment -- try aligning to the bottom of the line.

Also instead of the shortname in the breadcrumb bar:
[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/theme_cafelite-breadcrumb.png]]
place the Full course name here.
Here again, in Anomaly the full name takes up the main heading area. Try hacking cafelite to do similar.

[[Revamp of Cafelite]]
Derived from NEUI (new-eee) but using a row, column, box model with the help of emastic framework. And there are some new goodies, like a sortable list makro for the ~MainMenu and ~TopMenu. ~ToggleLeft, ~ToggleRight. Fully functional, stand alone, icons. ~ThemeSwitcher at the options panel and more. Version: 0.6.3 ... have fun! 
/*{{{*/
body {
	font-size: 1.0em;
	font-family: helvetica, arial, sans-serif;
	background-color: [[ColorPalette::Background]];
}

#displayArea {
	float: left;		/*-- new for emastic --*/		
	padding: 0;		/*-- new for emastic --*/
	margin: 0;		/*-- new for emastic --*/
}

#tiddlerDisplay {
/*	margin: 1em 0.5em;*/
}

.public {
	border-color: #C7EAFF;
}

.private {
	border-color: #FFCAE9;
}

.revisionCloak {
	position: absolute;
	position: fixed !important;
	height: 100%;
	width: 100%;
	top: 0;
	left: 0;
	border: 0;
	margin: 0;
	padding: 0;
	opacity: 0.5;
	filter: alpha(opacity=50);
	background-color: black;
}

/* fixing h1-h6 margin-top if it is first child */
h1:first-child, h2:first-child, h3:first-child,
h4:first-child, h5:first-child, h6:first-child,

ol:first-child, ul:first-child {
	margin-top: .3em;
}


[[StyleSheetHeaderMp]]
[[StyleSheetMenuBarMp]]
[[StyleSheetSideBarMp]]
[[StyleSheetTiddlerMp]]
[[StyleSheetBackstagePanels]]
/*}}}*/
!!Thursday Aug 15^^th^^ 9:30
*    brief introduction to Moodle 2 
*    overview of writing assignment types and their match with options available with Moodle Assignment
## Short essays (1-3 pages)
## Longer papers (>= 3 pages)
## Doing it all online -- the PDF assignment
*    grading options
## grade online -- zip download papers, zip upload response papers
## grade offline -- zip download & upload + download grading spreadsheet, upload grading spreadsheet
## grade & markup online -- pdf assignment
* gradebook 
## making grading more transparent -- rubric grading
## revising the writing -- outline, bibliography, drafts, final -- how to aggregate these into a single grade by grouping assignments into Categories.
## have Moodle do the arithmetic

Each participant will have a test course where they are the Teacher. They will also be enrolled as students in someone else's test course.
# Demo simple assignment -- 15 mins
** setting it up
** student submission, 
** grading the submission
** duplicating and moving to a different section of the Course outline
# Have participants create a simple assignment and duplicate it.
# Open another writing test course and submit a dummy response.
# 'Grade' and return the comments
# As student open up the assignment and view the results.
# Create assignment in own course
||Jay Roberts| N| 8-16|I am very interested but will be in the woods during that time. Let me know if another date pops up.|
| |Aletha Stahl| ?| 8-16|However, if this fills up and you add another session later (if you're considering that), that would be my preference.|
| |Lori Watson| N| 8-16|Sounds great!  But I'll be backpacking in the Utah mountains with Jay and crew...  Let me know if you have another one!|
| |Meg Streepey Smith| | |Geoscience. Will be on vacation 8th Aug|
| |Meghen Jones| | |"I will not be able to attend on that date as I'll be in Japan, but I'm very interested in learning more about this topic. Will there be another session offered? I am here this month and then back August 15.|
--Looks like Thurs Aug 16th may be a good date.--
Friday 17th Aug would be better since Librarians could then attend.
Publicize this?
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
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{

window.hideWhenLastTest = false;

window.removeElementWhen = function(test,place) {
	window.hideWhenLastTest = test;
	if (test) {
		jQuery(place).empty()
		place.parentNode.removeChild(place);
	}
};


merge(config.macros,{

	hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( eval(paramString), place);
	}},

	showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !eval(paramString), place);
	}},

	hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAny(params), place);
	}},

	showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAny(params), place);
	}},

	hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
	}},

	showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
	}},

	hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title == params[0], place);
	}},

	showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title != params[0], place);
	}},

	'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !window.hideWhenLastTest, place);
	}}

});

//}}}

/***
|''Name''|TiddlyFileImporter|
|''Version''|0.3.8|
|''Author''|Ben Gillies|
|''Type''|plugin|
|''Description''|Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.|
!Usage
Upload a TiddlyWiki file to TiddlyWeb, and import the tiddlers.
!Requires
tiddlyweb
tiddlywebplugins.reflector
!Code
***/
//{{{
(function($){
if(!version.extensions.TiddlyFileImporter)
{ //# ensure that the plugin is only installed once
	version.extensions.TiddlyFileImporter = { installed: true };
}

config.macros.fileImport = {
	reflectorURI: '/reflector?csrf_token=%0',
	incorrectTypeError: 'Incorrect File Type. You must upload a TiddlyWiki',
	uploadLabel: 'Upload',
	uploadLabelPrompt: 'Import tiddlers from this TiddlyWiki',
	step1FileText: 'File:',
	step1PostText: 'In the next screen you will select the tiddlers to import.',
	step1Title: 'Step 1: Pick a TiddlyWiki to import',
	step1TypeChooser: 'Import From:',
	step3Html: ['<input type="hidden" name="markList" />',
		'<input type="hidden" checked="true" name="chkSync" />',
		'<input type="hidden" name="chkSave" />',
		'<input type="hidden" name="txtSaveTiddler" />'].join(),

	handler: function(place, macroName, params, wikifier, paramString) {
		var wizard = new Wizard();
		wizard.createWizard(place, 'Import a TiddlyWiki');
		this.restart(wizard);
	},

	restart: function(wizard) {
		var me = config.macros.fileImport;
		wizard.addStep(me.step1Title, ['<input type="hidden" ',
			'name="markList" />'].join(""));
		var markList = wizard.getElement('markList');
		var uploadWrapper = document.createElement('div');
		markList.parentNode.insertBefore(uploadWrapper, markList);
		uploadWrapper.setAttribute('refresh', 'macro');
		uploadWrapper.getAttribute('macroName', 'fileImport');
		var iframeName = 'reflectorImporter' + Math.random().toString();
		me.createForm(uploadWrapper, wizard, iframeName);
		$(uploadWrapper).append('<p>' + me.step1PostText + '</p>');
		wizard.setValue('serverType', 'tiddlyweb');
		wizard.setValue('adaptor', new config.adaptors.file());
		wizard.setValue('host', config.defaultCustomFields['server.host']);
		wizard.setValue('context', {});
		var iframe = $(['<iframe name="' + iframeName + '" ',
			'style="display: none" />'].join("")).appendTo(uploadWrapper);
		var onSubmit = function(ev) {
			var uploadType = $('select[name=uploadtype]', wizard.formElem).val();
			if (uploadType == "file") {
				// set an onload ready to hijack the form
				me.setOnLoad(uploadWrapper, wizard, iframe[0]);
				wizard.importType = 'file';
				wizard.formElem.submit();
			} else {
				var csrf_token = config.extensions.tiddlyspace.getCSRFToken();
				$.ajax({
					url: "%0/reflector?csrf_token=%1".format(
						config.defaultCustomFields["server.host"], csrf_token),
					type: "POST",
					dataType: "text",
					data: {
						uri: $("input", ".importFrom", wizard.formElem).val()
					},
					success: function(data, txtStatus, xhr) {
						wizard.POSTResponse = data;
						me.importTiddlers(uploadWrapper, wizard);
					},
					error: function(xhr, txtStatus, error) {
						displayMessage(["There was an error fetching the ",
							'url: ', txtStatus].join(""));
						me.restart(wizard);
					}
				});
				return false;
			}
		};
		wizard.setButtons([{
			caption: me.uploadLabel,
			tooltip: me.uploadLabelPrompt,
			onClick: onSubmit
		}]);
		$(wizard.formElem).submit(function(ev) {
			onSubmit(ev);
			ev.preventDefault();
		});
	},

	createForm: function(place, wizard, iframeName) {
		var form = wizard.formElem;
		var me = config.macros.fileImport;
		form.action = me.reflectorURI.format(
			config.extensions.tiddlyspace.getCSRFToken());
		form.enctype = 'multipart/form-data';
		form.encoding = 'multipart/form-data';
		form.method = 'POST';
		form.target = iframeName;
		onSelectChange = function(e) {
			var changeTo = $(this).val();
			if (changeTo == "file") {
				$(".importFrom").html('%0 <input type="file" name="file" />'.
					format(me.step1FileText));
			} else {
				$(".importFrom").html('URL: <input type="text" name="uri" />'
					+ ' Do you want <a target="_blank" href="http://faq.tiddlyspace.com/How%20do%20I%20include%2Fexclude%20spaces%3F">inclusion</a> instead?');
			}
		};
		$(place).append('<span>%0</span>'.format(me.step1TypeChooser)).
			append($(['<select name="uploadtype"><option value="file" selected="selected">file',
				'<option value="uri">url</select>'].join("")).change(onSelectChange)).
			append('<div class="importFrom">%0<input type="file" name="file" /></div>'.
					format(me.step1FileText));
	},

	setOnLoad: function(place, wizard, iframe) {
		var me = config.macros.fileImport;
		var loadHandler = function() {
			me.importTiddlers.apply(this, [place, wizard, iframe]);
		};
		iframe.onload = loadHandler;
		completeReadyStateChanges = 0;
		iframe.onreadystatechange = function() {
			if (++(completeReadyStateChanges) == 5) {
				loadHandler();
			}
		};
	},

	importTiddlers: function(place, wizard, iframe) {
		var tmpStore = new TiddlyWiki();
		var POSTedWiki = "";
		if (wizard.importType == "file") {
			try {
				POSTedWiki= iframe.contentWindow
					.document.documentElement.innerHTML;
			} catch(e) {
				displayMessage(config.macros.fileImport.incorrectTypeError);
				config.macros.fileImport.restart(wizard);
				return;
			}
			// now we are done, so remove the iframe
			$(iframe).remove();
		} else {
			POSTedWiki = wizard.POSTResponse;
		}

		tmpStore.importTiddlyWiki(POSTedWiki);
		var newTiddlers = tmpStore.getTiddlers();
		var workspace = config.defaultCustomFields['server.workspace'];
		var context = {
			status: true,
			statusText: 'OK',
			httpStatus: 200,
			adaptor: wizard.getValue('adaptor'),
			tiddlers: newTiddlers
		};
		context.adaptor.store = tmpStore;
		wizard.setValue('context', context);
		wizard.setValue('workspace', workspace);
		wizard.setValue('inFileImport', true);
		config.macros.importTiddlers.onGetTiddlerList(context, wizard);
	}
};

var _onGetTiddler = config.macros.importTiddlers.onGetTiddler;
config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
	if (wizard.getValue('inFileImport')) {
		var me = config.macros.importTiddlers;
		if(!context.status)
			displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
		var tiddler = context.tiddler;
		var fields = tiddler.fields;
		merge(fields, config.defaultCustomFields);
		fields["server.workspace"] = wizard.getValue('workspace');
		delete fields['server.permissions'];
		delete fields['server.bag'];
		fields['server.page.revision'] = 'false';
		delete fields['server.recipe'];
		fields.changecount = 1;
		store.suspendNotifications();
		store.saveTiddler(tiddler.title, tiddler.title, tiddler.text,
			tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields,
			false, tiddler.created);
		store.resumeNotifications();
		var remainingImports = wizard.getValue("remainingImports")-1;
		wizard.setValue("remainingImports",remainingImports);
		if(remainingImports === 0) {
			if(context.isSynchronous) {
				store.notifyAll();
				refreshDisplay();
			}
			wizard.setButtons([
					{caption: me.doneLabel, tooltip: me.donePrompt, onClick: me.onClose}
				],me.statusDoneImport);
			autoSaveChanges();
		}
	} else {
		_onGetTiddler.apply(this, arguments);
	}
};

var _onCancel = config.macros.importTiddlers.onCancel;
config.macros.importTiddlers.onCancel = function(e)
{
	var wizard = new Wizard(this);
	if (!wizard.getValue('inFileImport')) {
		return _onCancel.apply(this, arguments);
	}
	var place = wizard.clear();
	config.macros.fileImport.restart(wizard);
	return false;
};

var _step3Html = config.macros.importTiddlers.step3Html;
var _onGetTiddlerList = config.macros.importTiddlers.onGetTiddlerList;
config.macros.importTiddlers.onGetTiddlerList = function(context, wizard) {
	var fileImport = config.macros.fileImport;
	var importTiddlers = config.macros.importTiddlers;
	if (wizard.getValue('inFileImport')) {
		importTiddlers.step3Html = fileImport.step3Html;
	} else {
		importTiddlers.step3Html = _step3Html;
	}
	_onGetTiddlerList.apply(this, arguments);
};
})(jQuery);
//}}}
|''Name:''|[[TWDefaultTheme]]|
|''Description:''|Your description here!|
|''Generator:''|[[TW FreeStyle|http://FreeStyle.tiddlyspot.com]]|
|''Gen.Description:''|Automatically generated from: TWDefaultThemeProject|
|''PageTemplate:''|PageTemplate|
|''ViewTemplate:''|ViewTemplate|
|''EditTemplate:''|EditTemplate|
|''RevisionTemplate:''|RevisionTemplate|
|''StyleSheet:''|##StyleSheet|

!StyleSheet
/*{{{*/

/* horizontal main menu stuff if created by list */
.noBullets a{
	padding-top: 0.2em;
	padding-bottom: 0.2em;
}

.noBullets ul,
.noBullets ol {
	list-style:none;
	padding:0;
	margin: 0;
}

.noBullets li {
	float: left;
}

[[StyleSheetTiddlySpace]]
/*}}}*/
/***
|Name:|RenameTagsPlugin|
|Description:|Allows you to easily rename or delete tags across multiple tiddlers|
|Version:|3.0 ($Rev: 5501 $)|
|Date:|$Date: 2008-06-10 23:11:55 +1000 (Tue, 10 Jun 2008) $|
|Source:|http://mptw.tiddlyspot.com/#RenameTagsPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
Rename a tag and you will be prompted to rename it in all its tagged tiddlers.
***/
//{{{
config.renameTags = {

	prompts: {
		rename: "Rename the tag '%0' to '%1' in %2 tidder%3?",
		remove: "Remove the tag '%0' from %1 tidder%2?"
	},

	removeTag: function(tag,tiddlers) {
		store.suspendNotifications();
		for (var i=0;i<tiddlers.length;i++) {
			store.setTiddlerTag(tiddlers[i].title,false,tag);
		}
		store.resumeNotifications();
		store.notifyAll();
	},

	renameTag: function(oldTag,newTag,tiddlers) {
		store.suspendNotifications();
		for (var i=0;i<tiddlers.length;i++) {
			store.setTiddlerTag(tiddlers[i].title,false,oldTag); // remove old
			store.setTiddlerTag(tiddlers[i].title,true,newTag);  // add new
		}
		store.resumeNotifications();
		store.notifyAll();
	},

	storeMethods: {

		saveTiddler_orig_renameTags: TiddlyWiki.prototype.saveTiddler,

		saveTiddler: function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
			if (title != newTitle) {
				var tagged = this.getTaggedTiddlers(title);
				if (tagged.length > 0) {
					// then we are renaming a tag
					if (confirm(config.renameTags.prompts.rename.format([title,newTitle,tagged.length,tagged.length>1?"s":""])))
						config.renameTags.renameTag(title,newTitle,tagged);

					if (!this.tiddlerExists(title) && newBody == "")
						// dont create unwanted tiddler
						return null;
				}
			}
			return this.saveTiddler_orig_renameTags(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created);
		},

		removeTiddler_orig_renameTags: TiddlyWiki.prototype.removeTiddler,

		removeTiddler: function(title) {
			var tagged = this.getTaggedTiddlers(title);
			if (tagged.length > 0)
				if (confirm(config.renameTags.prompts.remove.format([title,tagged.length,tagged.length>1?"s":""])))
					config.renameTags.removeTag(title,tagged);
			return this.removeTiddler_orig_renameTags(title);
		}

	},

	init: function() {
		merge(TiddlyWiki.prototype,this.storeMethods);
	}
}

config.renameTags.init();

//}}}

!Working with the Workshop -- peer review reviewed

+++!![Background -- why use Workshop ?]

The Workshop module is a major instructional technology tool in the Moodle toolkit. It's been around since version 1.0 but had acquired a reputation for flakiness. More recently David Mudrak took it over and did a thorough revamp.

I am of the opinion that a Teacher should use just a single major tool per course and use it frequently enough for students to get thoroughly familiar. This is how Geology prof Andy Moore [photo] and Earlham's Instructional Technologist have used Workshop for two successive years in GEOS314 Interpreting Earth History.

The Earth History is an upper level Geosciences course which attracts Environmental Studies as well as Geosciences majors and since it's Gen Ed fulfilling, some science students as well (roughly 33% of each). Given this mix of student background in Geology, Andy decided to adjust the course objectives to reflect student abilities and make the course more fulfilling than merely a content cramming exercise. With this in mind in addition to Labs (inside & out), short quizzes to make sure everyone gets the material, and field trips, the students were expected to prepare a 15 minute in depth presentation about an assigned Earth History topic. As a result students get to hone their research and presentation skills as well as learning the content. Every student does at least four (4) of these presentations during the semester which are evaluated by their peers and the teacher for content and delivery using a rubric [link to pdf]. Grades are based on a combination of student and teacher assessments and comprise 30% of the final grade.

The pedagogic value of peer assessment of presentations was fourfold:

# Students had to research a brand new Geological topic and compile a meaningful summary.
# They had to present it before their peers in an accessible and concise manner
# They had to take notes on the presentation in order to understand the concepts presented (for a subsequent quiz)
# They had to review and assess the presentations they had seen in a thorough but gentle way.

With grade allocation and feedback from the Teacher, we would also have:

* Progressive improvement in quality of presentations
* How to grade like a teacher -- finding balance between critique and encouragement
* Progressive improvement in quality of assessment

Andy had attempted to do this peer evaluation on paper but quickly found that the management headaches were all but insurmountable. So he came to me to ask whether there was a way of accomplishing the peer assessment online and preferably with Moodle. Enter Moodle Workshop.
=== 
+++!![Using the Workshop with GEOS314]

[course outline in moodle] A typical class session had two presentations which are videoed and evaluated. Classes took place three times a week, Monday, Wednesday, Friday but some weeks there were presentations on fewer days. The idea was that the presenters would upload or link to their presentations in the appropriate Workshop activity in the Moodle course before the start of the class session. They could then run their presentation from the link they just created. During each presentation the student peer reviewers made notes about the content rather than it's delivery since this would be the subject of the next quiz. They were able to access the video recording of the class presentation which was uploaded to Youtube immediately following the end of class and make their peer assessment in the moodle workshop out of class time using the rubric embedded in the Workshop activity. The peer assessment was due the night before the next presentation so that presenters and reviewers could get their feedback before the next topic.

I wrote a [[reasonably comprehensive document|http://epress.earlham.edu/tsardocs/2013/02/07/moodle-workshop-faq-student/]] detailing how to submit a presentation and evaluate a peer presentation.

The Teacher would do his assessment, review the assessments done by the students and override if necessary and then switch the Workshop to Grading phase. Students would review their grades and feedback in a timely manner. At some point there would be general and individual consultations about progress.
=== 

+++!![Workshop configuration and operation]

The Workshop activity progresses through four (4) phases [img]. The hope was that after the appropriate students had submitted their work the workshop would switch between submission / assessment / grading phase automatically according to the deadlines set.

!!!1. Setup
;Workshop Settings : //Description// 
:I detailed who was presenting and when the presentations should be uploaded by. Also the due date/time for assessments. I checked 'display description' so that it would be shown in the Course Outline.
;Grading Settings 
:Set the Grading strategy (rubric) and grades for submission and assessment (100 each). 
;Submission setting 
:I checked 'Allow late submissions' because students were often late. Self assessment and example submissions were not used. 
;Overall feedback 
:Set to 'Enabled and optional' so that students could add specific comments about the presenter (since the rubric form does not allow for comments). (Perhaps better to set to required).
;Availability 
:The submission deadline was set here, auto switching set and assessment open and dealine dates/times were set.

!!!!Assessment Rubric
Rubric was defined in Workshop administration > 'Edit assessment form'. 
Some care needs to be exercised with implementing a rubric. The rubric I was given had 7 criteria with 5 levels with the total being a convenient 100 points. Three of the criteria were worth 20 points each and four 10 points each. The problem was that the rubric scale goes from 0 to the max, so for 5 levels on a 10 point max scale you would have 0, 2.5, 5, 7.5 , 10 for successive levels. However the rubric levels can only cope with integer whole numbers so you cannot have a decimal value assigned to a level. The solution was to double every value so that the final grade was out of 200 instead of 100.

|!Assessment|!Criteria|>|>|>|>|!Levels|!Summary|
|Presenter : speech clarity & volume|''Volume and Rate''| 0| 5| 10| 15| 20|Difficult to hear -> Easy to hear with good rate of speech|
|Presenter : no distracting features|''Mannerisms''| 0| 5| 10| 15| 20|No eye contact. Nervous -> Eye contact with audience. No nervous habits.|
|Presentation : effective articulation of theme|''Organization''| 0| 10| 20| 30| 40|No organization. Unclear relationships -> Well organized with strong theme and clear ideas|
|Presentation : depth, focus & appropriate detail|''Content depth''| 0| 10| 20| 30| 40|No reference to theory / literature. Thesis not clear -> Complete explanation of key concepts with reference to literature|
|Presentation : understanding of subject|''Content Accuracy''| 0| 10| 20| 30| 40|Inaccurate or irrelevant information included -> All information accurate and explicit|
|Audience engagement : visual & audio|''Visuals''| 0| 5| 10| 15| 20|Little or poor use -> visuals used to engender interest and engagement|
|Audience engagement : pacing and total time|''Length''| 0| 5| 10| 15| 20|Lacks conclusion. Time not well used -> Appropriate length. Clear summary. Audience participation involved.|
| |''Total''| | | | |''200''| |

+++!!![Notes configuring the Workshop activity]
* By default Workshop is ''not'' configured for anonymous reviewing. You have to manually prevent "view author names" mod/workshop:viewauthornames and "view reviewer names" mod/workshop:viewreviewernames in permissions. Probably best to do this for the whole course.
* By default the teacher does not have submit or peer assess capability to the workshop. Switch this to 'Allow' with permissions override.
* By default every peer review grade has the same effect on the resulting assessment grade. But what Andy wanted was that the grade assigned by students should be compared to his. We fixed this by giving a bigger weight to Andy's assessment in the Grading phase than the students.
=== 
!!!2. Submissions phase
[img:switch phase] This switches from the Setup to Submissions and allows the presenters to upload their work. When the Submissions open date is enabled in Workshop admin > Edit settings : Availability then this gets switched on automatically.

!!!3. Assessment phase

Switching to this phase by clicking the light bulb allocates submissions to students according to the 'Allocate submissions' instruction page or if all the presenters have uploaded their work it can be switched automatically as detailed before. 
Make sure to run Workshop admin > ''Allocate submissions''
This is where we run into a problem. The Workshop is designed to have all students in the class upload a given submission (one or more files or links) and then each has to evaluate each other according to the configured assessment. But in this case we only have two submissions and 15 or more assessments. The work around was in Allocation settings to check 'Participants can assess without having submitted anything' and assign 15 reviews per submission.

!!!4. Grading
After the deadline for assessment (Edit settings : Availability) no more assessments can be done but the Grading phase must be switched manually.
[Grading evaluation screen]
After switching to the Grading evaluation phase there are two sets of grades :

!!!!1. For Presenters
Each of the two student presenters got a grade for their presentation which consisted of the average of all the grades received from  assessments.
!!!!2. For Assessors
The students not presenting assessed two presentations per Workshop, the presenters assessed one other. A grade was assigned for the accuracy of their own assessment. This accuracy was loosely defined as the nearness to the 'best assessment'. In our Workshop practice the Teacher gave himself a weight of 8 so that his assessment would always be the 'best assessment' for comparative purposes. Thus 

!! Grading calculation

The [[Workshop grading strategies|http://docs.moodle.org/24/en/Workshop_grading_strategies]] are opaque at best. However, the grade given by the rubric responses is visually consistent -- 

The [[grade for assessment|http://docs.moodle.org/24/en/Using_Workshop#Grade_for_assessment]] is predicated upon the philosophy that all assessments have equal importance. Besides being pedagogically unsound (the Teacher assessment should provide the calibration for comparing the accuracy of assessments) it's very difficult to figure out whether grade given for assessment is not erroneous.
=== 
+++!![Peer Assessment]
This is best reviewed in the Workshop grades report which is obtained after moving to the Grading phase
[Earth-WS-grading_accuracy1.png]
* The quality of the presentations varied widely. In a class session there was often a very good & a rather poor presentation together. This may have affected the way that assessments were done.
* Students generally graded harder in their assessments than the Teacher. 
** This resulted in a grade for submission that was frequently lower than that given by the Teacher. (see graphic)
** This was reflected in low Grades for Assessment, eg 48.5% indicates that your grade was way off that of the Teacher.
Example of Teacher assessment : Earth-WS-assessment-teacher.png
Example of low student assessment : Earth-WS-assessment-student1.png
: note that a Teacher can actually //override// the grade given by the student to align it better.
Reading the Grading report : [Earth-WS-grading_accuracy2.png]
Also see [[http://docs.moodle.org/24/en/Using_Workshop#Workshop_grading]]

!!Outcomes

* Improvement in delivery and standard of presentation
* Students did not allocate enough time to the actual presentation.
**  too much text, not enough maps, illustrations, photos, diagrams etc
=== 
+++!![Issues]

!!!Operational problems:

# Getting all the students to submit their assessments before the next presentation day
# Getting the Teacher to submit his assessment at all(!)
# Problem with understanding how grades for assessment were calculated.
# Grades not available by following class session so pedagogic value was greatly diluted

Assessment weight is manually set in the Assessment settings but these are only available to the Teacher. So Teacher sets weight to 8 and all assessments compared to this one.

Even so, it's not possible to compute the grade an assessment would get by hand. This is a major issue.

!!!Grade calculation method

From [[Workshop documentation at moodle.org|http://docs.moodle.org/25/en/Workshop_settings#Grade_calculation_method]]
<<<
This setting determines how to calculate grade for assessments. Currently there is only one option- comparison with the best assessment.
The Comparison with the best assessment tries to imagine what a hypothetical absolutely fair assessment would look like. 
<<<
From what I can glean from the documentation, the 'best asssessment' is simply //the most popular// given by all the assessors. Effectively what this means is that it rewards 'group think'. If your assessment is close to the average then it'll get high marks //regardless of any external standard//.

We attempted to influence this by weighting the Teacher's assessment by a factor of 8 and student's by 1. But this was just a guess and I did not have time to experiment to determine the optimal weighting factor.

Comparing assessments with "the best" :
<<<
This setting has 5 options: very lax, lax, fair, strict and very strict. It specifies how strict the comparison of assessment should be. By using comparison with the best assessment method, all assessments will be compared with the best assessment picked up by workshop. The more similar one assessment is with the best assessment, the higher grade this assessment will get, and vice versa. This setting determines how quickly the grades fall down when the assessments differ from the best assessment.
<<<

However, the premise for 'comparison with best assessment' is fundamentally flawed. The 'best' assessment is not necessarily the assessment closest to the mean -- we're not talking standard deviations here.

The problem is, as Vernellia Randall perceptively pointed out in the moodle.org discussion [[Please Vote: MDL-35722 - Allow teachers assessment to be "best" paper|https://moodle.org/mod/forum/discuss.php?d=212784]] is that there is no means of explicitly making the Teacher's assessment be the reference one to which students are compared. Moreover, the author's (David Mudrak) response "I am a little bit afraid that such feature would go against some basic concepts of the Workshop module." unfortunately illustrates the gulf between some of the moodle coders and teaching practitioners.

=== 


+++![Conclusions and thoughts]
* A larger class (than 15 - 20) with more reviews might be better, although a smaller class size gives more opportunities for practice.
* Students need to be impressed upon that the grade they give in their assessment does count. This might help the reflection process.
* A lack of written commentary indicates that the student has not given their assessment much thought and therefore such assessments should be removed and not count.
* To ameliorate the consistent undergrading by students the teacher should override the allocated grade to ensure a fair grade.
* In terms of workflow, the Workshop activity works well when the Teacher leads the way and forces the students to discipline themselves to the submission and assessment deadlines. If the Teacher adopts the assessment deadline too then the assessment grade can be a valuable pedagogical tool. 
** There may be a way of sharing the teacher's completed assessment too -- I did not investigate this. 

Example of a brilliant presentation done at the end of this process:
+++[Youtube video of presentation]
<html>
<iframe width="853" height="480" src="//www.youtube-nocookie.com/embed/w_QYno31KMk?rel=0" frameborder="0" allowfullscreen></iframe>
</html>
=== 
=== 
[[Install Apache, MariaDB And PHP In FreeBSD10|http://www.unixmen.com/install-apache-mariadb-php-freebsd10/]]
[[Install Latest phpMyAdmin In FreeBSD 10|http://www.unixmen.com/install-latest-phpmyadmin-freebsd-10/]]
[[AMP: Apache, MySQL and PHP on FreeBSD|http://bsdbox.co/2013/12/20/amp-apache-mysql-and-php-on-freebsd/]]
----
{{ts{24/07/14 15:36}}}
* Set new password for {{{theFN}}}
* Install vim-lite {{{patmos% sudo pkg install vim-lite-7.4.334}}}
* +++[Install Apache 2.4]> 
{{{
patmos% sudo pkg install apache24-2.4.9_4

Updating repository catalogue
The following 6 packages will be installed:

        Installing expat: 2.1.0_1
        Installing perl5: 5.16.3_11
        Installing gdbm: 1.11_2
        Installing db48: 4.8.30.0_2
        Installing apr: 1.5.1.1.5.3_2
        Installing apache24: 2.4.9_4
Using existing group 'www'.
Using existing user 'www'.
/usr/local/share/examples/apache24/httpd.conf -> /usr/local/etc/apache24/httpd.conf
 done
To run apache www server from startup, add apache24_enable="yes"
in your /etc/rc.conf.
}}}
So:
{{{
patmos% sudo echo 'apache24_enable="YES"' >>/etc/rc.conf
zsh: permission denied: /etc/rc.conf
}}}
Hmmmmmm
Start it up:
{{{patmos% sudo /usr/local/etc/rc.d/apache24 start}}}
And http://patmos.earlham.edu/ @@works@@
=== Problem with 'permission denied' when echo command.
Moodle 2.7.1 requires {{{PHP 5.4.4, MariaDB 5.5.31 or MySQL 5.5.31 or Postgres 9.1}}}
I'm planning to install php 5.5.14, ~MariaDB 5.5.38, Postgres 9.3.4
+++!!![Mariadb]>
{{{
patmos% sudo pkg install mariadb55-server-5.5.38

Proceed with installing packages [y/N]: y
mariadb55-client-5.5.38.txz                        100% 1701KB 154.6KB/s 240.5KB/s   00:11
mariadb55-server-5.5.38.txz                          8% 1040KB  15.6KB/s   0.0KB/s   11:38 ETA

pkg: An error occurred while fetching package
}}}
{{{pkg info}}} showed that it had not been installed, so try again with {{{sudo pkg install mariadb55-server-5.5.38}}} and just downloads the server part successfully.
{{{
[1/2] Installing mariadb55-client-5.5.38... done
[2/2] Installing mariadb55-server-5.5.38...===> Creating users and/or groups.
Creating group 'mysql' with gid '88'.
Creating user 'mysql' with uid '88'.
 done
************************************************************************

MariaDB respects hier(7) and doesn't check /etc and /etc/mysql for
my.cnf. Please move existing my.cnf files from those paths to
/usr/local/etc and /usr/local/etc/mysql.

************************************************************************
************************************************************************

Remember to run mysql_upgrade (with the optional --datadir=<dbdir> flag)
the first time you start the MySQL server after an upgrade from an
earlier version.
}}}
----
Note:
No {{{my.cnf}}} file in /usr/local/etc or /usr/local/etc/mysql.
!!Configuration
1. Set mysql_enable to YES in /etc/rc.conf
2. Start up MariaDB server
{{{
patmos% sudo service mysql-server start
Starting mysql.
}}}
3. Create root password {{{patmos% mysqladmin -u root password "Ca3rnarF0N"}}}
4. Install Innodb tables (mysql default) -- {{{show engines;}}} already there!
5. +++[Setup grant tables]>
{{{
patmos: /usr/local % sudo mysql_install_db --user=mysql
Password:
Installing MariaDB/MySQL system tables in './data' ...
OK
Filling help tables...
OK

To start mysqld at boot time you have to copy support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !
To do so, start the server, then issue the following commands:

'./bin/mysqladmin' -u root password 'new-password'
'./bin/mysqladmin' -u root -h patmos password 'new-password'

Alternatively you can run:
'./bin/mysql_secure_installation'

which will also give you the option of removing the test databases and anonymous user created by default.  This is strongly recommended for production servers.

See the MariaDB Knowledgebase at http://mariadb.com/kb or the MySQL manual for more instructions.

You can start the MariaDB daemon with:
cd '.' ; ./bin/mysqld_safe --datadir='./data'

You can test the MariaDB daemon with mysql-test-run.pl
cd './mysql-test' ; perl mysql-test-run.pl
}}}
=== 
6. do {{{sudo ./bin/mysql_secure_installation}}} and
{{{
Remove anonymous users? [Y/n] Y
 ... Success!

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
}}}
Successfully started up:
{{{
80968  -  IsJ  0:00.01 /bin/sh /usr/local/bin/mysqld_safe --defaults-extra-file=/var/db/mysql/
81064  -  IJ   0:00.35 /usr/local/libexec/mysqld --defaults-extra-file=/var/db/mysql/my.cnf --
}}}
=== 
From http://www.unixmen.com/install-apache-mariadb-php-freebsd10/ :
+++!![PHP]
1. The main install
{{{
patmos% sudo pkg install php55-5.5.14
Password:
Updating repository catalogue
The following 2 packages will be installed:

        Installing libxml2: 2.9.1_1
        Installing php55: 5.5.14
}}}
Before installing any extensions, let's get it going to see what's there.

{{{DocumentRoot "/usr/local/www/apache24/data"}}}
----
Configuration of  PHP

cp /usr/local/etc/php.ini-development /usr/local/etc/php.ini

Now let’s configure Apache. Open the file /usr/local/etc/apache24/httpd.conf in your favourite editor and look for the following line:

DirectoryIndex index.html

And change it so it reads as follows:

 DirectoryIndex index.html index.htm index.php

AddType lines:

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

Now restart Apache:

 /usr/local/etc/rc.d/apache24 restart

To check if your php is nstalled,

add the code test.php,

cd /usr/local/www/apache24/data/
vi   test.php

Add the following lines:

<?php
  phpinfo();
?>

Restart apache and test:
----
=== Currently {{ts{24/07/14 17:21}}} Apache is not obeying the .php or .phps directive. This is because the php55 {{{pkg}}} is built //without webserver support// -- would you believe!
[[BSD 10 php rebuild]]

!!Install phpmyadmin
From http://bsdbox.co/2013/12/20/amp-apache-mysql-and-php-on-freebsd/ :
# +++[Install from ports]>
{{{
cd /usr/ports/databases/phpmyadmin
make config-recursive
}}}
''Remove APC option''
{{{sudo make install clean}}}
=== 
# Add +++[following code]>
{{{
Alias /phpmyadmin "/usr/local/www/phpMyAdmin"

<Directory "/usr/local/www/phpMyAdmin">
   Options None
   AllowOverride None
   Order allow,deny
   Allow from all
</Directory>
}}}
=== to {{{/usr/local/etc/apache22/extra/httpd-vhosts.conf}}}
# +++[Configure]>
{{{
mkdir /usr/local/www/phpMyAdmin/config
chmod o+w /usr/local/www/phpMyAdmin/config
}}}
then run http://patmos.earlham.edu/phpmyadmin/setup
=== 

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<title>Reply</title>
	<link rel="stylesheet" href="//tiddlyspace.com/bags/benspa_public/tiddlers/bootvelcro.css">
	<style>
		html,
		body {
			overflow: hidden;
			background-color: transparent;
		}

		#container {
			/* prevent a fouc if no images present */
			display: none;
		}

		.modal-header {
			border-bottom: none;
			padding: 5px 0 0;
			position: absolute;
			width: 100%;
			background-color: #e0e0e0;
			-webkit-border-radius: 6px 6px 0 0;
			-moz-border-radius: 6px 6px 0 0;
			border-radius: 6px 6px 0 0;
			cursor: move;
		}

		.form-actions {
			position: absolute;
			bottom: 0;
			box-sizing: border-box;
			-moz-box-sizing: border-box;
			width: 100%;
			margin: 0;
			border-radius: 0 0 6px 6px;
			background-color: #e0e0e0;
			border-top: 1px solid gray;
		}

		.form-actions input.btn {
			width: auto;
			float: right;
			margin: 0 0.2em;
		}

		.closeBtn {
			background-color: #DCE7F1 !important;
		}

		.primary {
			background-color: #09F !important;
		}

		h1 {
			margin-bottom: 9px;
			margin-top: 9px;
		}

		body {
			width: 100%;
			height: 100%;
			position: absolute;
		}

		.modal {
			margin: 10px;
			top: 0;
			left: 0;
			bottom: 0;
			width: 510px;
			position: absolute;
			box-shadow: #444 0px 0px 10px 2px;
			border-radius: 6px;
			background-color: white;
			border: 1px solid gray;
			background-color: #F0F4F8;
		}

		label em {
			cursor: pointer;
		}

		.modal-body {
			overflow: auto;
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			margin: 65px 20px 67px;
			background-color: transparent;
		}

		.nav-tabs {
			padding-left: 1%;
			margin: 0;
			width: 99%;
			border-color: gray;
		}

		.nav-tabs > li {
			cursor: pointer;
		}

		.nav-tabs > li > a {
			line-height: 2.4em;
			font-weight: bold;
			font-size: 100%;
		}

		.nav-tabs > li.active > a{
			background-color: #F0F4F8;
			border-color: gray;
			border-bottom-color: #F0F4F8;
		}

		.active {
			display: block;
		}

		input,
		textarea,
		select,
		.uneditable-input {
			color: #606060;
		}

		.imagePicker {
			-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
			border: 1px solid #CCC;
			height: 110px;
			overflow: auto;
			-webkit-border-radius: 3px;
			-moz-border-radius: 3px;
			border-radius: 3px;
			margin-left: 0;
		}

		.imagePicker img {
			margin: 5px;
			border: 2px solid transparent;
		}

		.imagePicker .current {
			border: 2px dotted #555;
		}

		label {
			font-weight: bold;
		}

		.form-actions label {
			float: left;
			margin-top: 0.75em;
		}

		fieldset input,
		fieldset textarea {
			width: 90%;
			border-color: gray;
		}

		@media all and (max-width: 550px) {
			.modal {
				width: 95%;
			}
		}

		#help {
			position: absolute;
			border: 0;
			right: 4px;
			top: 5px;
			text-indent: -9999px;
			color: transparent;
			height: 16px;
			width: 16px;
			background: none;
			background-image: url(/bags/common/tiddlers/help.png);
			background-repeat: no-repeat;
			background-color: white;
			z-index: 2;
			border-radius: 10px;
		}

		#help-info {
			padding: 0;
			border: 1px solid gray;
			width: 60%;
			height: 50px;
			color: #404040;
			background-color: white;
			position: absolute;
			top: 5px;
			right: 5px;
			z-index: 1;
			cursor: auto;
			border-radius: 5px;

		}

		#help-info p {
			padding: 10px 25px;
			margin-bottom: 0;
		}
	</style>
</head>
<body>
	<div id="container">
		<form action="#" class="modal">
			<div class="modal-header">
				<button id="help">help</button>
				<div id="help-info" style="display:none;"><p>
				Found something interesting? Write about it in your own space. <a href="//docs.tiddlyspace.com/Reply to this Tiddler" target="_blank">Find out more</a>
				</p></div>
				<ul class="nav nav-tabs" data-tabs="tabs">
					<li class="active" data-tab-name="post"><a href="#postForm">Reply</a></li>
				</ul>
			</div>


			<fieldset id="postForm" class="modal-body">
				<label>Title
					<input type="text" name="title">
				</label>
				<input type="hidden" name="url">
				<label>Post
					<textarea name="text" rows="8"></textarea>
				</label>
				<label>Tags
					<input type="text" name="tags" value="">
				</label>
			</fieldset>


			<div class="form-actions">
				<label class="checkbox">
					<input type="checkbox" name="private" val="private">
					keep private
				</label>
				<input type="submit" class="btn primary btn-large" value="Done">
				<input type="button" class="btn btn-large closeBtn" value="Cancel">
			</div>
		</form>
	</div>

	<script type="text/javascript"
            src="/bags/common/tiddlers/jquery.js"></script>
	<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/_reply.js"></script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>Account</title>
	<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/jquery-ui.custom.css" type='text/css' rel='stylesheet' >
</head>
<body>

<div id="container">
	<div class="main section">
		<a class="app" href="/">home</a>
		<div class="left">
		<div id="siteiconArea">
		<h2>User Icon</h2>
		<div>
			<img id="siteicon" class="siteicon">
			<form id="upload" method="POST" enctype="multipart/form-data">
				<input type="hidden" name="title" value="SiteIcon" />
				<input type="hidden" name="tags" value="excludeLists">
				<input type="hidden" name="csrf_token" class="csrf" />
				<input type="file" name="file" accept="image/*" />
				<input type="submit" value="upload" />
			</form>
			<div id="dropzone">Drop file here
				<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
			</div>
		</div>
		</div>
		<h2>Find Space</h2>
		<form class="spaceSearch">
			<input class="inputBox" type="text" placeholder="find space" />
			<a href="http://docs.tiddlyspace.com/What%20is%20a%20Space%3F" class="help"
				title="What is a space?">What is a space?</a>
			<button>view all</button>
		</form>
		<div class='list-container'>
			You are a member of the following spaces:
			<ul class='ts-space-search'>
			</ul>
		</div>
		<h2>Create New Space</h2>
		<form class="ts-spaces">
			<input class="inputBox" type="text" name="spacename" placeholder="space name"><span class="hostSuffix">.tiddlyspace.com</span>
			<input type="submit" value="Create Space" />
		</form>
		</div>
		<div class="right">
		<h2>Change Password</h2>
		<form class="ts-password">
			<input class="inputBox" placeholder="existing password" type="password" name="password">
			<input class="inputBox" placeholder="new password" type="password" name="new_password">
			<input class="inputBox" placeholder="new password"	type="password" name="new_password_confirm">
			<input type="submit" value="Change password">
		</form>
		<h2>OpenID</h2>
		<h3>Why OpenID?</h3>
		<a href="http://openid.net/"><img src="/bags/common/tiddlers/openid.png" alt="openid" ></a><br />
		Use just one username and password across hundreds of OpenID-enabled sites.<br />
		It's an open standard.<br />
		<a href="http://openid.net/what/">learn more</a>
		<ul class="ts-identities"></ul>
		<form class="ts-openid" target="_top">
			<div>
				Add an openid:
			</div>
			<input class="inputBox" type="text" name="openid" placeholder="your openid" />
			<input type="submit" value="Register" />
			<a href="http://openid.net/get-an-openid/" class="help"
			title="What is an open id?">What is an open id?</a>
		</form>
		</div>
		<div class="clear"></div>
	</div>
</div>
<script src="/bags/common/tiddlers/backstage.js"></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src="/bags/common/tiddlers/jquery-ui.custom.js"></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src='/bags/common/tiddlers/ts.js'></script>
<script src="/status.js"></script>
<script type="text/javascript">
/*
 * jQuery UI Autocomplete HTML Extension
 *
 * Copyright 2010, Scott González (http://scottgonzalez.com)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *
 * http://github.com/scottgonzalez/jquery-ui-extensions
 */
(function( $ ) {

var proto = $.ui.autocomplete.prototype,
	initSource = proto._initSource;

function filter( array, term ) {
	var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
	return $.grep( array, function(value) {
		return matcher.test( $( "<div>" ).html( value.label || value.value || value ).text() );
	});
}

$.extend( proto, {
	_initSource: function() {
		if ( this.options.html && $.isArray(this.options.source) ) {
			this.source = function( request, response ) {
				response( filter( this.options.source, request.term ) );
			};
		} else {
			initSource.call( this );
		}
	},

	_renderItem: function( ul, item) {
		return $( "<li></li>" )
			.data( "item.autocomplete", item )
			.append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) )
			.appendTo( ul );
	}
});

})( jQuery );

/***
_accounts application specific javascript
***/
var link;
ts.init(function(ts) {
	if(ts.user.anon) { // redirect to homepage when user not logged in
		window.location = ts.getHost();
	} else if(ts.user.name === ts.currentSpace){
		initSiteIconUpload(ts.user.name);
	} else {
		link = $("<a />").attr("href", ts.getHost(ts.user.name) + "/_account").text("Change User Icon");
		$("#siteiconArea div").empty().append(link);
	}
	$(".hostSuffix").text("." + ts.getHost("").split("//")[1]);
	ts.getSpaces(function(spaces) {
		$("<div class='info' />").text("You have " + spaces.length + " spaces.").insertBefore($(".spaceSearch")[0]);
		$("form.spaceSearch input").autocomplete({
			html: true,
			source: function(req, response) {
				ts.getSpaces(function(spaces) {
					var selected = [];
					for(var i = 0; i < spaces.length; i++) {
						var space = spaces[i];
						if(space.name.indexOf(req.term) > -1) {
							var host = ts.getHost(space.name) ;
							var img = host + "/SiteIcon";
							selected.push({
								value: space.name,
								label: '<a href="' + host + '" target="_parent" class="autocompleteLink"><img src="' + img + '" style="height:24px;width:auto;max-height:24px;max-width:24px;"/>' + space.name + '</a>'
							});
						}
					}
					response(selected);
				});
			},
			select: function(event, ui) {
				window.top.location = ts.getHost(ui.item.value);
			}
		});

		var $ul = $('.ts-space-search');
		$.each(spaces, function(i, space) {
			$ul.append($('<li/>').html($('<a/>').attr('href', space.uri)
				.text(space.name)));
		});

		$('form.spaceSearch button').click(function(ev) {
			$('.list-container').slideToggle('fast');
			ev.preventDefault();
			return false;
		});
	});
});

if(window != window.top) {
	$("html").addClass("iframeMode");
	$("a").live("click",function(ev) {
		$(ev.target).attr("target", "_parent");
	});
}
</script>
<!--[if lt IE 8]>
<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
<![endif]-->
</body>
</html>
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
Absolutely brilliant squire :-). And many thanks for putting your work out there so that dingbats like me can follow along :-).
>"I like!" -- Borat.
!Upload an icon
<<tiddler spaceIcon>>
!Describe your space
If you haven't already done so, you should provide a brief decscription of yourself and what you're using this space for. To do this, just edit the [[SiteInfo]] tiddler (keeping the title the same of course).

!Change the title
<<tiddler spaceTitle>>
!Change the theme
<<tiddler colorScheme>>
!Change the menu
If you'd like to change the menu items along the top, you can edit the [[MainMenu]] tiddler.

!Change the default tiddlers
<<tiddler setDefaultTiddlers>>
!More Advanced customisations
If you know HTML and CSS, you can edit some or all of the following tiddlers to customise your space further:
* PageTemplate
* EditTemplate
* ViewTemplate
* StyleSheet
Here's how I aggregated a bunch of RSS feeds from WP blogs into Moodle.
1. I found [[Feed2JS|http://feed2js.org]] that basically makes a javascript stream from a RSS feed.
2. You 'Build the Feed' with :
* RSS feed URL, eg {{{http://espeak.earlham.edu/oaalfot10/feed/}}}
* bunch of other parameters. I chose 40 char description and 1 item to display
3. Hit [Generate Javascript] and it outputs this code:
{{{
<script language="JavaScript" 
src="http://feed2js.org//feed2js.php?
src=http%3A%2F%2Fespeak.earlham.edu%2Foaalfot10%2Ffeed%2F
&chan=title&num=1&desc=40&au=y&date=y&targ=y&utf=y"
  charset="UTF-8" type="text/javascript"></script>
}}}
4. Select |Style| tab and try different styles. I ended up using {{{mpdreamz.css}}}
5. The next thing to do is to replicate this for all the members of the course. Initially I used Dreamweaver and a table and copy/paste with the class list usernames. This is extremely tedious and also rather error prone. {{{blogs/span202-12}}} +++[code]>
{{{
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>RSS feeds from student blogs</title>
<link href="mpdreamz.css" rel="stylesheet" type="text/css" />
</head>
<body>
<table border="0" cellpadding="8" cellspacing="0" rules="rows">
<tbody>
<tr>
  <td colspan="2"><h2 align="center">Feeds from Student Blogs</h2></td>
  </tr>
<tr>
<td style="text-align: left;">Omar Al-fotiihi<br />
<script language="JavaScript"
etc
}}}
=== 
6. From Dreamweaver I saved remotely to a folder in my web area ({{{H:\www\span202-12}}}) and then merely used a file/web site resource to link to the URL http://legacy.earlham.edu/~markp/span202-12/cornide.html
The page looks like [[this|http://legacy.earlham.edu/~markp/moodledocs/graphics/RSS-blog-feed-aggregate.png]]<<imagebox>>
[[How to use|http://legacy.earlham.edu/~markp/moodledocs/graphics/RSS-blog-feed-use.png]]<<imagebox>>

7. I set up another one for Gonzalo Paton last year but I don't know whether he used it.
----

This time around (Aug 30 2012) Ana wanted separate feeds for SPAN101-1:201310 and SPAN102-2:201310. This promised to be exceedingly tedious to create until I figured on using Excel! Saved in {{{Espeak/Spanish blogs}}}
I split up the HTML code into fixed and variable cells and then duplicated the code that needed to be copied. Turned out quite easy:

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/assemble-RSS-aggregate-table.png]]

Having got an excel spreadsheet with all the html code in the right places (eg {{{eSpeak/Spanish blogs/span101-1-201310-ana.csv}}}) I had to copy and paste the code into Dreamweaver in order to add the html header stuff.
@@Problem@@ -- every time I pasted the result added quote marks ''" "'' around everything! Nothing seems to work. Pasting in to Cream, or whatever -- all hopeless. Finally tried @@MS Word@@and ''it worked'' -- no quotes. 
So, copy from Excel, paste into Word doc, then copy from there and paste into Dreamweaver and all is well!

This cut the time to create the two sites to less than half.

created files {{{span101-1-201310-ana.html}}} and the same for the second section.
[[mTouch-U|http://mtouch.pragmasql.com/Home]]
{{ts{17/07/14 10:59}}}
Posted [[Database error on upgrade from 2.5 to 2.6|https://moodle.org/mod/forum/discuss.php?d=264117]] to Installation Help Forum 
+++[Text]

I've been preparing a new version of Moodle for rollout at the end of July. I used git to create the main codebase (currently 2.6.3) and have added 6 modules, 3 blocks and sundry other items to round out the install. All tested with a blank database and functional.

The FreeBSD 7 server I have current access to is running php 5.4.4 and mysql 5.5.25 but no opcode cache (I am moving to a FreeBSD v10 server which will have newer versions of everything but this is 2 weeks off). When I start with the blank database the Checks page gives me a warning about INTL and Opcode cache but implies that these are optional and not show stoppers. Indeed, since this not a production system I see no need to faff about with opcode caching. The system does stall before the Plugins check page but if I close the browser tab and fire it up again it proceeds. But this is not my main problem.

Having accumulated all the code I need to use I made backups of the database and codebase just in case before loading in a mysqldump of the production moodle database. This worked fine. Normally what would now happen is that the system would start up, attempt to update the database and then make some complaints about  new tables, or Quickmail or whatever which I could fix with Phpmyadmin.

Instead the system does not even get past the first database read. Here's what gets displayed when I add debugging statements to the config.php :

''Notice: Undefined property: stdClassKc :: $cacherev in /usr/home/markp/public_html/26clmoo14/lib/modinfolib.php on line 449''

@@Error reading from database@@

Debug info: Unknown column 'cacherev' in 'field list'
{{{
SELECT id,shortname,fullname,format,enablecompletion,groupmode,groupmodeforce,cacherev FROM mdl_course WHERE id = ?
[array (
0 => '1',
)]
Error code: dmlreadexception
}}}
Stack trace:
<<<
    line 443 of /lib/dml/moodle_database.php: dml_read_exception thrown
    line 996 of /lib/dml/mysqli_native_moodle_database.php: call to moodle_database->query_end()
    line 1428 of /lib/dml/moodle_database.php: call to mysqli_native_moodle_database->get_records_sql()
    line 1400 of /lib/dml/moodle_database.php: call to moodle_database->get_record_sql()
    line 1379 of /lib/dml/moodle_database.php: call to moodle_database->get_record_select()
    line 609 of /lib/modinfolib.php: call to moodle_database->get_record()
    line 450 of /lib/modinfolib.php: call to course_modinfo::build_course_cache()
    line 411 of /lib/modinfolib.php: call to course_modinfo->_construct()
    line 2003 of /lib/modinfolib.php: call to course_modinfo::instance()
    line 1832 of /lib/navigationlib.php: call to get_fast_modinfo()
    line 1896 of /lib/navigationlib.php: call to global_navigation->generate_sections_and_activities()
    line 445 of /course/format/lib.php: call to global_navigation->load_generic_course_sections()
    line 1811 of /lib/navigationlib.php: call to format_base->extend_course_navigation()
    line 1114 of /lib/navigationlib.php: call to global_navigation->load_course_sections()
    line 222 of /blocks/navigation/block_navigation.php: call to global_navigation->initialise()
    line 178 of /blocks/navigation/block_navigation.php: call to block_navigation->get_navigation()
    line 296 of /blocks/moodleblock.class.php: call to block_navigation->get_content()
    line 238 of /blocks/moodleblock.class.php: call to block_base->formatted_contents()
    line 993 of /lib/blocklib.php: call to block_base->get_content_for_output()
    line 1045 of /lib/blocklib.php: call to block_manager->create_block_contents()
    line 361 of /lib/outputrenderers.php: call to block_manager->ensure_content_created()
    line 45 of /theme/clean/layout/columns3.php: call to core_renderer->standard_head_html()
    line 870 of /lib/outputrenderers.php: call to include()
    line 800 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
    line 101 of /index.php: call to core_renderer->header()
<<<

A quick look at the mdl_course table reveals that the field 'cacherev' is just not present. So, it seems that this has been introduced with v2.6 code.

Any ideas about how I can work around this? I have seen absolutely zero documentation about updating a 2.5 production database to 2.6 format.

Thanks

Mark
=== 

Open up the Database in Phpmysql and add a new column 'cacherev' to the table mdl_course:

{{{ALTER TABLE `mdl_course` ADD `cacherev` BIGINT(10) NOT NULL DEFAULT '0';}}}

NOW [[Problem with EvaluationKit module]]
Also with Filtered_course_list block. +++[Error]

Notice: Undefined variable: course_list in /usr/home/markp/public_html/26clmoo14/blocks/filtered_course_list/block_filtered_course_list.php on line 129
@@Error reading from database@@
Debug info: 
{{{
Unknown column 'u.firstnamephonetic' in 'field list'
SELECT u.id,u.picture,u.firstname,u.lastname,u.firstnamephonetic,u.lastnamephonetic,u.middlename,u.alternatename,u.imagealt,u.email,u.username, MAX(u.lastaccess) AS lastaccess
FROM mdl_user u
WHERE u.lastaccess > ?
AND u.lastaccess <= ?
AND u.deleted = 0
GROUP BY u.id,u.picture,u.firstname,u.lastname,u.firstnamephonetic,u.lastnamephonetic,u.middlename,u.alternatename,u.imagealt,u.email,u.username
ORDER BY lastaccess DESC LIMIT 0, 50
}}}
[array (
0 => 1405609600,
1 => 1405609975,
)]
Error code: dmlreadexception
Stack trace:
<<<
    line 443 of /lib/dml/moodle_database.php: dml_read_exception thrown
    line 996 of /lib/dml/mysqli_native_moodle_database.php: call to moodle_database->query_end()
    line 122 of /blocks/online_users/block_online_users.php: call to mysqli_native_moodle_database->get_records_sql()
    line 296 of /blocks/moodleblock.class.php: call to block_online_users->get_content()
    line 238 of /blocks/moodleblock.class.php: call to block_base->formatted_contents()
    line 993 of /lib/blocklib.php: call to block_base->get_content_for_output()
    line 1045 of /lib/blocklib.php: call to block_manager->create_block_contents()
    line 361 of /lib/outputrenderers.php: call to block_manager->ensure_content_created()
    line 45 of /theme/clean/layout/columns3.php: call to core_renderer->standard_head_html()
    line 870 of /lib/outputrenderers.php: call to include()
    line 800 of /lib/outputrenderers.php: call to core_renderer->render_page_layout()
    line 101 of /index.php: call to core_renderer->header()
<<<
=== 

And now I see that {{{u.firstnamephonetic,u.lastnamephonetic}}} are columns present in mdl_user in 2.6 which are not in 2.5 database.
Move {{{Filtered_course_list }}} block //out// of the code root and start up. Then see whether the relevant columns are created. Also move Eval_kit_sso: {{{mv evaluation_kit_sso/  ~/moo-code/2014-july}}}


Still problem with {{{mdl_user}}} columns. Print out the mdl_user structure for 2.6 and add the extra columns:
{{{
ALTER TABLE `mdl_user` ADD `lastnamephonetic` VARCHAR( 255 ) NULL DEFAULT NULL;
ALTER TABLE `mdl_user` ADD `firstnamephonetic` VARCHAR( 255 ) NULL DEFAULT NULL ,
ADD `middlename` VARCHAR( 255 ) NULL DEFAULT NULL ,
ADD `alternatename` VARCHAR( 255 ) NULL DEFAULT NULL;
ALTER TABLE `mdl_user` ADD `calandartype` VARCHAR( 30 ) NOT NULL DEFAULT 'gregorian' AFTER `lang` ;
}}}
@@WORKED@@

Now get expected +++[display]

Upgrading Moodle database from version 2.5.3 (Build: 20131111) (2013051403.00) to 2.6.3 (Build: 20140512) (2013111803.00)

Your Moodle files have been changed, and you are about to automatically upgrade your server to this version:

2.6.3 (Build: 20140512) (2013111803.00)

Once you do this you can not go back again. Please note that this process can take a long time.

Are you sure you want to upgrade this server to this version?
=== 

Now ''move back into code/blocks the filtered_course_list & Eval Kit''

Problem with +++[Editdates]>
Cannot downgrade report_editdates from 2014011700 to 2013081300.

More information about this error
Debug info:
Error code: cannotdowngrade
Stack trace:

    line 556 of /lib/upgradelib.php: downgrade_exception thrown
    line 1601 of /lib/upgradelib.php: call to upgrade_plugins()
    line 436 of /admin/index.php: call to upgrade_noncore()
=== downgrading. Looks like the version I have is //too new//
Also +++[Quickmail problem]
Capability "block/quickmail:myaddinstance" was not found! This has to be fixed in code.

    line 389 of /lib/accesslib.php: call to debugging()
    line 14 of /blocks/quickmail/block_quickmail.php: call to has_capability()
    line 331 of /blocks/moodleblock.class.php: call to block_quickmail->applicable_formats()
    line 808 of /lib/upgradelib.php: call to block_base->_self_test()
    line 420 of /lib/upgradelib.php: call to upgrade_plugins_blocks()
    line 1601 of /lib/upgradelib.php: call to upgrade_plugins()
    line 436 of /admin/index.php: call to upgrade_noncore()

block_quickmail
=== 
Problem with Database upgrading: +++[Report_editdates]
{{{
Cannot downgrade report_editdates from 2014011700 to 2013081300.

More information about this error
Debug info:
Error code: cannotdowngrade
Stack trace:

    line 556 of /lib/upgradelib.php: downgrade_exception thrown
    line 1601 of /lib/upgradelib.php: call to upgrade_plugins()
    line 436 of /admin/index.php: call to upgrade_noncore()
}}}
=== 

* [[Sussing out 2.5 to 2.6 update -- part 2]]
* [[Sussing out 2.5 to 2.6 update -- part 3]]
/***
|''Name''|TiddlySpaceConfig|
|''Version''|0.7.7|
|''Description''|TiddlySpace configuration|
|''Status''|stable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceConfig.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlyWebConfig ServerSideSavingPlugin TiddlyFileImporter|
!Code
***/
//{{{
(function($) {

var tweb = config.extensions.tiddlyweb;

var recipe = config.defaultCustomFields["server.workspace"].split("recipes/")[1];
var currentSpace; // assigned later

var disabledTabs = [];

var coreBags = ["system", "tiddlyspace"];
var systemSpaces = ["plugins", "info", "images", "theme"];
systemSpaces = $.map(systemSpaces, function(item, i) {
	return "system-%0_public".format(item);
});

// hijack search macro to add custom attributes for mobile devices
var _search = config.macros.search.handler;
config.macros.search.handler = function(place, macroName, params) {
	_search.apply(this, arguments);
	$(".searchField:input", place).
		attr({ autocapitalize: "off", autocorrect: "off" });
};

// arg is either a container name or a tiddler object
// if fuzzy is truthy, space may be inferred from workspace (for new tiddlers)
// returns space object or false
var determineSpace = function(arg, fuzzy) {
	if(typeof arg == "string") { // container name
		var space = split(arg, "_", "r");
		return ["public", "private"].contains(space.type) ? space : false;
	} else if(arg) { // tiddler
		var container = determineContainer(arg, fuzzy);
		return container ? determineSpace(container.name, fuzzy) : false;
	} else {
		return false;
	}
};

// if fuzzy is truthy, container may be inferred from workspace for new tiddlers
// returns container object or false
var determineContainer = function(tiddler, fuzzy) { // TODO: expose?
	var bag = tiddler.fields["server.bag"];
	var recipe = tiddler.fields["server.recipe"]; // XXX: unused/irrelevant/redundant!?
	if(bag) {
		return { type: "bag", name: bag };
	} else if(recipe) {
		return { type: "recipe", name: recipe };
	} else if(fuzzy) { // new tiddler
		var workspace = tiddler.fields["server.workspace"];
		if(workspace) {
			var container = split(workspace, "/", "l");
			return ["bags", "recipes"].contains(container.type) ? container : false;
		} else {
			return false;
		}
	} else {
		return false;
	}
};

// hijack removeTiddlerCallback to restore tiddler from recipe cascade -- TODO: move into TiddlyWebWiki?
var sssp = config.extensions.ServerSideSavingPlugin;
var _removeTiddlerCallback = sssp.removeTiddlerCallback;
sssp.removeTiddlerCallback = function(context, userParams) {
	var title = context.tiddler.title;
	var recipe = context.tiddler.fields["server.recipe"];
	_removeTiddlerCallback.apply(this, arguments);
	if(recipe) {
		context.workspace = "recipes/" + recipe;
		var callback = function(context, userParams) {
			if(context.status) {
				var dirty = store.isDirty();
				store.saveTiddler(context.tiddler).clearChangeCount();
				store.setDirty(dirty);
			} else {
				store.notify(title, true);
			}
		};
		context.adaptor.getTiddler(title, context, null, callback);
	}
};

// splits a string once using delimiter
// mode "l" splits at the first, "r" at the last occurrence
// returns an object with members type and name
var split = function(str, sep, mode) {
	mode = mode == "r" ? "pop" : "shift"; // TODO: use +/-1 instead of "l"/"r"?
	var arr = str.split(sep);
	var type = arr.length > 1 ? arr[mode]() : null;
	return { type: type, name: arr.join(sep) };
};

var plugin = config.extensions.tiddlyspace = {
	currentSpace: determineSpace(recipe),
	coreBags: coreBags.concat(systemSpaces),

	determineSpace: determineSpace,
	isValidSpaceName: function(name) {
		return name.match(/^[a-z][0-9a-z\-]*[0-9a-z]$/) ? true : false;
	},
	getCurrentBag: function(type) {
		return "%0_%1".format(currentSpace, type);
	},
	getCurrentWorkspace: function(type) {
		return "bags/" + this.getCurrentBag(type);
	},
	// returns the URL for a space's avatar (SiteIcon) based on a server_host
	// object and an optional space name
	// optional nocors argument prevents cross-domain URLs from being generated
	getAvatar: function(host, space, nocors) {
		if(space && typeof space != "string") { // backwards compatibility -- XXX: deprecated
			space = space.name;
		}
		var subdomain = nocors ? currentSpace : space;
		host = host ? this.getHost(host, subdomain) : "";
		var bag = space ? "%0_public".format(space) : "tiddlyspace";
		return "%0/bags/%1/tiddlers/SiteIcon".format(host, bag);
	},
	// returns the URL based on a server_host object (scheme, host, port) and an
	// optional subdomain
	getHost: function(host, subdomain) {
		if(host === undefined) { // offline
			tweb.status.server_host = {}; // prevents exceptions further down the stack -- XXX: hacky workaround, breaks encapsulation
			return null;
		}
		subdomain = subdomain ? subdomain + "." : "";
		var url = "%0://%1%2".format(host.scheme, subdomain, host.host);
		var port = host.port;
		if(port && !["80", "443"].contains(port)) {
			url += ":" + port;
		}
		return url;
	},
	disableTab: function(tabTiddler) {
		if(typeof(tabTiddler) == "string") {
			disabledTabs.push(tabTiddler);
		} else {
			for(var i = 0; i < tabTiddler.length; i++) {
				plugin.disableTab(tabTiddler[i]);
			}
		}
	},
    checkSyncStatus: function(tiddler) {
		if(tiddler) {
			var title = typeof(tiddler) === "string" ? tiddler : tiddler.title;
			var el = story.getTiddler(title) || false;
			if(el) {
				refreshElements(el);
			}
		}
	},
	isDisabledTab: function(tabTitle) {
		var match = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])", "mg").exec(tabTitle);
		var tabIdentifier = match ? match[1] : tabTitle;
		return disabledTabs.contains(tabIdentifier);
	},
	getCSRFToken: window.getCSRFToken || null // this may not have been processed yet
};

currentSpace = plugin.currentSpace.name;

tweb.serverPrefix = tweb.host.split("/")[3] || ""; // XXX: assumes root handler
tweb.getStatus(function(status) {
	var url = plugin.getHost(status.server_host);
	tweb.status.server_host.url = url;
	config.messages.tsVersion = status.version;
});

if(window.location.protocol == "file:") {
	// enable AutoSave by default
	config.options.chkAutoSave = config.options.chkAutoSave === undefined ?
		true : config.options.chkAutoSave;
} else {
	// set global read-only mode based on membership heuristics
	var indicator = store.getTiddler("SiteTitle") || tiddler;
	readOnly = !(recipe.split("_").pop() == "private" ||
		tweb.hasPermission("write", indicator));
	// replace TiddlyWiki's ImportTiddlers due to cross-domain restrictions
	if(config.macros.fileImport) {
		$.extend(config.macros.importTiddlers, config.macros.fileImport);
	}
}

// hijack saveChanges to ensure SystemSettings is private by default
var _saveChanges = saveChanges;
saveChanges = function(onlyIfDirty, tiddlers) {
	if(tiddlers && tiddlers.length == 1 &&
			tiddlers[0] && tiddlers[0].title == "SystemSettings") {
		var fields = tiddlers[0].fields;
		delete fields["server.recipe"];
		fields["server.bag"] = plugin.getCurrentBag("private");
		fields["server.workspace"] = plugin.getCurrentWorkspace("private");
	}
	return _saveChanges.apply(this, arguments);
};

// ensure backstage is always initialized
// required to circumvent TiddlyWiki's read-only based handling
config.macros.backstageInit = {
	init: function() {
		showBackstage = true;
	}
};

// disable evaluated macro parameters for security reasons
config.evaluateMacroParameters = "none";
var _parseParams = String.prototype.parseParams;
String.prototype.parseParams = function(defaultName, defaultValue, allowEval,
		noNames, cascadeDefaults) {
	if(config.evaluateMacroParameters == "none") {
		arguments[2] = false;
	}
	return _parseParams.apply(this, arguments);
};

var _tabsMacro = config.macros.tabs.handler;
config.macros.tabs.handler = function(place, macroName, params) {
	var newParams = [params[0]]; // keep cookie name
	for(var i = 1; i < params.length; i += 3) {
		var tabTitle = params[i + 2];
		if(!plugin.isDisabledTab(tabTitle)){
			newParams = newParams.concat(params[i], params[i + 1], tabTitle);
		}
	}
	_tabsMacro.apply(this, [place, macroName, newParams]);
};

// disable ControlView for XHRs by default
$.ajaxSetup({
	beforeSend: function(xhr) {
		xhr.setRequestHeader("X-ControlView", "false");
	}
});
// TiddlyWeb adaptor currently still uses httpReq, which needs extra magic -- XXX: obsolete this!
var _httpReq = httpReq;
httpReq = function(type, url, callback, params, headers, data, contentType,
		username, password, allowCache) {
	headers = headers || {};
	headers["X-ControlView"] = "false";
	_httpReq.apply(this, arguments);
};

// register style sheet for backstage separately (important)
store.addNotification("StyleSheetBackstage", refreshStyles);

// option for default privacy setting
config.optionsDesc.chkPrivateMode = "Set your default privacy mode to private";
config.optionsSource.chkPrivateMode = "setting";
config.options.chkPrivateMode = config.options.chkPrivateMode || false;
saveSystemSetting("chkPrivateMode", true);
config.defaultCustomFields["server.workspace"] = plugin.
	getCurrentWorkspace(config.options.chkPrivateMode ? "private" : "public");

config.paramifiers.follow = {
	onstart: function(v) {
		if(!readOnly) {
			var bag = "%0_public".format(currentSpace);
			story.displayTiddler(null, v, DEFAULT_EDIT_TEMPLATE, null, null,
				"server.bag:%0 server.workspace:bags/%0".format(bag));
			story.setTiddlerTag(v, "follow", 1);
			story.focusTiddler(v, "text");
		}
	}
};

var fImport = config.macros.fileImport;
if(fImport) {
	fImport.uploadTo = "Upload to: ";
	var _createForm = config.macros.fileImport.createForm;
	config.macros.fileImport.createForm = function(place, wizard, iframeName) {
		var container = $("<div />").text(fImport.uploadTo).appendTo(place);
		var select = $('<select name="mode" />').appendTo(container)[0];
		$('<option value="private" selected>private</a>').appendTo(select);
		$('<option value="public">public</a>').appendTo(select);
		wizard.setValue("importmode", select);
		_createForm.apply(this, [place, wizard, iframeName]);
	};

	var _onGet = config.macros.importTiddlers.onGetTiddler;
	config.macros.importTiddlers.onGetTiddler = function(context, wizard) {
		var type = $(wizard.getValue("importmode")).val();
		var ws =  plugin.getCurrentWorkspace(type);
		wizard.setValue("workspace", ws);
		_onGet.apply(this, [context, wizard]);
	};
}

config.extensions.ServerSideSavingPlugin.reportSuccess = function(msg, tiddler) {
	plugin.checkSyncStatus(tiddler);
	msg = config.extensions.ServerSideSavingPlugin.locale[msg];
	var link = "/" + encodeURIComponent(tiddler.title);
	displayMessage(msg.format([tiddler.title]), link);
};


})(jQuery);
//}}}
In addition to the others we have for v2.2:
* new version of [[custom corners|http://moodle.org/plugins/view.php?plugin=theme_custom_corners]]
/***
|''Name''|TiddlyWebAdaptor|
|''Description''|adaptor for interacting with TiddlyWeb|
|''Author:''|FND|
|''Contributors''|Chris Dent, Martin Budden|
|''Version''|1.4.10|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/adaptors/TiddlyWebAdaptor.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
|''Keywords''|serverSide TiddlyWeb|
!Notes
This plugin includes [[jQuery JSON|http://code.google.com/p/jquery-json/]].
!To Do
* createWorkspace
* document custom/optional context attributes (e.g. filters, query, revision) and tiddler fields (e.g. server.title, origin)
!Code
***/
//{{{
(function($) {

var adaptor = config.adaptors.tiddlyweb = function() {};

adaptor.prototype = new AdaptorBase();
adaptor.serverType = "tiddlyweb";
adaptor.serverLabel = "TiddlyWeb";
adaptor.mimeType = "application/json";

adaptor.parsingErrorMessage = "Error parsing result from server";
adaptor.noBagErrorMessage = "no bag specified for tiddler";
adaptor.locationIDErrorMessage = "no bag or recipe specified for tiddler"; // TODO: rename

// retrieve current status (requires TiddlyWeb status plugin)
adaptor.prototype.getStatus = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/status";
	var uri = uriTemplate.format([context.host]);
	var req = httpReq("GET", uri, adaptor.getStatusCallback, context,
		null, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getStatusCallback = function(status, context, responseText, uri, xhr) {
	context.status = responseText ? status : false;
	try {
		context.statusText = xhr.statusText;
	} catch(exc) { // offline (Firefox)
		context.status = false;
		context.statusText = null;
	}
	context.httpStatus = xhr.status;
	if(context.status) {
		context.serverStatus = $.evalJSON(responseText); // XXX: error handling!?
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve a list of workspaces
adaptor.prototype.getWorkspaceList = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.workspaces = [];
	var uriTemplate = "%0/recipes"; // XXX: bags?
	var uri = uriTemplate.format([context.host]);
	var req = httpReq("GET", uri, adaptor.getWorkspaceListCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getWorkspaceListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		try {
			var workspaces = $.evalJSON(responseText);
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		context.workspaces = workspaces.map(function(itm) { return { title: itm }; });
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve a list of tiddlers
adaptor.prototype.getTiddlerList = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers%3";
	var params = context.filters ? "?" + context.filters : "";
	if(context.format) {
		params = context.format + params;
	}
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), params]);
	var req = httpReq("GET", uri, adaptor.getTiddlerListCallback,
		context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.tiddlers = [];
		try {
			var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
			context.tiddlers.push(tiddler);
		}
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// perform global search
adaptor.prototype.getSearchResults = function(context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/search?q=%1%2";
	var filterString = context.filters ? ";" + context.filters : "";
	var uri = uriTemplate.format([context.host, context.query, filterString]); // XXX: parameters need escaping?
	var req = httpReq("GET", uri, adaptor.getSearchResultsCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getSearchResultsCallback = function(status, context, responseText, uri, xhr) {
	adaptor.getTiddlerListCallback(status, context, responseText, uri, xhr); // XXX: use apply?
};

// retrieve a particular tiddler's revisions
adaptor.prototype.getTiddlerRevisionList = function(title, limit, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
	var req = httpReq("GET", uri, adaptor.getTiddlerRevisionListCallback,
		context, merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerRevisionListCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.revisions = [];
		try {
			var tiddlers = $.evalJSON(responseText); //# NB: not actual tiddler instances
		} catch(ex) {
			context.status = false; // XXX: correct?
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = adaptor.toTiddler(tiddlers[i], context.host);
			context.revisions.push(tiddler);
		}
		var sortField = "server.page.revision";
		context.revisions.sort(function(a, b) {
			return a.fields[sortField] < b.fields[sortField] ? 1 :
				(a.fields[sortField] == b.fields[sortField] ? 0 : -1);
		});
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve an individual tiddler revision -- XXX: breaks with standard arguments list -- XXX: convenience function; simply use getTiddler?
adaptor.prototype.getTiddlerRevision = function(title, revision, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.revision = revision;
	return this.getTiddler(title, context, userParams, callback);
};

// retrieve an individual tiddler
//# context is an object with members host and workspace
//# callback is passed the new context and userParams
adaptor.prototype.getTiddler = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;
	if(context.revision) {
		var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions/%4";
	} else {
		uriTemplate = "%0/%1/%2/tiddlers/%3";
	}
	if(!context.tiddler) {
		context.tiddler = new Tiddler(title);
	}
	context.tiddler.fields["server.type"] = adaptor.serverType;
	context.tiddler.fields["server.host"] = AdaptorBase.minHostName(context.host);
	context.tiddler.fields["server.workspace"] = context.workspace;
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title),
		context.revision]);
	var req = httpReq("GET", uri, adaptor.getTiddlerCallback, context,
		merge({ accept: adaptor.mimeType }, context.headers), null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		try {
			var tid = $.evalJSON(responseText);
		} catch(ex) {
			context.status = false;
			context.statusText = exceptionText(ex, adaptor.parsingErrorMessage);
			if(context.callback) {
				context.callback(context, context.userParams);
			}
			return;
		}
		var tiddler = adaptor.toTiddler(tid, context.host);
		tiddler.title = context.tiddler.title;
		tiddler.fields["server.etag"] = xhr.getResponseHeader("Etag");
		// normally we'd assign context.tiddler = tiddler here - but we can't do
		// that because of IE, which triggers getTiddler in putTiddlerCallback,
		// and since ServerSideSavingPlugin foolishly relies on persistent
		// object references, we need to merge the data into the existing object
		$.extend(context.tiddler, tiddler);
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// retrieve tiddler chronicle (all revisions)
adaptor.prototype.getTiddlerChronicle = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions?fat=1";
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name), adaptor.normalizeTitle(title)]);
	var req = httpReq("GET", uri, adaptor.getTiddlerChronicleCallback,
		context, { accept: adaptor.mimeType }, null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(status) {
		context.responseText = responseText;
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store an individual tiddler
adaptor.prototype.putTiddler = function(tiddler, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = tiddler.title;
	context.tiddler = tiddler;
	context.host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var uriTemplate = "%0/%1/%2/tiddlers/%3";
	try {
		context.workspace = context.workspace || tiddler.fields["server.workspace"];
		var workspace = adaptor.resolveWorkspace(context.workspace);
	} catch(ex) {
		return adaptor.locationIDErrorMessage;
	}
	var uri = uriTemplate.format([context.host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(tiddler.title)]);
	var etag = adaptor.generateETag(workspace, tiddler);
	var headers = etag ? { "If-Match": etag } : null;
	var payload = {
		type: tiddler.fields["server.content-type"] || null,
		text: tiddler.text,
		tags: tiddler.tags,
		fields: $.extend({}, tiddler.fields)
	};
	delete payload.fields.changecount;
	$.each(payload.fields, function(key, value) {
		if(key.indexOf("server.") == 0) {
			delete payload.fields[key];
		}
	});
	payload = $.toJSON(payload);
	var req = httpReq("PUT", uri, adaptor.putTiddlerCallback,
		context, headers, payload, adaptor.mimeType, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.status) {
		var loc = xhr.getResponseHeader("Location");
		var etag = xhr.getResponseHeader("Etag");
		if(loc && etag) {
			var bag = loc.split("/bags/").pop().split("/")[0];
			context.tiddler.fields["server.bag"] = bag;
			context.tiddler.fields["server.workspace"] = "bags/" + bag;
			var rev = etag.split("/").pop().split(/;|:/)[0];
			context.tiddler.fields["server.page.revision"] = rev;
			context.tiddler.fields["server.etag"] = etag;
			if(context.callback) {
				context.callback(context, context.userParams);
			}
		} else { // IE
			context.adaptor.getTiddler(context.tiddler.title, context,
				context.userParams, context.callback);
		}
	} else if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store a tiddler chronicle
adaptor.prototype.putTiddlerChronicle = function(revisions, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = revisions[0].title;
	var headers = null;
	var uriTemplate = "%0/%1/%2/tiddlers/%3/revisions";
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(context.title)]);
	if(workspace.type == "bag") { // generate ETag
		var etag = [adaptor.normalizeTitle(workspace.name),
			adaptor.normalizeTitle(context.title), 0].join("/"); //# zero-revision prevents overwriting existing contents
		headers = { "If-Match": '"' + etag + '"' };
	}
	var payload = $.toJSON(revisions);
	var req = httpReq("POST", uri, adaptor.putTiddlerChronicleCallback,
		context, headers, payload, adaptor.mimeType, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerChronicleCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// store a collection of tiddlers (import TiddlyWiki HTML store)
adaptor.prototype.putTiddlerStore = function(store, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	var uriTemplate = "%0/%1/%2/tiddlers";
	var host = context.host;
	var workspace = adaptor.resolveWorkspace(context.workspace);
	var uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name)]);
	var req = httpReq("POST", uri, adaptor.putTiddlerStoreCallback,
		context, null, store, "text/x-tiddlywiki", null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.putTiddlerStoreCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// rename an individual tiddler or move it to a different workspace -- TODO: make {from|to}.title optional
//# from and to are objects with members title and workspace (bag; optional),
//# representing source and target tiddler, respectively
adaptor.prototype.moveTiddler = function(from, to, context, userParams, callback) { // XXX: rename parameters (old/new)?
	var self = this;
	var newTiddler = store.getTiddler(from.title) || store.getTiddler(to.title); //# local rename might already have occurred
	var oldTiddler = $.extend(true, {}, newTiddler); //# required for eventual deletion
	oldTiddler.title = from.title; //# required for original tiddler's ETag
	var _getTiddlerChronicle = function(title, context, userParams, callback) {
		return self.getTiddlerChronicle(title, context, userParams, callback);
	};
	var _putTiddlerChronicle = function(context, userParams) {
		if(!context.status) {
			return callback(context, userParams);
		}
		var revisions = $.evalJSON(context.responseText); // XXX: error handling?
		// change current title while retaining previous location
		for(var i = 0; i < revisions.length; i++) {
			delete revisions[i].revision;
			if(!revisions[i].fields.origin) { // NB: origin = "<workspace>/<title>"
				revisions[i].fields.origin = ["bags", revisions[i].bag, revisions[i].title].join("/");
			}
			revisions[i].title = to.title;
		}
		// add new revision
		var rev = $.extend({}, revisions[0]);
		$.each(newTiddler, function(i, item) {
			if(!$.isFunction(item)) {
				rev[i] = item;
			}
		});
		rev.title = to.title;
		rev.created = rev.created.convertToYYYYMMDDHHMM();
		rev.modified = new Date().convertToYYYYMMDDHHMM();
		delete rev.fields.changecount;
		revisions.unshift(rev);
		if(to.workspace) {
			context.workspace = to.workspace;
		} else if(context.workspace.substring(0, 4) != "bags") { // NB: target workspace must be a bag
			context.workspace = "bags/" + rev.bag;
		}
		var subCallback = function(context, userParams) {
			if(!context.status) {
				return callback(context, userParams);
			}
			context.adaptor.getTiddler(newTiddler.title, context, userParams, _deleteTiddler);
		};
		return self.putTiddlerChronicle(revisions, context, context.userParams, subCallback);
	};
	var _deleteTiddler = function(context, userParams) {
		if(!context.status) {
			return callback(context, userParams);
		}
		$.extend(true, newTiddler, context.tiddler);
		context.callback = null;
		return self.deleteTiddler(oldTiddler, context, context.userParams, callback);
	};
	callback = callback || function() {};
	context = this.setContext(context, userParams);
	context.host = context.host || oldTiddler.fields["server.host"];
	context.workspace = from.workspace || oldTiddler.fields["server.workspace"];
	return _getTiddlerChronicle(from.title, context, userParams, _putTiddlerChronicle);
};

// delete an individual tiddler
adaptor.prototype.deleteTiddler = function(tiddler, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = tiddler.title; // XXX: not required!?
	var uriTemplate = "%0/bags/%1/tiddlers/%2";
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var bag = tiddler.fields["server.bag"];
	if(!bag) {
		return adaptor.noBagErrorMessage;
	}
	var uri = uriTemplate.format([host, adaptor.normalizeTitle(bag),
		adaptor.normalizeTitle(tiddler.title)]);
	var etag = adaptor.generateETag({ type: "bag", name: bag }, tiddler);
	var headers = etag ? { "If-Match": etag } : null;
	var req = httpReq("DELETE", uri, adaptor.deleteTiddlerCallback, context, headers,
		null, null, null, null, true);
	return typeof req == "string" ? req : true;
};

adaptor.deleteTiddlerCallback = function(status, context, responseText, uri, xhr) {
	context.status = [204, 1223].contains(xhr.status);
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// compare two revisions of a tiddler (requires TiddlyWeb differ plugin)
//# if context.rev1 is not specified, the latest revision will be used for comparison
//# if context.rev2 is not specified, the local revision will be sent for comparison
//# context.format is a string as determined by the TiddlyWeb differ plugin
adaptor.prototype.getTiddlerDiff = function(title, context, userParams, callback) {
	context = this.setContext(context, userParams, callback);
	context.title = title;

	var tiddler = store.getTiddler(title);
	try {
		var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
	} catch(ex) {
		return adaptor.locationIDErrorMessage;
	}
	var tiddlerRef = [workspace.type + "s", workspace.name, tiddler.title].join("/");

	var rev1 = context.rev1 ? [tiddlerRef, context.rev1].join("/") : tiddlerRef;
	var rev2 = context.rev2 ? [tiddlerRef, context.rev2].join("/") : null;

	var uriTemplate = "%0/diff?rev1=%1";
	if(rev2) {
		uriTemplate += "&rev2=%2";
	}
	if(context.format) {
		uriTemplate += "&format=%3";
	}
	var host = context.host || this.fullHostName(tiddler.fields["server.host"]);
	var uri = uriTemplate.format([host, adaptor.normalizeTitle(rev1),
		adaptor.normalizeTitle(rev2), context.format]);

	if(rev2) {
		var req = httpReq("GET", uri, adaptor.getTiddlerDiffCallback, context, null,
			null, null, null, null, true);
	} else {
		var payload = {
			title: tiddler.title,
			text: tiddler.text,
			modifier: tiddler.modifier,
			tags: tiddler.tags,
			fields: $.extend({}, tiddler.fields)
		}; // XXX: missing attributes!?
		payload = $.toJSON(payload);
		req = httpReq("POST", uri, adaptor.getTiddlerDiffCallback, context,
			null, payload, adaptor.mimeType, null, null, true);
	}
	return typeof req == "string" ? req : true;
};

adaptor.getTiddlerDiffCallback = function(status, context, responseText, uri, xhr) {
	context.status = status;
	context.statusText = xhr.statusText;
	context.httpStatus = xhr.status;
	context.uri = uri;
	if(status) {
		context.diff = responseText;
	}
	if(context.callback) {
		context.callback(context, context.userParams);
	}
};

// generate tiddler information
adaptor.prototype.generateTiddlerInfo = function(tiddler) {
	var info = {};
	var uriTemplate = "%0/%1/%2/tiddlers/%3";
	var host = this.host || tiddler.fields["server.host"]; // XXX: this.host obsolete?
	host = this.fullHostName(host);
	var workspace = adaptor.resolveWorkspace(tiddler.fields["server.workspace"]);
	info.uri = uriTemplate.format([host, workspace.type + "s",
		adaptor.normalizeTitle(workspace.name),
		adaptor.normalizeTitle(tiddler.title)]);
	return info;
};

// create Tiddler instance from TiddlyWeb tiddler JSON
adaptor.toTiddler = function(json, host) {
	var created = Date.convertFromYYYYMMDDHHMM(json.created);
	var modified = Date.convertFromYYYYMMDDHHMM(json.modified);
	var fields = json.fields;
	fields["server.type"] = adaptor.serverType;
	fields["server.host"] = AdaptorBase.minHostName(host);
	fields["server.bag"] = json.bag;
	fields["server.title"] = json.title;
	if(json.recipe) {
		fields["server.recipe"] = json.recipe;
	}
	if(json.type && json.type != "None") {
		fields["server.content-type"] = json.type;
	}
	fields["server.permissions"] = json.permissions.join(", ");
	fields["server.page.revision"] = json.revision;
	fields["server.workspace"] = "bags/" + json.bag;
	var tiddler = new Tiddler(json.title);
	tiddler.assign(tiddler.title, json.text, json.modifier, modified, json.tags,
		created, json.fields, json.creator);
	return tiddler;
};

adaptor.resolveWorkspace = function(workspace) {
	var components = workspace.split("/");
	return {
		type: components[0] == "bags" ? "bag" : "recipe",
		name: components[1] || components[0]
	};
};

adaptor.generateETag = function(workspace, tiddler) {
	var revision = tiddler.fields["server.page.revision"];
	var etag = revision == "false" ? null : tiddler.fields["server.etag"];
	if(!etag && workspace.type == "bag") {
		if(typeof revision == "undefined") {
			revision = "0";
		} else if(revision == "false") {
			return null;
		}
		etag = [adaptor.normalizeTitle(workspace.name),
			adaptor.normalizeTitle(tiddler.title), revision].join("/");
		etag = '"' + etag + '"';
	}
	return etag;
};

adaptor.normalizeTitle = function(title) {
	return encodeURIComponent(title);
};

})(jQuery);


/*
 * jQuery JSON Plugin
 * version: 1.3
 * source: http://code.google.com/p/jquery-json/
 * license: MIT (http://www.opensource.org/licenses/mit-license.php)
 */
(function($){function toIntegersAtLease(n)
{return n<10?'0'+n:n;}
Date.prototype.toJSON=function(date)
{return this.getUTCFullYear()+'-'+
toIntegersAtLease(this.getUTCMonth())+'-'+
toIntegersAtLease(this.getUTCDate());};var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.quoteString=function(string)
{if(escapeable.test(string))
{return'"'+string.replace(escapeable,function(a)
{var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};$.toJSON=function(o,compact)
{var type=typeof(o);if(type=="undefined")
return"undefined";else if(type=="number"||type=="boolean")
return o+"";else if(o===null)
return"null";if(type=="string")
{return $.quoteString(o);}
if(type=="object"&&typeof o.toJSON=="function")
return o.toJSON(compact);if(type!="function"&&typeof(o.length)=="number")
{var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i],compact));}
if(compact)
return"["+ret.join(",")+"]";else
return"["+ret.join(", ")+"]";}
if(type=="function"){throw new TypeError("Unable to convert object of type 'function' to json.");}
var ret=[];for(var k in o){var name;type=typeof(k);if(type=="number")
name='"'+k+'"';else if(type=="string")
name=$.quoteString(k);else
continue;var val=$.toJSON(o[k],compact);if(typeof(val)!="string"){continue;}
if(compact)
ret.push(name+":"+val);else
ret.push(name+": "+val);}
return"{"+ret.join(", ")+"}";};$.compactJSON=function(o)
{return $.toJSON(o,true);};$.evalJSON=function(src)
{return eval("("+src+")");};$.secureEvalJSON=function(src)
{var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,'@');filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']');filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered))
return eval("("+src+")");else
throw new SyntaxError("Error parsing JSON, source is not valid.");};})(jQuery);
//}}}
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
{{{
<<activity>>
}}}
!Important
This tiddler can contain the {{{activity}}} macro which is part of the @following space.
If you want to use it, you need to go to backstage and include it.

Have a look at @@[[News|NewsMap]]@news@@
{{ts{15/06/12 11:10}}} Email to Amy, Anne, Brian and Aaron:
Chaps,
Before we go ahead and reorganize the initial look and feel of moodle 2012-13 I wanted to get your feedback on the order of display of top level categories.
Recall:
*    We're displaying courses grouped in department categories underneath semester categories -- rather than a list of courses under semesters. Why? Basically, to allow admin assistants to be enrolled as such for all courses in a department. We'll also manually move courses from the 'Crosslisted' category into appropriate department.
*    Why does the display matter when MyMoodle will display all the courses enrolled?
**        MyMoodle is a mess. People don't bother to hide courses and for some Admin Assistants (like Cheri Gaddis) who are enrolled in a lot of courses it's very hard to find to right one.
**        I think that we should not 'hide' any course categories. Faculty want to be able to see previous years courses and it involves a lot of faffing and clunky workaround to make that happen. The only reason categories are hidden is to make MyMoodle more tractable to use.
**        Solution -- Do not force MyMoodle as the default logged in screen. Instead have users see Site News and myCourses block -- with categories and courses listed in a logical order.
**        You see see only the courses you are enrolled in but they are logically ordered in year and department. This means that we can unhide all previous years courses and make them available for viewing by faculty.
**        The good thing about this is that moodle will 'remember' the myCourses setting from one session to another using a cookie if using the same browser on the same machine.
**        The MyMoodle interface will still be there -- we're planning a series of buttons at the top of the theme one of which will lead to MyMoodle.
[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/ec-moodle-front-page.png]]

The problem is that the Moodle Admin tools make it extremely hard and error prone to reorder course categories -- you can only move one at a time. We can circumvent this by modifying the appropriate entries in the mdl_course_categories table and I have sussed out and tested a sequence of SQL instructions that resort the display.

Below is the current order of display of top level categories
|id|name|parent|sortorder|
|113|EC Spring Semester, 2011-12|0|1|
|57|EC Fall Semester, 2011-12|0|2|
|56|Year 2010 - 2011|0|3|
|184|Spring MED, 2011-12|0|4|
|186|MAT Spring 2011-12|0|5|
|9|Clubs and Social (CLUB)|0|6|
|10|Committees (COMM)|0|7|
|105|Faculty Repositories|0|8|
|36|Miscellaneous (MISC)|0|9|
|104|Library|0|10|
|50|Testing (TEST)|0|11|
|190|EC Fall Semester, 2012-2013|0|999|
Here's the order which I think we should be using. I'm separating the MAT & Med courses, the Fall 2013 categories are not yet in Banner.
|id|name|parent|sortorder|
|190|EC Fall Semester, 2012-2013|0|999|
|113|EC Spring Semester, 2011-12|0|1|
|57|EC Fall Semester, 2011-12|0|2|
|184|Spring MED, 2011-12|0|4|
|186|MAT Spring 2011-12|0|5|
|56|Year 2010 - 2011|0|3|
|10|Committees (COMM)|0|7|
|9|Clubs and Social (CLUB)|0|6|
|36|Miscellaneous (MISC)|0|9|
|104|Library|0|10|
|50|Testing (TEST)|0|11|
|105|Faculty Repositories|0|8|
Reset admin password.
Originally gave blank page when logged in. Other users login fine.
deleteing cookie has no effect.
Nothing seems untoward in mdl.user table
Did hang up when changing theme from Bootstrap to decaf.
Could it be a theme thing?
Reset password with Chrome -- the password reset page came up fine (in decaf). When changed and [Continue] get error:
<<<
Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data.
<<<
So, cannot login as admin!
After reading [[slow site admin loading|https://moodle.org/mod/forum/discuss.php?d=211138]] which is a recent issue (12-Sept) with Moodle 2.3 I am starting to suspect that it may be an interaction between # courses and theme -- since it was displaying fine with the Bootstrap theme.
I've done 2 things:
# In php.ini {{{memory_limit = 256M}}}
# In config.php {{{$CFG->extramemorylimit = '512M';}}}
And restarted Apache. But eventually get the same error.
On a hunch that it's theme related I open phpmyadmin and change the default site theme in the database:
{{{
UPDATE `clam233`.`mdl_config` SET `value` = 'leatherbound' WHERE `mdl_config`.`id` =6;
}}}
Now it logs in straight away!
Change the site theme back to Decaf //and the site locks up with a blank page//!!
# of Courses = 973
# Categories = 50
More on Decaf :
{{{
$plugin->version   = 2012101708; // The current module version (Date: YYYYMMDDXX)
$plugin->release   = "1.6.8";
}}}
Also reported as [[CONTRIB-4053|http://tracker.moodle.org/browse/CONTRIB-4053]] Decaf display issue with large # courses and [[here|https://moodle.org/mod/forum/discuss.php?d=153801#p672766]]
[[Response -- problems decaf]]
/*{{{*/
.tiddler .originButton div {
	display: inline-block;
}

.tiddler .spaceSiteIcon .siteIcon {
	_display: inline; /* IE doesn't like inline-block */
}

.tiddler .originButton {
	display: block;
}

.selected .tagging,
.selected .tagging:hover {
	border: none;
	background: none;
}

.tagging {
	float: none;
	background: none;
	border: none;
}

.tagging li.listTitle {
	margin-left: 0px;
}
.tagging li {
	margin: 0 8px;
}

.tagging .tiddlyLink {
	-webkit-border-radius: 3px;
	-moz-border-radius: 3px;
	-o-border-radius: 3px;
	border-radius: 3px;
	padding: 1px 2px;
	line-height: 1.2em;
}

/* for following */
#popup .siteIcon {
	float: left;
	height: 25px;
}

.content {
	width: 100%; /* IE */
	font-size: 0.9em;
}

.editorHeading {
	height: 48px;
}

.heading {
	left: 0;
	margin-bottom: 40px;
	position: relative;
	top: 32px;
}

.followButton a {
	display: block;
	margin-top: -20px;
}

.tiddler .followPlaceHolder {
	display: block;
	position: absolute;
	top: 16px;
	right: 64px;
	_right: 138px; // add width of modifierIcon
}

.tiddler .followButton {
	position: relative;
	height: 24px;
	text-align: left;
	color: #fff;
	background: [[ColorPalette::PrimaryMid]];
	padding: 10px 0px 0px 10px;
	width: 38px;
	margin: -16px -8px 24px 0;
}

/* creates the larger triangle */
.followButton:before {
	content: "\00a0";
	display: block; /* reduce the damage in FF3.0 */
	position: relative;
	bottom: -20px;
	right: 0;
	width: 0;
	height: 0;
	border-width: 0 0 20px 20px;
	border-style: solid;
	border-color: transparent [[ColorPalette::PrimaryMid]];
}

.toolbar svg {
	height: 16px;
	width: 16px;
}

.toolbar svg .glyph {
	fill: #ccc;
}

.toolbar a:hover .glyph {
	fill: black;
}

.toolbar a:active .glyph {
	fill: [[ColorPalette::Background]];
}

.originButton,
.followPlaceHolder,
.tiddler .subtitle {
	cursor: pointer;
}

.editSpaceSiteIcon .originButton {
	cursor: auto;
}

.tiddler .subtitle:hover {
	font-weight: bold;
	background: none;
}

.originButton img,
.originButton svg {
	margin-left: 0px;
}

.modifierIcon {
	position: absolute;
	width: 74px;
	top: 0px;
	right: 0px;
	_right: 74px; /* in IE6 positioning works incorrectly so use -width instead */
	text-align: right;
}

.modifierIcon img,
.modifierIcon svg {
	margin-right: 8px;
}

.tiddler .viewer {
	padding-bottom: 16px;
	margin: 0 0 0 56px;
	line-height: 1.4em;
}

.viewer pre {
	margin-left: 0;
}

.siteIcon .label {
	color: [[ColorPalette::TertiaryDark]];
}

.tiddler .spaceSiteIcon {
	float: left;
	margin-right: 0;
	margin-top: 0;
	position: relative;
	display: block;
}

.tiddler .titleBar {
	display: block;
	margin-right: 136px;
	margin-left: 56px;
}

.followButton a {
	color: [[ColorPalette::Background]];
}

.tiddler {
	position: relative;
	padding: 0;
	margin-bottom: 3em;
	border-top: 3px solid [[ColorPalette::PrimaryMid]];
	background: #fff;
}

.tiddler .editor {
	padding: 0px 8px;
}

.tiddler .heading .title {
	position: relative;
	display: block;
	word-wrap: break-word;
	font-size: 32px;
	line-height: 32px;
}
.tiddler .heading .editor.title {
	font-size: 1.7em;
	line-height: normal;
}

.tiddler .headingClear {
	clear: both;
}

.tiddler .subtitle {
	font-style: italic;
	font-size: 0.9em;
	color: #a6a59e;
	margin-top: 0;
}

.toolbar {
	position: absolute;
	padding: 0;
	top: 8px;
	right: -8px;
}

.toolbar .moreCommand.highlight {
	background: none;
}

.tiddler .toolbar .button {
	border: none;
	display: inline;
	padding: 0px;
	margin-right: 16px;
}

.tiddler .toolbar a:hover {
	background: none;
}

.tiddler .tagged .listTitle {
	display: none;
}

.revButton {
	float: right;
}

/*! EditTemplate specific*/
.tiddler .privacySettings {
	text-align: center;
}
.tiddler .privacySettings .originButton {
	display: inline;
}

.editSpaceSiteIcon, .privacyEdit {
	float: left;
}

.editSpaceSiteIcon svg,
.editSpaceSiteIcon img,
.editSpaceSiteIcon .roundelLabel {
	float: left;
}

.tagTitle {
	position: absolute;
	text-align: center;
	width: 48px;
	top: 0px;
	left: -56px;
}

.editSpaceSiteIcon .originButton img,
.editSpaceSiteIcon .originButton svg {
	height: 16px;
	margin-left: 24px;
	margin-right: 32px;
	width: 16px;
}

.tagAnnotation {
	margin-top: 8px;
	padding-bottom: 8px;
}
.annotationsBox {
	margin-top: 8px;
}

.editorFooter {
	position: relative;
	padding: 0;
	margin-top: 16px;
	margin-left: 64px;
}

.tiddler .editorFooter .editor {
	padding-left: 0px;
}

.heading .editor input {
	width: 100%;
	font-size: 1.5em;
}

.spaceSiteIcon .externalImage .image a:hover,
.modifierIcon .externalImage .image a:hover {
	background: none;
}

div.toolbar {
	visibility:hidden;
	right:-16px;
}

.selected div.toolbar {
	visibility: visible;
}

.followButton a:hover {
	background: [[ColorPalette::PrimaryMid]];
	text-decoration: underline;
}

a.image:hover {
	background: transparent;
}

@media all and (max-device-width: 480px) {
	div.toolbar {
		visibility:visible;
	}
}
@media only screen and (device-width: 768px) {
	div.toolbar {
		visibility:visible;
	}
}
@media all and (max-width: 960px) {
	.tiddler .titleBar {
		margin-left: 36px;
		margin-right: 80px;
	}

	.tiddler .heading {
		margin-bottom: 48px;
	}

	.tiddler .heading .title {
		font-size: 32px;
		line-height: 32px;
	}

	.tiddler .modifierIcon img,
	.tiddler .modifierIcon svg,
	.tiddler .spaceSiteIcon .originButton img,
	.originButton svg {
		width: 32px;
		height: 32px;
		margin-left: 0px;
		margin-right: 0px;
	}

	.tiddler .followPlaceHolder {
		right: 48px;
	}

	.tiddler .followButton {
		width: 24px;
	}

	.tiddler .viewer {
		margin: 0px 0px 0px 36px;
		padding-top: 0;
	}

	br {
		line-height: 0.5em;
	}
}
/*}}}*/
ColorPalette
StyleSheet
SiteSubtitle
GettingStarted
SiteTitle
MainMenu
SiteIcon
DefaultTiddlers
ViewTemplate
PageTemplate
SideBarOptions
EditTemplate
SiteInfo
SideBarTabs
ToolbarCommands
<<tiddler SidebarButtons>>
/%<<closeAll>><<permaview>><<newTiddler>><<newJournal 'YYYY, DD MMM'>>
%/
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DgCANqQ7AADakO4AAGhDugMAoA3pDgCANqQ7AADakO4AAGhDugMAoA3pjtltrq2FjX9XffHMpkpXrFhlKWyV2oe6CvOdbwylW3b9F1CWVag84JDumN3kXq9uV6h1B9pxXlpLVDc70h3HFumO2WXTfXxwP+7p2t0O2us2uaLdsjsU9vbv3jbDN4rtoyff3es5fq/swGJbDrtlt5bumegvr7/k80p/uImewlGl3zdRpSH3ffNenVy9qETA0pHumF063b1XY7vj9F54CHbEsR20ZL+fPdPgMimWoJKBxbYfG2fFdLy3kPTPliXWP/vhxnpWjyr7AaUXYh9ZuFxaImAVkO6YXXu6T25KuGJ1e2IK8p8g2RnJ59X4LpJpdi9X9nC21+yyAxBuOfxvYymAZSHdMbv0XXXhq4mTukcl3SdntMrpnr3ukJ1dYjqxbh1nl51FY7pLPlDSHSuFdMfs0qdnJfvE0jPzC0v34XAqpGe0sune6wxEUQ37zi47i47H7pKSAktHumN2wriSbIF0n+/KdOP2szOdNd0br7sPpDvUId0xu/TxevUl7TniarPkrrrSP5ee7kPJTYWS9iGX2dkfPXOk++RoJT/mJMul3xxgWUh3zC67W9+UPREXtmwmH4Ly/kzv1t1G0ukYDnJygpKBJapRsbXwIvHkIDdLHgjMtg+dnohLrzgkb8VIzyKRxJN1SJQ3tkqsRCQ9lot0Bw7Rul9unJfWsgBake447o7J1dPSeR2TsgBake5A/lSzAhXxfBzKAmhFugMAoA3pDgCANqQ7AADakO4AAGhDugMAoA3pDgCANqQ7AADakO4AAGhDugMAoA3pDgCANqQ7AADakO4AAGhDugMAoA3pDgCANqQ7AADakO4AAGhDugMAoA3pDgCANqQ7AADakO4AAGhDugMAoA3pDgCANqQ7AADakO4AAGjzH+Fj7EE5geADAAAAFHpUWHRWRVJTSU9OAAB42jPUswAAASoAmF0WeZwAAAAielRYdENSRUFUT1IAAHjaC3YOcnX1C/bwD4kPDgl18fQHAC55BTYNrY6nAAAAEXpUWHRHTk9URVMAAHjaUwAAACEAISXBVbAAAAARYkJJbgIAAAAAAAAAAJ8CAABYAAAA78jRlwAAAbViQlBuiVBORw0KGgoAAAANSUhEUgAAAp8AAABYCAIAAAA8+At6AAABfElEQVR42u3VQQkAMAzAwNa/6ZoYDMKdgvyyAwC07O8AAOAxdweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgBp3B4AadweAGncHgJoDE20AWWNwICwAAAAASUVORK5CYIJ/OaoDAAAAAElFTkSuQmCC
* [[ART115:201310-P -- Context and Meaning|https://moodle.earlham.edu/course/view.php?id=2557]] in {{{Testing}}} category
* [[ART410:201310-P -- Australian Aboriginal Art|https://moodle.earlham.edu/course/view.php?id=2558]]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onclick="if(jQuery) jQuery(document).trigger('cNewJournal', {elem:this, comp:{menue:1}})" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})" title="Create a new tiddler from the current date and time">
 <metadata id="metadata14">
  <rdf:RDF>
   <cc:Work rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
    <dc:title/>
    <dc:rights>
     <cc:Agent>
      <dc:title>http://creativecommons.org/licenses/by-nc-sa/3.0/at/</dc:title>
     </cc:Agent>
    </dc:rights>
    <dc:source>http://iconbuilder.tiddlyspace.com</dc:source>
    <dc:creator>
     <cc:Agent>
      <dc:title>Mario Pietsch</dc:title>
     </cc:Agent>
    </dc:creator>
   </cc:Work>
  </rdf:RDF>
 </metadata>
 <defs id="defs_bBgTrans">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon">
 <rect id="iconBG" stroke="#696969" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" fill="none" class="showBG"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0,-1,1,0,0,0)" width="22" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showFG"/>
<g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" stroke-dasharray="none" fill="none" class="showSY">
  <path d="m21.763,50.448,8.4828-0.000001,0,3.5274,3.2858,0,0,11.126-11.769,0z" stroke-width="1.60000002"/>
  <path d="m30.795,50.25,2.8355,2.9981" stroke-width="1.28512716"/>
  <path d="m-19.945,14.462a3.0439,3.0439,0,1,1,-6.0877,0,3.0439,3.0439,0,1,1,6.0877,0z" transform="matrix(1.1526536,0,0,1.1526536,54.173325,42.898189)" stroke-width="1.04107594"/>
  <path d="m27.754,57.974,0,2.0218" stroke-width="1.20000005"/>
  <path d="m25.834,57.588,1.8711,2.3837" stroke-width="1.20000005"/>
 </g>
 <rect id="overlay" stroke="#696969" opacity="0" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" class="showOV"/>
</g>
</svg>
The title and subtitle of your space are visible to visitors and are also displayed in your browser's tabs. Click on the SiteTitle and SiteSubtitle tiddler links below to make changes.
* [[SiteTitle]]
* [[SiteSubtitle]]
!Take 1
After five years with moodle 1.9, Moodle version 2 is coming soon! At the end of this semester in fact. But don't worry, we in the Moodle Support Centre have a [[cunning plan|http://www.earlham.edu/~markp/screens/baldrick-cunning-plan.jpg]]<<imagebox>>.
+++!![Four reasons to move to Moodle 2]
# Moodle 2 is way cool with some massively useful new features -- for example, drag and drop upload of files. See tomorrow's posting for more details.
# The automatic course creation and enrollment system (LMB) won't operate much longer.
# Other plugins that we use are no longer updated since current version of Moodle (1.9) is obsolete.
# Moodle central has stopped fixing bugs or security patches for v1.9 -- which means if it breaks we cannot fix it. We simply have to move on to Moodle version 2
===
+++!![Moodle 2 Goodies]
* File management easier:
** ''Drag and drop upload'' of files to create resources. 
** Private Files section available throughout all your courses.
** Dropbox repository -- add resources straight from your Dropbox
* One multi-purpose assignment activity instead of 4 incompatible options.
* responsive theme allows you to manage your course with your iPad
* optional advanced extras such as conditional assignments
* new quiz options
* built-in browser spell check.
+++[Advanced features]
* Book -- for multiple paged content display
* Conditional Activities dependent upon prior completion of another activity.
* Better media support
* Assignment
** Single assignment activity with options
** Rubric style grading
** Submission statement -- 'this is my own work' (2.4)
** Group assignments (2.4)
** Blind marking (2.4)
** ''Offline grading'' (2.4)
** See list here : [[Moodle 2.4]]
* Peer assessment Workshop completely reformulated
===
===
+++![Timetable]
<<tiddler [[Moodle 2 Timetable]]>>
=== 
+++!![Transferring course content]
# Courses can be transferred by backup/restore process from either [[EIS Moodle 08-10|https://moodle08-10.earlham.edu:2443]] or [[Moodle10-13]]. 
# Preliminary testing has shown that all content gets moved over
** However, User details (student enrollments) and grades do not get transferred.
# The process of making course backup and restoring into new moodle2 course can be done by Teachers without Moodle Tsar intervention
# Fill out the Course Transfer Form (CTF) to request a Moodle team member to all or some of the transfer for you.
** Do you need files only but not the Course Outline? We can accommodate that too by zipping up and placing in a special System Files repository where you can get at them.
!!!Note:
* @@Don't leave it until just before the semester starts to request a course transfer!@@ There will be bottlenecks and you may not get your course content on demand.
* The course to transfer into needs to be present in the moodle system. (If this is not present there will not be a course into which a restore can take place.) Contact the Registrar's Office to make sure that your course is in Banner.
** We cannot "just create" a regular course for you since this will never have student enrollments. 
* ''However'', just as in the current Moodle, we will create a 'meta' course which can group two or more sections taught by the same instructor. 
=== 
For //Categories// rather than the current 'Sum of grades' I'd suggest using 'Simple Weighted Mean of grades' (SWM) so that you can set a max grade for each Category that totals to 100%. All the individual grade Items will then be meaned and weighted by their 'out of grade'. For example:
|!Grade Category|!Total (sum grades)|!equiv percentage|!Suggested max grade % using SWM|
|Exams | 100| 25 | 25 |
|Research project| 150| 37 | 35 |
|DD Participation | 55| 14 | 15 |
|Thought Papers | 60| 14 | 15 |
|Free writes | 40| 9 | 10 |
Moodle stuff I'm working on
!!Requested conditions
* 25 class sessions
* 22 needed for grades -- 3 sessions allowed absent
* on 2 presentation days 3 points per present.
!!Summary:
3 absences
22 present * 2 points per = 44
3 point per two presentation days = 6
TOTAL = 50
//Can we do this with a single Attendance instance?//
!!Modified approach
Yes, this can be done with a single Attendance instance with some mods.
# Absences included within the Attendance -- so 25 sessions and not 22
# Presence and presentation days get extra credit
Here's how:
!!!1. Create Attendance activity
# create in normal way. [[Add sessions|http://epress.earlham.edu/tsardocs/2013/08/01/attendance/]]. From 8/26 - 11/21 this will give 25 sessions.
# Add a setting for Allowed Absence that gives 2 grade points. You'll just give out three of these. Hit [Update][img[http://legacy.earlham.edu/~markp/screens/moodle/attendance-settings.png]] 
!!!2. Set up Categories & Items
# Create a Category called Attendance & Participation with /Simple weighted mean of grades/ and give it a Category total of 50.
# Move the Attendance activity inside this Category
# Create a Category Item called something like ''Presentation Attendance'' worth 6 points. You'll enter this grade //in the gradebook itself//. Check the Extra credit box. [img[http://legacy.earlham.edu/~markp/screens/moodle/gradebook-category-extra-credit.png]]
!!!3. Take Attendance
# The Attendance will have 3 columns for Present (P)/ Allowed Absence (AA)/ Absent (A). Make the first three absences as Allowed and anything after as Absent.
# Record attendance at Presentations separately and enter into the gradebook item called Presentation Attendance
!!!4. Typical display in Attendance & Gradebook:
* At the end of the semester, you'll get something like this in the Attendance Report : 
[img[http://legacy.earlham.edu/~markp/screens/moodle/attendance-report-all-edited.png]]
* And when added to Presentation participation it could look something like this:
[img[http://legacy.earlham.edu/~markp/screens/moodle/gradebook-extra-credit.png]]
* What the student sees in Attendance:
[img[http://legacy.earlham.edu/~markp/screens/moodle/attendance-student-view.png]]
* And the student view of the Gradebook: 
[img[http://legacy.earlham.edu/~markp/screens/moodle/attendance-gradebook-student-view.png]]

!!Final Note
You can choose not to give Presentation Attendance extra credit (uncheck the box) -- or reduce the level to 2 points per presentation session. If you do this then the Presentation Attendance will get rolled into the Simple Weighted mean of grades for the Category and overachievers won't get their extra 6 points.

<!DOCTYPE HTML>
<html>
<body style="display:none">
topics: <ul id="topics"></ul>
<button id='addtopic'>add topic</button>
stream:
<ul id="stream"></ul>
<script type='text/javascript' src='/bags/common/tiddlers/jquery.js'></script>
<script type='text/javascript' src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src="/twikifier.js" type="text/javascript" charset="utf-8"></script>
<script type='text/javascript'>
	$.ajaxSetup({
		beforeSend: function(xhr) {
			xhr.setRequestHeader("X-ControlView", "false");
		}
	});
	function renderTopic(topic) {
		var item = $("<li />").appendTo("#topics");
		$("<button class='show' />").text(topic).appendTo(item);
		$("<button class='delete'>x</button>").appendTo(item);
		return item[0];
	}
	var host =  '/';
	var space = "jon";
	var active_topics = [];
	var current_topic, offset;
	function renderTopics() {
		var topics = active_topics;
		$("#topics").empty();
		for(var i = 0; i < topics.length; i++) {
			var topic = topics[i];
			if(topic) {
				renderTopic(topic);
			}
		}
		$("body").show();
	}
	// Array Remove - By John Resig (MIT Licensed)
	Array.prototype.remove = function(from, to) {
		var rest = this.slice((to || from) + 1 || this.length);
		this.length = from < 0 ? this.length + from : from;
		return this.push.apply(this, rest);
	};

	var topicList = new tiddlyweb.Tiddler("Topics", new tiddlyweb.Bag(space + "_public", host));
	topicList.get(function(tid) {
			active_topics = tid.text.split("\n");
			renderTopics(active_topics);
			$("#topics .show:first").trigger("click");
		},
		function() {
			active_topics = ["tiddlyspace"];
			renderTopics(active_topics)
		}
	);
	$("#addtopic").click(function(ev) {
		var text = prompt("What topic would you like to watch?");
		if(active_topics.indexOf(text) === -1) {
			active_topics.push(text);
		}
		var el = renderTopic(text);
		topicList.text = active_topics.join("\n");
		topicList.put(function() {
			$("button.show", el).trigger("click");
		}, function() {
			alert("eek!")
		});
	});
	$("#topics .delete").live("click",function(ev) {
		var topic = $(".show", this.parentNode).text();
		active_topics.remove(active_topics.indexOf(topic));
		renderTopics();
		topicList.text = active_topics.join("\n");
		topicList.put(function() {}, function() {
			alert("eek!")
		});
	});
	w = createWikifier(window, jQuery, { host: host, container: "recipes/" + space + "_public" });
	$("#topics .show").live("click",function(ev) {
		var tag = $(this).text();
		current_topic = tag;
		offset = 0;
		$("#stream").empty();
		var search = new tiddlyweb.Search('tag:"' + tag + '" &fat=y', host);
		search.get(function(tiddlers) {
			for(var i = 0; i < tiddlers.length; i++) {
				var tiddler = tiddlers[i];
				var item = $("<li />").appendTo("#stream")[0];
				$("<h2 />").text(tiddler.title + ": ").appendTo(item);
				
				$("<div class='text' />").text(tiddler.text).appendTo(item);
				$("<div class='author' />").text(tiddler.modifier).appendTo(item);
			}
		}, function() {
			$("<li>no topics :-(</li>").appendTo("#stream");
		});
	});
	$(window).scroll(function(){
		if($(window).scrollTop() == $(document).height() - $(window).height()) {
			offset += 10;
			// find a way to get all tiddlers created before the ones above
			console.log("loadMore();");
		}
	});
</script>
</body>
</html>
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
/*{{{*/
[[StyleSheetTiddlySpaceMp]]

[[StyleSheetMediaPrint]]
/*}}}*/
{{ts{3/02/12 16:38}}}
From Moodle Tracker:
* [[Notices from restore when there are no files|http://tracker.moodle.org/browse/MDL-27800]]
* [[Front Page Restore does not show available backups|http://tracker.moodle.org/browse/MDL-30808]]
[tag[default]]
* +++[Email from Jana Schroeder Sep-7 :]>
I am writing because of an ongoing problem of Moodle accessibility for those of us using screen readers.  When I am in edit mode I see graphics after each resource and assignment I have posted that say things like Move Up, Move Down, Delete, Update, etc.  However, the only one of these that JAWS recognizes as a link and that I can actually act on is the Update link.  I am unable to delebe, more or even hide a resource or assignment once created.  I recall that this was not a problem a few years ago.  When I noticed it last year or the year before, you said you thought it might be an issue related to the theme that was chosen for our Moodle site.  Is that something that can be changed now or only when next year’s Moodle site is created?  What can I do to help ensure this issue gets addressed now or at the earliest possible time?:  It is difficult not being able to make these basic changes when needed.
=== Summary : in edit mode the only clickable icon is 'Update', all the others are images only.
* +++[My Response]>
Thanks for letting me know about this problem. I am more aware of issues with Jaws now that I'm working with Sejal on her Moodle courses.
The problem for me is that I have no way of testing a theme since my PC does not have Jaws and ITS has only a single licence.
But I'm going to try to get Jaws installed on my new PC when it arrives.
There's a setting in your Profile (Update Profile on the meny bar) that says 'Screen reader' Yes or No. Currently your own profile has this set to 'no'. I wonder whether setting it to 'yes' would improve matters?
=== Suggest Update Profile : Screen Reader -> Yes. Jana had problems finding this because it was hidden behind the [Show Advanced] button, so I changed it for her.
* +++[Sept 10 email]>
Thanks for changing the setting for me.  I tried editing a posted resource but still found that only update was a link that could be activated.  Any other thoughts or is this an insurmountable limitation?
=== Still problematic. I changed the Moodle site theme to a bog standard 
* I went over to Jana's office on Sept 12 and we fixed the problem. We did two things:
## In Update Profile we switched off Ajax
## We opened the moodle course in ''//firefox//'' instead of I.E (version 8) and lo and behold all the editing icons reverted to clickable!!
[[JAWS resources]]
<!--{{{-->
<div macro='slideRevision'></div>
<div class='heading'>
	<span class="titleBar">
		<div class='title' macro='view title text'></div>
	</span>
	<span class='modifierIcon'
		macro='view modifier SiteIcon label:no height:48 width:48 preserveAspectRatio:yes'>
	</span>
	<div class='toolbar'
		macro='toolbar [[ToolbarCommands::RevisionToolbar]] icons:yes height:48 width:48 more:popup'>
	</div>
	<div class='tagClear'></div>
</div>
<div class='content'>
	<div class='viewer' macro='view text wikified'></div>
</div>
<div class='tagInfo'>
	<div class='tidTags' macro='tags'></div>
	<div class='tagging' macro='tagging'></div>
</div>
<!--}}}-->
I am unsure about whether this is present by default in 2.4 or 2.5.
Tony Gardner-Medwin (UCL) pages:
* [[Certainty-Based Marking (CBM) and Moodle|http://www.tmedwin.net/cbm/moodle/]]
* [[Self-Test Scores, with and without Certainty-Based Marking, on LAPT or Moodle|http://www.ucl.ac.uk/lapt/laptlite/sys/lpscoring.htm]]
Isabelle's blog post [[Certainty Based Marking in Moodle|http://helderenwijzer.nl/2011/10/certainty-based-marking-in-moodle/]]
[[Mdl 2.3.4 Certainty Based Marking, Too harsh?|https://moodle.org/mod/forum/discuss.php?d=225920]]
Tim Hunt's forum discussion [[Quiz report averages|https://moodle.org/mod/forum/discuss.php?d=192263#p844233]]
: Tim Hunt's Tracker [[MDL-32188 Improve how CBM behaviours work|https://tracker.moodle.org/browse/MDL-32188]]. Currently ({{ts{11/07/13 14:36}}}) unworked on since Aug of 12.
/*{{{*/
Name:Automatic
Background: #e5f0e5
Foreground: #0e190f
PrimaryPale: #fcfdfc
PrimaryLight: #accfae
PrimaryMid: #4A6C4A
PrimaryDark: #000000
SecondaryPale: #fdfcfc
SecondaryLight: #cfacac
SecondaryMid: #a15d5c
SecondaryDark: #000000
TertiaryPale: #fcfcfd
TertiaryLight: #afaccf
TertiaryMid: #615ca1
TertiaryDark: #000000
/*}}}*/
Getting started with your neui-em theme, you may want to edit the following tiddlers at the layout below.
<<tiddler Layout>>
/***
|''Name''|ActivityStreamPlugin|
|''Version''|0.5.4|
|''Description''|Provides a following macro|
|''Author''|Jon Robson|
|''Requires''|TiddlySpaceFollowingPlugin|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Source''|https://github.com/jdlrobson/TiddlyWiki/raw/master/plugins/TiddlySpaceInstaller/ActivityStreamPlugin.js|
!Usage
{{{<<activity>>}}}
!!Supressing activity
You can supress notifications by  id:
"plugin", "shadow", "standard", "follow", "followYou", "siteInfo", "siteIcon", "ownSiteIcon", "notify", "reply"
e.g. {{{ <<activity supress:siteIcon>> }}} will hide siteIcon activity from you.

!!Supressing people
{{{<<activity ignore:person}}} will ignore all activity where person is the subject of the activity. eg. person followed other-person will not appear in the feed.
!!Controlling displayed dates.
{{{<<activity timestampFormat:"<0hh o' clock>" headingFormat:"0DD/0MM" >>}}} will display date headings as date/month eg.
3rd of January would be displayed as 03/01. This particular timestamp example gives you the hour of the activity.

!!Even more content
{{{<<activity limit:no>>}}} will show you all possible activity in the last X days where X is set at a macro level (advanced developers should see config.macros.activity.RECENTNESS).
!StyleSheet

.activityStream .externalImage, .activityStream .image {
	display: inline;
}

.feedItem .siteIcon {
	display: inline;
}

.activityStream .error {
	background-color: red;
	color: white;
	font-weight: bold;
}

.activityStream .feedItem {
list-style: none;
}

.activityStream .notification {
	background-color: yellow;
	color: black;
}

.activityStream .activityGroupTitle {
	font-weight: bold;
	margin-top: 8px;
}
.activityStream .feedItem {
	margin-left: 8px;
}
!Code
***/
//{{{
(function($) {
var name = "StyleSheetActivityStream";
config.shadowTiddlers[name] = store.getTiddlerText(tiddler.title +
     "##StyleSheet");
store.addNotification(name, refreshStyles);

var followMacro = config.macros.followTiddlers;
var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var scanMacro = config.macros.tsScan;

var modifierSpaceLink = "<<view modifier spaceLink>>";
var spaceTiddlyLink = "<<view server.bag spaceLink server.title>>";
var bagSpaceLink = "<<view server.bag spaceLink>>";
var bagSiteIcon = "<<view server.bag SiteIcon width:24 height:24 label:no preserveAspectRatio:yes>>";
var modifierSiteIcon = "<<view modifier SiteIcon width:24 height:24 label:no preserveAspectRatio:yes>>";
var timestamp = "[<<view modified date '0hh:0mm'>>]";
var replyLink = "<<view server.title replyLink>>";
config.shadowTiddlers.ActivityStreamTemplates = [
	"!notify\n%3 {{notification{%0 %1 has modified %2 in %0 %1 and flagged it for your attention!}}} %8\n",
	"!reply\n%3 {{notification{%0 %1 replied with %2 to your %4 %5 post.}}} %8\n",
	"!userSiteIcon\n%3 %6 %7 has a new ~SiteIcon.\n",
	"!spaceSiteIcon\n%3 %6 %7 updated the SiteIcon for the %0 %1 space.\n",
	"!image\n%3 %6 %7 drew the image %2 in the %1 space.\n",
	"!plugin\n%3 %6 %7 modified a plugin called %2 in the %0 %1 space.\n",
	"!shadow\n%3 %6 %7 modified a shadow tiddler %2 in the %0 %1 space.\n",
	"!geo\n%3 %6 %7 modified a geo tiddler called %2 in the %0 %1 space <<view title maplink 'view on map'>>. %8\n",
	"!followYou\n%3 %0 %1 is now following you.\n",
	"!follow\n%3 %0 %1 is now following %4 %5 <<view server.title link follow>>\n",
	"!siteInfo\n%3 %6 %7 <<view server.bag spaceLink server.title label:described>> the %0 %1 space.\n",
	"!video\n%3 %6 %7 modified a video entitled %2 in the %0 %1 space. %8\n",
	"!standard\n%3 %6 %7 modified %2 in the %0 %1 space. %8\n"
	].join("").format(bagSiteIcon, bagSpaceLink, spaceTiddlyLink, timestamp,
		"<<view server.title SiteIcon width:24 height:24 label:no preserveAspectRatio:yes>>", "<<view server.title spaceLink>>",
		modifierSiteIcon, modifierSpaceLink, replyLink);
story.refreshTiddler("ActivityStreamTemplates", null, true);
config.annotations.ActivityStreamTemplates = "This is a special tiddler used by the ActivityStreamPlugin. It is used for templating notifications. Templates at the top have preference over templates at the bottom.";

var macro = config.macros.activity = {
	default_limit: 50,
	templates: [],
	init: function() {
		var templates = [];
		var regex = new RegExp(/^!(.*)\n/gm);
		var text = store.getTiddlerText("ActivityStreamTemplates");
		var match = regex.exec(text);
		while(match) {
			templates.push(match[1]);
			match = regex.exec(text);
		}
		macro.templates = templates;
	},
	// order matters - earlier templates override older ones
	RECENTNESS: 2, // in days
	TIMESTAMP_FORMAT: "<0hh:0mm>",
	info: {},
	locale: {
		pleaseWait: "please wait while we load your stream...",
		errorLoading: "The activity stream failed to load. Please make sure you have an internet connection and try again.",
		userHeading: "Below is the activity stream for spaces that this space follows with the follow tag. (%0/%1 spaces have been loaded)",
		emptyStream: "Activity stream currently empty. (%0/%1 loaded)"
	},
	getTimeStamp: function() {
		var today = new Date();
		macro._lastRun = today.getTime();
		var previous = new Date(today.setDate(today.getDate() - macro.RECENTNESS));
		return previous.convertToYYYYMMDDHHMM();
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var container = $("<div />").text(macro.locale.pleaseWait).appendTo(place).
			attr("refresh", "macro").attr("macroName", macroName).attr("paramString", paramString);
		var space = tiddlyspace.currentSpace.name;
		var options = macro.getOptions(paramString);
		$(container).attr("activity-limit", options.limit);
		macro._session = Math.random();
		var activityType;
		var sourceActivity = function(user) {
			macro.CURRENT_USER = user.name;
			macro.USER_AT_TAG = "@%0".format(user.name);
			followMacro.getFollowers(function(users) {
				macro.getActivity(container, users, activityType, options);
			}, macro.CURRENT_USER);
			container.attr("activity-type", activityType);
			macro._renderStream(container, activityType, options);
		};

		if(options.user) {
			sourceActivity({name: options.user});
		} else {
			sourceActivity({ name: tiddlyspace.currentSpace.name });
		}
	},
	getOptions: function(paramString) {
		var options = {};
		var args = paramString.parseParams("name")[0];
		var toMap = ["timestampFormat", "headingFormat", "limit", "user"];
		var i;
		for(i = 0; i < toMap.length; i++) {
			var map = toMap[i];
			options[map] = args[map] ? args[map][0] : false;
		}
		var supress = args.supress || [];
		var templates = [];
		var show = args.show ? args.show : macro.templates;
		for(i = 0; i < show.length; i++) {
			var template = show[i];
			if(supress.indexOf(template) === -1) {
				templates.push(template);
			}
		}
		options.ignore = args.ignore || [];
		options.templates = templates;
		return options;
	},
	_getActivityQuery: function(user, timestamp) {
		timestamp = timestamp || macro.getTimeStamp();
		if(user) {
			return "/bags/%0_public/tiddlers?select=modified:>%1".format(user, timestamp);
		} else {
			return false;
		}
	},
	refresh: function(container) {
		var type = $(container).attr("activity-type");
		var limit = $(container).attr("activity-limit");
		var options = macro.getOptions($(container).attr("paramString"));
		options.limit = parseInt(limit, 10);
		macro.renderStream(container, type, options);
	},
	getActivity: function(place, users, type, options) {
		var i;
		var timestamp = macro.activityTimestamp;
		var firstRun =  timestamp ? false : true;
		macro.info.loaded = firstRun ? 0 : macro.info.loaded;
		var afterAjax = function(tiddlers) {
			if(firstRun) {
				macro.info.loaded += 1;
			}
			macro.updateStream(tiddlers, type, options);
			macro.renderStream(place, type, options);
		};
		var success = function(tiddlers) {
			afterAjax(tiddlers);
		};
		var error = function() {
			afterAjax([]);
		};
		if(macro._lastRun > new Date().getTime() - 300000) { // leave 5 minutes between calls
			afterAjax([]);
			return;
		}
		macro.info.queries = users.length;
		for(i = 0; i < users.length; i++) {
			var user = users[i];
			ajaxReq({
				url: macro._getActivityQuery(user, timestamp),
				dataType: "json", success: success, error: error
			});
		}
		macro.activityTimestamp = new Date().convertToYYYYMMDDHHMM();
	},
	reportError: function(place) {
		var error = $("<div />").addClass("error").text(locale.errorLoading);
		$(place).empty().append(error);
	},
	createFeedEntry: function(container, tiddler, options) {
		var item = $("<li />").addClass("feedItem");
		var content = $("<div />").appendTo(item);
		var wikifyPlace = $("<span />").appendTo(content)[0];
		var author = tiddler.modifier;
		if(author && !options.ignore.contains(author)) {
			$(container).append(item);
			config.macros.view.views.activityItem(null, wikifyPlace, null, null, null, tiddler);
			return item;
		}
		return false;
	},
	renderStream: function(place, type, options) {
		window.clearTimeout(macro._renderTimeout);
		macro._renderTimeout = window.setTimeout(function() {
			macro._renderStream(place, type, options);
		}, 100);
	},
	_renderStream: function(place, type, options) {
		$(place).empty();
		var limit = options.limit;
		var container = $("<ul />").addClass("activityStream").appendTo(place);
		var textHeading = macro.locale.userHeading.format(macro.info.loaded, macro.info.queries);
		$("<li />").addClass("listTitle").text(textHeading).appendTo(container);
		var tiddlers = store.sortTiddlers(store.filterTiddlers("[server.activity[true]]"), "-modified"); // TODO: sort headings instead if possible (conflicts with limit)
		var headings = [];
		var groups = {};
		var processed = 0, i, j;
		var atEndOfActivityFeed = true;
		for(i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			if(options.templates.contains(tiddler.fields["server.activity.type"])) {
				if(!limit || processed < limit) {
					var modified = tiddler.modified;
					if(modified) {
						// format date.
						var modifiedString = modified.formatString(options.headingFormat || config.macros.timeline.dateFormat);
						if(headings.contains(modifiedString)) {
							groups[modifiedString].push(tiddler);
						} else {
							headings.push(modifiedString);
							groups[modifiedString] = [ tiddler ];
						}
					}
					processed += 1;
				} else {
					atEndOfActivityFeed = false;
				}
			}
		}
		var somethingRendered;
		for(i = 0; i < headings.length; i++) {
			var heading = headings[i];
			var _tiddlers = store.sortTiddlers(groups[heading], "-modified");
			var headingEl;
			if(_tiddlers.length > 0) {
				headingEl = $("<li />").addClass("listTitle activityGroupTitle").text(heading).appendTo(container);
			}
			var rendered = [];
			for(j = 0; j < _tiddlers.length; j++) {
				var item = macro.createFeedEntry(container, _tiddlers[j], options);
				if(item) {
					rendered.push(item);
				}
			}
			if(rendered.length === 0) {
				headingEl.remove();
			} else {
				somethingRendered = true;
			}
		}
		if(!somethingRendered) {
			var msg;
			if(macro.gotActivity) { // it has been run before
				msg = macro.locale.emptyStream.format(macro.info.loaded, macro.info.queries);
			} else {
				msg = macro.locale.pleaseWait;
			}
			$(container).text(msg);
		}
		if(!atEndOfActivityFeed) { // show more button
			$("<input />").attr("type", "button").val("more").click(function(ev) {
				var currentLimit = $(place).attr("activity-limit");
				var newLimit = parseInt(currentLimit, 10) + 50;
				macro.default_limit = newLimit;
				$(place).attr("activity-limit", newLimit);
				macro.refresh(place);
			}).appendTo(place);
		}
		this.gotActivity = true;
	},
	updateStream: function(jstiddlers, type, options) {
		// assume already sorted.
		var tiddlers = scanMacro._tiddlerfy(jstiddlers, options);
		var _dirty = store.isDirty();
		$.each(tiddlers, function(i, tid) {
			var info = config.macros.view.activity.getActivityInfo(tid, options);
			tid.fields["server.activity.type"] = info.type;
			tid.fields["server.activity"] = "true";
			if(!tid.tags.contains("excludeLists")) {
				tid.title = tiddlyspace.getLocalTitle(tid.title, tid.fields["server.workspace"]);
				tid.tags = tid.tags.concat(["excludeLists", "excludeMissing", "excludeSearch"]);
				tid.fields.doNotSave = "true";
				store.addTiddler(tid); // save caused unsaved changes alert and slowdown
			}
		});
		store.setDirty(_dirty);
	}
};

config.macros.view.views.activityItem = function(value, place, params, wikifier,
	paramString, tiddler) {
	var info = config.macros.view.activity.getActivityInfo(tiddler, {});
	wikify(info.template, place, null, tiddler);
};

var helper = config.macros.view.activity = {
	_isNotification: function(tiddler) {
		return tiddler.tags.contains(macro.USER_AT_TAG) || tiddler.tags.contains("@all");
	},
	_repliesOn: function() {
		return tiddlyspace.currentSpace.name === macro.CURRENT_USER;
	},
	types: {
		video: function(tiddler) {
			return tiddler.tags.contains("video");
		},
		geo: function(tiddler) {
			return tiddler.fields["geo.lat"] && tiddler.fields["geo.long"];
		},
		siteInfo: function(tiddler) {
			var title = tiddler.fields["server.title"];
			return title === "SiteInfo";
		},
		userSiteIcon: function(tiddler) {
			var modifierBag = "%0_public".format(tiddler.modifier);
			var title = tiddler.fields["server.title"];
			return title === "SiteIcon" && modifierBag === tiddler.fields["server.bag"];
		},
		spaceSiteIcon: function(tiddler) {
			var title = tiddler.fields["server.title"];
			return title === "SiteIcon"; // note userSiteIcon above does the bag check
		},
		shadow: function(tiddler) {
			var title = tiddler.fields["server.title"];
			return title in config.shadowTiddlers;
		},
		plugin: function(tiddler) {
			return tiddler.tags.contains("systemConfig");
		},
		followYou: function(tiddler) {
			var title = tiddler.fields["server.title"];
			title = title.indexOf("@") === 0 ? title.substr(1) : title;
			return tiddler.tags.contains("follow") && title === macro.USER_AT_TAG;
		},
		follow: function(tiddler) {
			return tiddler.tags.contains("follow");
		},
		reply: function(tiddler) {
			var title = tiddler.fields["server.title"];
			var myTiddler = store.getTiddler(tiddler.title);
			var myTiddlerIsOlder = myTiddler && myTiddler.modified < tiddler.modified;
			return store.tiddlerExists(title) && myTiddlerIsOlder && helper._repliesOn(tiddler);
		},
		notify: function(tiddler) {
			var title = tiddler.fields["server.title"];
			var myTiddler = store.getTiddler(title);
			var myTiddlerIsNewer = myTiddler && myTiddler.modified > tiddler.modified;
			return helper._isNotification(tiddler) && helper._repliesOn(tiddler) && !myTiddlerIsNewer;
		},
		standard: function(tiddler) {
			return true;
		},
		image: function(tiddler) {
			return config.macros.image.isImageTiddler(tiddler);
		}
	},
	// each type should point to a slice in ActivityStreamTemplates tiddler
	getActivityInfo: function(tiddler, options) {
		var repliesOn = tiddlyspace.currentSpace.name === macro.CURRENT_USER;
		var activityType, i;
		if(tiddler) {
			for(i = 0; i < macro.templates.length; i++) {
				var type = macro.templates[i];
				if(!activityType && helper.types[type]) {
					if(helper.types[type](tiddler)) {
						activityType = type;
					}
				}
			}
		}
		template = store.getTiddlerText("ActivityStreamTemplates##" + activityType) || locale.standardTemplate;
		return activityType ? { template: template, type: activityType } : false;
	}
};

config.macros.view.views.link = function(value, place, params, wikifier,
		paramString, tiddler) {
		var el = createTiddlyLink(place,value,true);
		if(params[2]) {
			$(el).text(params[2]);
		}
};

config.macros.view.views.maplink = function(value, place, params, wikifier,
		paramString, tiddler) {
		var lat = tiddler.fields["geo.lat"];
		var lng = tiddler.fields["geo.long"];
		var label  = params[2] || value;
		if(lat && lng) {
			$("<a />").attr("href", "http://maps.google.com/maps?saddr=%0,%1".format(lat, lng)).text(label).appendTo(place);
		}
};

var _displayS = tiddlyspace.displayServerTiddler;
tiddlyspace.displayServerTiddler = function(src, title, workspace, callback) {
	var localTitle = tiddlyspace.getLocalTitle(title, workspace);
	var localTiddler = store.getTiddler(localTitle);

	var _callback = function(src, tiddler) {
		if(callback) {
			callback(src, tiddler);
		}
		if(localTiddler) {
			tiddler.fields["server.activity"] = "true";
			tiddler.fields["server.activity.type"] = localTiddler.fields["server.activity.type"];
		}
	};
	return _displayS.apply(this, [ src, title, workspace, _callback ]);
};
}(jQuery));
//}}}
!!Format for each workshop session:
# Spiel -- intro to topic
# Demonstration
# Class assignment practicing the topic
# Participant applies and adapts topic to own course
/***
|''Name''|TiddlySpacePublishingCommands|
|''Version''|0.8.5|
|''Status''|@@beta@@|
|''Description''|toolbar commands for drafting and publishing|
|''Author''|Jon Robson|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpacePublishingCommands.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig TiddlySpaceFilters|
!Usage
Provides changeToPrivate, changeToPublic and saveDraft commands
Provides TiddlySpacePublisher macro.
{{{<<TiddlySpacePublisher type:private>>}}} make lots of private tiddlers public.
{{{<<TiddlySpacePublisher type:public>>}}} make lots of public tiddlers public.
!TODO
* add public argument?
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var originMacro = config.macros.tiddlerOrigin;

tiddlyspace.getTiddlerStatusType = function(tiddler) {
	var isShadow = store.isShadowTiddler(tiddler.title);
	var exists = store.tiddlerExists(tiddler.title);
	if(isShadow && !exists) {
		return "shadow";
	} else if(!exists) {
		return "missing";
	} else {
		var types = ["private", "public"];
		var type = "external";
		for(var i = 0; i < types.length; i++) {
			var t = types[i];
			type = config.filterHelpers.is[t](tiddler) ? t : type;
		}
		if(config.filterHelpers.is.unsynced(tiddler)) {
			type = type == "private" ? "unsyncedPrivate" : "unsyncedPublic";
		}
		return type;
	}
};

var cmd = config.commands.publishTiddler = {
	text: "make public",
	tooltip: "Change this private tiddler into a public tiddler",
	errorMsg: "Error publishing %0: %1",

	isEnabled: function(tiddler) {
		return !readOnly && config.filterHelpers.is["private"](tiddler);
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		if(tiddler) {
			var newBag = cmd.toggleBag(tiddler.fields["server.bag"]);
			this.moveTiddler(tiddler, {
				title: tiddler.fields["publish.name"] || tiddler.title,
				fields: { "server.bag": newBag }
			});
		}
	},
	toggleBag: function(bag, to) {
		var newBag;
		if(typeof bag != typeof "") {
			var tiddler = bag;
			bag = tiddler.fields["server.bag"];
		}
		if(bag.indexOf("_private") > -1) { // should make use of endsWith
			to = to ? to : "public";
			newBag = bag.replace("_private", "_" + to);
		} else {
			to = to ? to : "private";
			newBag = bag.replace("_public", "_" + to);
		}
		return newBag;
	},
	copyTiddler: function(title, newTitle, newBag, callback) {
		var original = store.getTiddler(title);
		newTitle = newTitle ? newTitle : title;
		var adaptor = original.getAdaptor();
		var publish = function(original, callback) {
			var tiddler = $.extend(new Tiddler(newTitle), original);
			tiddler.fields = $.extend({}, original.fields, {
				"server.bag": newBag,
				"server.workspace": "bags/%0".format(newBag),
				"server.page.revision": "false"
			});
			delete tiddler.fields["server.title"];
			tiddler.title = newTitle;
			adaptor.putTiddler(tiddler, null, null, callback);
		};
		publish(original, callback);
	},
	moveTiddler: function(tiddler, newTiddler, callback) {
			var info = {
			copyContext: {},
			deleteContext: {}
		};
		var _dirty = store.isDirty();
		var adaptor = tiddler.getAdaptor();
		var newTitle = newTiddler.title;
		var oldTitle = tiddler.title;
		delete tiddler.fields["server.workspace"];
		var oldBag = tiddler.fields["server.bag"];
		var newBag = newTiddler.fields["server.bag"];
		var newWorkspace = "bags/%0".format(newBag);
		cmd.copyTiddler(oldTitle, newTitle, newBag, function(ctx) {
				info.copyContext = ctx;
				var context = {
					tiddler: tiddler,
					workspace: newWorkspace
				};
				store.addTiddler(ctx.tiddler);
				tiddler.title = oldTitle; // for cases where a rename occurs
				if(ctx.status) { // only do if a success
					if(oldBag != newBag) {
						adaptor.deleteTiddler(tiddler, context, {}, function(ctx) {
							info.deleteContext = ctx;
							var el;
							if(tiddler) {
								tiddler.fields["server.workspace"] = newWorkspace;
								tiddler.fields["server.bag"] = newBag;
							}
							el = el ? el : story.refreshTiddler(oldTitle, null, true);
							if(oldTitle != newTitle) {
								store.deleteTiddler(oldTitle);
								store.notify(oldTitle, true);
							}
							if(el) {
								story.displayTiddler(el, newTitle);
							}
							if(oldTitle != newTitle) {
								story.closeTiddler(oldTitle);
							}
							if(callback) {
								callback(info);
							}
							store.setDirty(_dirty);
						});
					} else {
						if(callback) {
							callback(info);
						}
					}
					refreshDisplay();
				}
		});
	}
};

var changeToPrivate = config.commands.changeToPrivate = {
	text: "make private",
	tooltip: "turn this public tiddler into a private tiddler",
	isEnabled: function(tiddler) {
		return !readOnly && config.filterHelpers.is["public"](tiddler);
	},
	handler: function(event, src, title) {
		var tiddler = store.getTiddler(title);
		var newBag = cmd.toggleBag(tiddler, "private");
		var newTiddler = { title: title, fields: { "server.bag": newBag }};
		cmd.moveTiddler(tiddler, newTiddler);
	}
};
config.commands.changeToPublic = cmd;

/* Save as draft command */
var saveDraftCmd = config.commands.saveDraft = {
	text: "save draft",
	tooltip: "Save as a private draft",
	isEnabled: function(tiddler) {
		return changeToPrivate.isEnabled(tiddler);
	},
	getDraftTitle: function(title) {
		var draftTitle;
		var draftNum = "";
		while(!draftTitle) {
			var suggestedTitle = "%0 [draft%1]".format(title, draftNum);
			if(store.getTiddler(suggestedTitle)) {
				draftNum = !draftNum ? 2 : draftNum + 1;
			} else {
				draftTitle = suggestedTitle;
			}
		}
		return draftTitle;
	},
	createDraftTiddler: function(title, gatheredFields) {
		var tiddler = store.getTiddler(title);
		var draftTitle = saveDraftCmd.getDraftTitle(title);
		var draftTiddler = new Tiddler(draftTitle);
		if(tiddler) {
			$.extend(true, draftTiddler, tiddler);
		} else {
			$.extend(draftTiddler.fields, config.defaultCustomFields);
		}
		for(var fieldName in gatheredFields) {
			if(TiddlyWiki.isStandardField(fieldName)) {
				draftTiddler[fieldName] = gatheredFields[fieldName];
			} else {
				draftTiddler.fields[fieldName] = gatheredFields[fieldName];
			}
		}
		var privateBag = tiddlyspace.getCurrentBag("private");
		var privateWorkspace = tiddlyspace.getCurrentWorkspace("private");
		draftTiddler.title = draftTitle;
		draftTiddler.fields["publish.name"] = title;
		draftTiddler.fields["server.workspace"] = privateWorkspace;
		draftTiddler.fields["server.bag"] = privateBag;
		draftTiddler.fields["server.title"] = draftTitle;
		draftTiddler.fields["server.page.revision"] = "false";
		delete draftTiddler.fields["server.etag"];
		return draftTiddler;
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title); // original tiddler
		var tidEl = story.getTiddler(title);
		var uiFields = {};
		story.gatherSaveFields(tidEl, uiFields);
		var tid = saveDraftCmd.createDraftTiddler(title, uiFields);
		tid = store.saveTiddler(tid.title, tid.title, tid.text, tid.modifier,
			new Date(), tid.tags, tid.fields);
		autoSaveChanges(null, [tid]);
		story.closeTiddler(title);
		story.displayTiddler(src, title);
		story.displayTiddler(src, tid.title);
	}
};

var macro = config.macros.TiddlySpacePublisher = {
	locale: {
		title: "Batch Publisher",
		changeStatusLabel: "Make %0",
		noTiddlersText: "No tiddlers to publish",
		changeStatusPrompt: "Make all the selected tiddlers %0.",
		description: "Change tiddlers from %0 to %1 in this space"
	},

	listViewTemplate: {
		columns: [
			{ name: "Selected", field: "Selected", rowName: "title", type: "Selector" },
			{ name: "Tiddler", field: "tiddler", title: "Tiddler", type: "Tiddler" },
			{ name: "Status", field: "status", title: "Status", type: "WikiText" }
		],
		rowClasses: []
	},

	changeStatus: function(tiddlers, status, callback) { // this is what is called when you click the publish button
		var publicBag;
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var newTiddler = {
				title: tiddler.title,
				fields: { "server.bag": cmd.toggleBag(tiddler, status) }
			};
			cmd.moveTiddler(tiddler, newTiddler, callback);
		}
	},
	getMode: function(paramString) {
		var params = paramString.parseParams("anon")[0];
		var status = params.type ?
			(["public", "private"].contains(params.type[0]) ? params.type[0] : "private") :
			"private";
		var newStatus = status == "public" ? "private" : "public";
		return [status, newStatus];
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var wizard = new Wizard();
		var locale = macro.locale;
		var status = macro.getMode(paramString);
		wizard.createWizard(place, locale.title);
		wizard.addStep(macro.locale.description.format(status[0], status[1]),
			'<input type="hidden" name="markList" />');
		var markList = wizard.getElement("markList");
		var listWrapper = $("<div />").addClass("batchPublisher").
			attr("refresh", "macro").attr("macroName", macroName).
			attr("params", paramString)[0];
		markList.parentNode.insertBefore(listWrapper, markList);
		$.data(listWrapper, "wizard", wizard);
		macro.refresh(listWrapper);
	},
	getCheckedTiddlers: function(listWrapper, titlesOnly) {
		var tiddlers = [];
		$(".chkOptionInput[rowName]:checked", listWrapper).each(function(i, el) {
			var title = $(el).attr("rowName");
			if(titlesOnly) {
				tiddlers.push(title);
			} else {
				tiddlers.push(store.getTiddler(title));
			}
		});
		return tiddlers;
	},
	refresh: function(listWrapper) {
		var checked = macro.getCheckedTiddlers(listWrapper, true);
		var paramString = $(listWrapper).empty().attr("params");
		var wizard = $.data(listWrapper, "wizard");
		var locale = macro.locale;
		var params = paramString.parseParams("anon")[0];
		var publishCandidates = [];
		var status = macro.getMode(paramString);
		var pubType = status[0];
		var newPubType = status[1];
		var tiddlers = params.filter ? store.filterTiddlers(params.filter[0]) :
			store.filterTiddlers("[is[%0]]".format(pubType));
		var enabled = [];
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var title = tiddler.title;
			if(!tiddler.tags.contains("excludePublisher") && title !== "SystemSettings") {
				publishCandidates.push({ title: title, tiddler: tiddler, status: pubType});
			}
			if(checked.contains(title)) {
				enabled.push("[rowname=%0]".format(title));
			}
		}

		if(publishCandidates.length === 0) {
			createTiddlyElement(listWrapper, "em", null, null, locale.noTiddlersText);
		} else {
			var listView = ListView.create(listWrapper, publishCandidates, macro.listViewTemplate);
			wizard.setValue("listView", listView);
			var btnHandler = function(ev) {
				var tiddlers = macro.getCheckedTiddlers(listWrapper);
				var callback = function(status) {
					$(".batchPublisher").each(function(i, el) {
						macro.refresh(el);
					});
				};
				macro.changeStatus(tiddlers, newPubType, callback);
			};
			wizard.setButtons([{
				caption: locale.changeStatusLabel.format(newPubType),
				tooltip: locale.changeStatusPrompt.format(newPubType),
				onClick: btnHandler
			}]);
			$(enabled.join(",")).attr("checked", true); // retain what was checked before
		}
	}
};

})(jQuery);
//}}}
Have a look at @freestyle
!Spaces
<<groupBy server.bag>>

!Private
<<list filter [is[private]]>>

!Public
<<list filter [is[public]]>>

!Drafts
<<list filter [is[draft]]>>
Fill in this form and add your own comments.
Date completed :
Date revised :
!!Basic class information
Moodle long name for class :
Moodle shortname for class:
Year / level (1st, 2nd, 3rd or 4th year class) :
Approx # students enrolled (if known) :
Estimated ability of students (being honest) :
T.A ? :
!!Desired Learning Outcomes
Enter the top three learning outcomes you would like to achieve with this course
#
#
#
!!Assessment options
Make a list of the types of assessment you're planning to use and how much each is worth of the total grade
|!#|!Assessment|!Use this?|!# instances|!% of total grade|!Comments|
| 1|Essay/Paper| | | | |
| 2|Research paper (long)| | | | |
| 3|Quiz| | | | |
| 4|Project (group/individual)| | | | |
| 5|Lab/ Field work| | | | |
| 6|Lead class discussion/class presentation| | | | |
| 7|Class Participation| | | | |
| 8|Class Attendance| | | | |
| 9|fill in: | | | | |
| 10|fill in: | | | | |

!!Course Management Features
Use these to make your life easier managing the course:
|!Moodle feature|!Use this? (Y/N)|!Comments|
|News Forum| | |
|Quickmail| | |
|Gradebook| | |
|Reports| | |

!!Student Helps
Which of these do you plan to use?
|!Moodle feature|!Use this? (Y/N)|!Comments|
|Grades delivered promptly online| | |
|Feedback from assignments| | |
|Progress Bar to track progress with readings and activities| | |
|Active participation in online Help forum| | |

!!Course Material
Which of these kinds of course material are you considering?
|!Item|!Format|!Use this? (Y/N)|!Quantity|!Comments|
|Scanned material (papers, chapters, excerpts)|pdf | | | |
|Links to Library, web, wikipedia resources|URL  | | | |
|Media resources (audio/video) |mp3, mp4, ~YouTube link  | | | |
|Personalized resources (instructions, slide show, etc)|word,ppt,prezi  | | | |
|Local web pages|  | | | |
|Blog posts/pages| | | | |
|RSS feeds|  | | | |
|Other content delivery options (eg ''book'', lesson)|  | | | |

!!Pedagogical Activities
Match the assessment option you listed above to the nearest moodle feature.
|!moodle feature|!Assessment equivalent|!Frequency use (eg n/week)|!Total number|!% grade|!Comments|
|Assignment : offline| | | | | |
|Assignment : online| | | | | |
|Assignment : File upload| | | | | |
|Quiz : multiple choice| | | | | |
|Quiz : short answer| | | | | |
|Forum : respond to prompt| | | | | |
|Forum : initiate discussion| | | | | |
|Forum : Q&A thoughtful response| | | | | |
|Forum : group work| | | | | |
|~OUWiki : project| | | | | |
|Glossary | | | | | |
|Peer assessment Workshop| | | | | |
|Other | | | | | |
/***
|''Name''|TiddlySpaceBackstage|
|''Version''|0.8.0|
|''Description''|Provides a TiddlySpace version of the backstage and a homeLink macro|
|''Status''|@@beta@@|
|''Contributors''|Jon Lister, Jon Robson, Colm Britton|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceBackstage.js|
|''Requires''|TiddlySpaceConfig ImageMacroPlugin TiddlySpaceViewTypes|
!StyleSheet
.tiddler .error.annotation .button{
	display: inline-block;
}

#backstageArea {
	z-index: 49;
	color: white;
	background-color: black;
	background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #222),color-stop(0.5, #333),color-stop(1, #555));
	background: -moz-linear-gradient(center bottom,#222 0%, #333 50%, #555 100%);
	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222);
	-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff555555, endColorstr=#ff222222)";
	height: 25px;
	padding: 0;
}

#backstageButton {
	overflow: hidden;
}

#backstageButton #backstageShow,
#backstageButton #backstageHide {
	margin: 0px;
	padding: 0px;
}

#backstageButton #backstageShow:hover,
#backstageButton #backstageHide:hover {
	background: none;
	color: none;
}

#backstageButton img,
#backstageButton svg {
	width: 24px;
	height: 24px;
}

#messageArea {
	top: 50px;
}

#backstageToolbar {
	position: relative;
}

#backstageArea a {
	padding: 0px;
	margin-left: 0px;
	color: white;
	background: none;
}

#backstageArea a:hover {
	background-color: white;
}

#backstage ol,
#backstage ul {
	padding: auto;
}

#backstageButton a {
	margin: 0;
}

.backstagePanelBody ul {
	padding: 5px;
	margin: 5px;
}

#backstage #backstagePanel {
	margin-left: 5%;
	padding: 0em;
	margin-right: 5%;
}

#backstageToolbar a {
	position: relative;
}

#backstageArea a.backstageSelTab,
#backstageToolbar .backstageTask {
	line-height: 25px;
	color: #767676;
}

.backstageTask .externalImage,
.backstageTask .image {
	display: inline;
}

#backstageToolbar a span {
	z-index: 2;
}

a.backstageTask {
	display: inline;
        margin-left: 1em !important;
}

.backstagePanelBody .button {
	display: inline-block;
	margin-right: 10px;
}

.backstagePanelBody {
	margin: 0 0 0 0.6em;
	padding: 0.4em 0.5em 1px 0.5em;
}

#backstage table {
	margin: auto;
}

#backstage .wizard table {
	border: 0px;
	margin: 0;
}

#backstage div  li.listLink {
	border: 0px;
	width: 78%;
	font-size: 0.7em;
}

#backstage div li.listTitle {
	font-weight: bold;
	text-decoration: underline;
	font-size: 1em;
	background: #ccc;
	width: 100%;
}

#backstage fieldset {
	border: solid 1px [[ColorPalette::Background]];
}

#backstage .viewer table,#backstage table.twtable {
	border: 0px;
}

#backstageToolbar img {
	padding: 0;
}

#backstage .wizard,
#backstage .wizardFooter {
	background: none;
}

.viewer td, .viewer tr, .twtable td, .twtable tr {
	border: 1px solid #eee;
}

#backstage .inlineList ul li {
	background-color: [[ColorPalette::Background]];
	border: solid 1px [[ColorPalette::TertiaryMid]];
	display: block;
	float: left;
	list-style: none;
	margin-right: 1em;
	padding: 0.5em;
}

.backstageClear, .inlineList form {
	clear: both;
	display: block;
	margin-top: 3em;
}

.tiddlyspaceMenu {
	text-align: center;
}

span.chunkyButton {
	display: inline-block;
	padding: 0;
	margin: 0;
	border: solid 2px #000;
	background-color: #04b;
}

span.chunkyButton a.button, span.chunkyButton a:active.button {
	white-space: nowrap;
	font-weight: bold;
	font-size: 1.8em;
	color: #fff;
	text-align: center;
	padding: 0.5em 0.5em;
	margin: 0;
	border-style: none;
	display: block;
}

span.chunkyButton:hover {
	background-color: #014;
}

span.chunkyButton a.button:hover {
	border-style: none;
	background: none;
	color: #fff;
}

#backstage .unpluggedSpaceTab .wizard,
.unpluggedSpaceTab .wizard {
	background: white;
	border: 2px solid #CCC;
	padding: 5px;
}

.syncKey .keyItem {
	border: 1px solid black;
	display: inline-block;
	margin: 0.2em;
	padding: 0.1em 0.1em 0.1em 0.1em;
}

.keyHeading {
	font-size: 2em;
	font-weight: bold;
	margin: 0.4em 0em -0.2em;
}

.unpluggedSpaceTab .putToServer,
.unpluggedSpaceTab .notChanged {
	display: none;
}

.tiddlyspaceMenu ul {
	margin: 0;
	padding: 0;
}

.tiddlyspaceMenu ul li {
	list-style: none;
}

.unsyncedChanges .unsyncedList {
	display: block;
}

.unsyncedList {
	display: none;
}
!Code
***/
//{{{
(function ($) {
    var name = "StyleSheet" + tiddler.title;
    config.shadowTiddlers[name] = "/*{{{*/\n%0\n/*}}}*/".
        format(store.getTiddlerText(tiddler.title + "##StyleSheet")); // this accesses the StyleSheet section of the current tiddler (the plugin that contains it)
    store.addNotification(name, refreshStyles);

    if (!config.extensions.tiddlyweb.status.tiddlyspace_version) { // unplugged
        config.extensions.tiddlyweb.status.tiddlyspace_version = "<unknown>";
        config.extensions.tiddlyweb.status.server_host = {
            url:config.extensions.tiddlyweb.host }; // TiddlySpaceLinkPlugin expects this
    }
    var disabled_tasks_for_nonmembers = ["tiddlers", "plugins", "batch", "sync"];

    var tweb = config.extensions.tiddlyweb;
    var tiddlyspace = config.extensions.tiddlyspace;
    var currentSpace = tiddlyspace.currentSpace.name;
    var imageMacro = config.macros.image;

    if (config.options.chkBackstage === undefined) {
        config.options.chkBackstage = false;
    }

// Set up Backstage
    config.tasks = {};
    config.tasks.status = {
        text:"status",
        tooltip:"TiddlySpace Info",
        content:"<<tiddler Backstage##Menu>>"
    };
    config.tasks.tiddlers = {
        text:"tiddlers",
        tooltip:"tiddlers control panel",
        content:"<<tiddler Backstage##BackstageTiddlers>>"
    };
    config.tasks.plugins = {
        text:"plugins",
        tooltip:"Manage installed plugins",
        content:"<<tiddler Backstage##Plugins>>"
    };
    config.tasks.batch = {
        text:"batch",
        tooltip:"Batch manage public/private tiddlers",
        content:"<<tiddler Backstage##BatchOps>>"
    };
    config.tasks.tweaks = {
        text:"tweaks",
        tooltip:"Tweak TiddlyWiki behaviors",
        content:"<<tiddler Backstage##Tweaks>>"
    };
    config.tasks.exportTiddlers = {
        text:"import/export",
        tooltip:"Import/export tiddlers from/to a TiddlyWiki",
        content:"<<tiddler Backstage##ImportExport>>"
    };
    config.tasks.sync = {
        text:"sync",
        tooltip:"Check Sync status",
        content:"<<tiddler Backstage##SpaceUnplugged>>"
    };

    if (window.location.protocol === "file:") {
        config.unplugged = true;
    }

    config.backstageTasks = ["status", "tiddlers", "plugins",
        "batch", "tweaks", "exportTiddlers", "sync"];

    config.messages.backstage.prompt = "";
// initialize state
    var _show = backstage.show;
    backstage.show = function () {
        // selectively hide backstage tasks and tabs based on user status
        var tasks = $("#backstageToolbar .backstageTask").show();
        var bs = backstage.tiddlyspace;
        if (!config.unplugged) {
            tweb.getUserInfo(function (user) {
                if (user.anon) {
                    jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
                        var taskIndex = config.backstageTasks.indexOf(task);
                        if (taskIndex !== -1) {
                            config.backstageTasks.splice(taskIndex, 1);
                        }
                    });
                    config.messages.memberStatus = bs.locale.loggedout;
                } else {
                    config.messages.memberStatus = readOnly ?
                        bs.locale.nonmember : bs.locale.member;
                }
            });
        } else {
            config.messages.memberStatus = bs.locale.unplugged;
        }

        // display backstage
        return _show.apply(this, arguments);
    };
    if (readOnly) {
        jQuery.each(disabled_tasks_for_nonmembers, function (i, task) {
            var taskIndex = config.backstageTasks.indexOf(task);
            if (taskIndex !== -1) {
                config.backstageTasks.splice(taskIndex, 1);
            }
        });
    }

    var tasks = config.tasks;
    var commonUrl = "/bags/common/tiddlers/%0";

    backstage.tiddlyspace = {
        locale:{
            member:"You are a member of this space.",
            nonmember:"You are not a member of this space.",
            loggedout:"You are currently logged out of TiddlySpace.",
            unplugged:"You are unplugged."
        },
        showButton:function () {
            var showBtn = $("#backstageShow")[0];
            var altText = $(showBtn).text();
            $(showBtn).empty();
            imageMacro.renderImage(showBtn, "backstage.svg",
                { altImage:commonUrl.format("backstage.png"), alt:altText});
        },
        hideButton:function () {
            var hideBtn = $("#backstageHide")[0];
            var altText = $(hideBtn).text();
            $(hideBtn).empty();
            imageMacro.renderImage(hideBtn, "close.svg",
                { altImage:commonUrl.format("close.png"), alt:altText, width:24, height:24 });
        }
    };

    var _init = backstage.init;
    backstage.init = function () {
        _init.apply(this, arguments);
        var init = function (user) {
            var bs = backstage.tiddlyspace;
            bs.showButton();
            bs.hideButton();
        };
        tweb.getUserInfo(init);
    };

    var home = config.macros.homeLink = {
        locale:{
            linkText:"your home space"
        },
        handler:function (place) {
            var container = $("<span />").appendTo(place)[0];
            tweb.getUserInfo(function (user) {
                if (!user.anon && user.name !== currentSpace) {
                    createSpaceLink(container, user.name, null, home.locale.linkText);
                }
            });
        }
    };

    config.macros.exportSpace = {
        handler:function (place, macroName, params) {
            var filename = params[0] ||
                "/tiddlers.wiki?download=%0.html".format(currentSpace);
            $('<a class="button">download</a>').// XXX: i18n
                attr("href", filename).appendTo(place);
        }
    };

}(jQuery));
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#FF4646" offset="0"/>
   <stop id="stop2" stop-color="#ffcccc" offset="0.66462"/>
   <stop id="stop3" stop-color="#FF4646" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol">
 <path id="path3645" stroke-linejoin="miter" style="stroke-dasharray:none;" d="m-23.302,17.497c0.01395-0.0064,0.0156,0.0261,0.0143,0.03143-0.01484,0.061-0.10068,0.05137-0.14,0.02579-0.11849-0.07708-0.08526-0.2504-0.003-0.34004,0.17365-0.18931,0.47534-0.11872,0.63154,0.05396,0.27503,0.30406,0.15201,0.77586-0.14521,1.0145-0.46844,0.3761-1.1521,0.18524-1.4889-0.27069-0.49266-0.6669-0.21843-1.6041,0.43042-2.0548,0.89949-0.62476,2.1319-0.25161,2.7121,0.62439,0.77241,1.1662,0.28478,2.7356-0.8526,3.4609-1.4672,0.93564-3.4151,0.31794-4.3011-1.1151-1.1144-1.8023-0.3511-4.1704,1.4118-5.2328,2.1717-1.3088,5.0016-0.38425,6.256,1.7427,1.5188,2.5753,0.4174,5.9087-2.1079,7.3706-3.0131,1.7444-6.8916,0.45055-8.5767-2.5073-1.9855-3.4851-0.48369-7.9504,2.941-9.8743,3.9914-2.2422,9.0851-0.51682,11.263,3.4089" transform="matrix(1.02832, 0, 0, 1.02832, 51.2465, 40.8719)" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" stroke-width="1.55593979000000000" fill="none"/>
</g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>

/***
|''Name''|RevisionsCommandPlugin|
|''Description''|provides access to tiddler revisions|
|''Author''|FND|
|''Contributors''|Martin Budden|
|''Version''|0.3.3|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/RevisionsCommandPlugin.js|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/association/plugins/|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Keywords''|serverSide|
!Usage
Extend [[ToolbarCommands]] with {{{revisions}}}.
!Revision History
!!v0.1 (2009-07-23)
* initial release (renamed from experimental ServerCommandsPlugin)
!!v0.2 (2010-03-04)
* suppressed wikification in diff view
!!v0.3 (2010-04-07)
* restored wikification in diff view
* added link to side-by-side diff view
!To Do
* strip server.* fields from revision tiddlers
* resolve naming conflicts
* i18n, l10n
* code sanitizing
* documentation
!Code
***/
//{{{
(function($) {

jQuery.twStylesheet(".diff { white-space: pre, font-family: monospace }",
	{ id: "diff" });

var cmd = config.commands.revisions = {
	type: "popup",
	hideShadow: true,
	text: "revisions",
	tooltip: "display tiddler revisions",
	revTooltip: "", // TODO: populate dynamically?
	loadLabel: "loading...",
	loadTooltip: "loading revision list",
	selectLabel: "select",
	selectTooltip: "select revision for comparison",
	selectedLabel: "selected",
	compareLabel: "compare",
	linkLabel: "side-by-side view",
	revSuffix: " [rev. #%0]",
	diffSuffix: " [diff: #%0 #%1]",
	dateFormat: "YYYY-0MM-0DD 0hh:0mm",
	listError: "revisions could not be retrieved",

	handlePopup: function(popup, title) {
		title = this.stripSuffix("rev", title);
		title = this.stripSuffix("diff", title);
		var tiddler = store.getTiddler(title);
		var type = _getField("server.type", tiddler);
		var adaptor = new config.adaptors[type]();
		var limit = null; // TODO: customizable
		var context = {
			host: _getField("server.host", tiddler),
			workspace: _getField("server.workspace", tiddler)
		};
		var loading = createTiddlyButton(popup, cmd.loadLabel, cmd.loadTooltip);
		var params = { popup: popup, loading: loading, origin: title };
		adaptor.getTiddlerRevisionList(title, limit, context, params, this.displayRevisions);
	},

	displayRevisions: function(context, userParams) {
		removeNode(userParams.loading);
		if(context.status) {
			var callback = function(ev) {
				var e = ev || window.event;
				var revision = resolveTarget(e).getAttribute("revision");
				context.adaptor.getTiddlerRevision(tiddler.title, revision, context,
					userParams, cmd.displayTiddlerRevision);
			};
			var table = createTiddlyElement(userParams.popup, "table");
			for(var i = 0; i < context.revisions.length; i++) {
				var tiddler = context.revisions[i];
				var row = createTiddlyElement(table, "tr");
				var timestamp = tiddler.modified.formatString(cmd.dateFormat);
				var revision = tiddler.fields["server.page.revision"];
				var cell = createTiddlyElement(row, "td");
				createTiddlyButton(cell, timestamp, cmd.revTooltip, callback, null,
					null, null, { revision: revision });
				cell = createTiddlyElement(row, "td", null, null, tiddler.modifier);
				cell = createTiddlyElement(row, "td");
				createTiddlyButton(cell, cmd.selectLabel, cmd.selectTooltip,
					cmd.revisionSelected, null, null, null,
					{ index:i, revision: revision, col: 2 });
				cmd.context = context; // XXX: unsafe (singleton)!?
			}
		} else {
			$("<li />").text(cmd.listError).appendTo(userParams.popup);
		}
	},

	revisionSelected: function(ev) {
		var e = ev || window.event;
		e.cancelBubble = true;
		if(e.stopPropagation) {
			e.stopPropagation();
		}
		var n = resolveTarget(e);
		var index = n.getAttribute("index");
		var col = n.getAttribute("col");
		while(!index || !col) {
			n = n.parentNode;
			index = n.getAttribute("index");
			col = n.getAttribute("col");
		}
		cmd.revision = n.getAttribute("revision");
		var table = n.parentNode.parentNode.parentNode;
		var rows = table.childNodes;
		for(var i = 0; i < rows.length; i++) {
			var c = rows[i].childNodes[col].firstChild;
			if(i == index) {
				if(c.textContent) {
					c.textContent = cmd.selectedLabel;
				} else {
					c.text = cmd.selectedLabel;
				}
			} else {
				if(c.textContent) {
					c.textContent = cmd.compareLabel;
				} else {
					c.text = cmd.compareLabel;
				}
				c.onclick = cmd.compareSelected;
			}
		}
	},

	compareSelected: function(ev) {
		var e = ev || window.event;
		var n = resolveTarget(e);
		var context = cmd.context;
		context.rev1 = n.getAttribute("revision");
		context.rev2 = cmd.revision;
		context.tiddler = context.revisions[n.getAttribute("index")];
		context.format = "unified";
		context.adaptor.getTiddlerDiff(context.tiddler.title, context,
			context.userParams, cmd.displayTiddlerDiffs);
	},

	displayTiddlerDiffs: function(context, userParams) {
		var tiddler = context.tiddler;
		tiddler.title += cmd.diffSuffix.format([context.rev1, context.rev2]);
		tiddler.text = "{{diff{\n" + context.diff + "\n}}}";
		tiddler.tags = ["diff"];
		tiddler.fields.doNotSave = "true"; // XXX: correct?
		if(!store.getTiddler(tiddler.title)) {
			store.addTiddler(tiddler);
		}
		var src = story.getTiddler(userParams.origin);
		var tiddlerEl = story.displayTiddler(src, tiddler);
		var uri = context.uri.replace("format=unified", "format=horizontal");
		var link = $('<a target="_blank" />').attr("href", uri).text(cmd.linkLabel);
		$(".viewer", tiddlerEl).prepend(link);
	},

	displayTiddlerRevision: function(context, userParams) {
		var tiddler = context.tiddler;
		tiddler.title += cmd.revSuffix.format([tiddler.fields["server.page.revision"]]);
		tiddler.fields.doNotSave = "true"; // XXX: correct?
		if(!store.getTiddler(tiddler.title)) {
			store.addTiddler(tiddler);
		}
		var src = story.getTiddler(userParams.origin);
		story.displayTiddler(src, tiddler);
	},

	stripSuffix: function(type, title) {
		var str = cmd[type + "Suffix"];
		var i = str.indexOf("%0");
		i = title.indexOf(str.substr(0, i));
		if(i != -1) {
			title = title.substr(0, i);
		}
		return title;
	}
};

var _getField = function(name, tiddler) {
	return tiddler.fields[name] || config.defaultCustomFields[name];
};

})(jQuery);
//}}}
/***
|''Description''|Sanitisation for dynamically pulling tiddlers into your space and displaying them|
!Notes
Works both inside and outside TiddlyWiki. Uses the HTML Sanitizer provided by the Google Caja project
(see http://code.google.com/p/google-caja/wiki/JsHtmlSanitizer for more on this), which is licensed under
an Apache License (see http://www.apache.org/licenses/LICENSE-2.0).
!Code
***/
//{{{
(function($) {

var cleanURL = function(url) {
	var regexp = /^(?:http|https|mailto|ftp|irc|news):\/\//;
	return (regexp.test(url)) ? url : null;
};

$.sanitize = function(html) {
	return html_sanitize(html, cleanURL);
};

/*
 * HTML Sanitizer, provided by Google Caja
 */

/* Copyright Google Inc.
 * Licensed under the Apache Licence Version 2.0
 * Autogenerated at Tue May 17 17:39:24 BST 2011
 * @provides html4
 */var html4={};html4.atype={NONE:0,URI:1,URI_FRAGMENT:11,SCRIPT:2,STYLE:3,ID:4,IDREF:5,IDREFS:6,GLOBAL_NAME:7,LOCAL_NAME:8,CLASSES:9,FRAME_TARGET:10},html4.ATTRIBS={"*::class":9,"*::dir":0,"*::id":4,"*::lang":0,"*::onclick":2,"*::ondblclick":2,"*::onkeydown":2,"*::onkeypress":2,"*::onkeyup":2,"*::onload":2,"*::onmousedown":2,"*::onmousemove":2,"*::onmouseout":2,"*::onmouseover":2,"*::onmouseup":2,"*::style":3,"*::title":0,"a::accesskey":0,"a::coords":0,"a::href":1,"a::hreflang":0,"a::name":7,"a::onblur":2,"a::onfocus":2,"a::rel":0,"a::rev":0,"a::shape":0,"a::tabindex":0,"a::target":10,"a::type":0,"area::accesskey":0,"area::alt":0,"area::coords":0,"area::href":1,"area::nohref":0,"area::onblur":2,"area::onfocus":2,"area::shape":0,"area::tabindex":0,"area::target":10,"bdo::dir":0,"blockquote::cite":1,"br::clear":0,"button::accesskey":0,"button::disabled":0,"button::name":8,"button::onblur":2,"button::onfocus":2,"button::tabindex":0,"button::type":0,"button::value":0,"canvas::height":0,"canvas::width":0,"caption::align":0,"col::align":0,"col::char":0,"col::charoff":0,"col::span":0,"col::valign":0,"col::width":0,"colgroup::align":0,"colgroup::char":0,"colgroup::charoff":0,"colgroup::span":0,"colgroup::valign":0,"colgroup::width":0,"del::cite":1,"del::datetime":0,"dir::compact":0,"div::align":0,"dl::compact":0,"font::color":0,"font::face":0,"font::size":0,"form::accept":0,"form::action":1,"form::autocomplete":0,"form::enctype":0,"form::method":0,"form::name":7,"form::onreset":2,"form::onsubmit":2,"form::target":10,"h1::align":0,"h2::align":0,"h3::align":0,"h4::align":0,"h5::align":0,"h6::align":0,"hr::align":0,"hr::noshade":0,"hr::size":0,"hr::width":0,"iframe::align":0,"iframe::frameborder":0,"iframe::height":0,"iframe::marginheight":0,"iframe::marginwidth":0,"iframe::width":0,"img::align":0,"img::alt":0,"img::border":0,"img::height":0,"img::hspace":0,"img::ismap":0,"img::name":7,"img::src":1,"img::usemap":11,"img::vspace":0,"img::width":0,"input::accept":0,"input::accesskey":0,"input::align":0,"input::alt":0,"input::autocomplete":0,"input::checked":0,"input::disabled":0,"input::ismap":0,"input::maxlength":0,"input::name":8,"input::onblur":2,"input::onchange":2,"input::onfocus":2,"input::onselect":2,"input::readonly":0,"input::size":0,"input::src":1,"input::tabindex":0,"input::type":0,"input::usemap":11,"input::value":0,"ins::cite":1,"ins::datetime":0,"label::accesskey":0,"label::for":5,"label::onblur":2,"label::onfocus":2,"legend::accesskey":0,"legend::align":0,"li::type":0,"li::value":0,"map::name":7,"menu::compact":0,"ol::compact":0,"ol::start":0,"ol::type":0,"optgroup::disabled":0,"optgroup::label":0,"option::disabled":0,"option::label":0,"option::selected":0,"option::value":0,"p::align":0,"pre::width":0,"q::cite":1,"select::disabled":0,"select::multiple":0,"select::name":8,"select::onblur":2,"select::onchange":2,"select::onfocus":2,"select::size":0,"select::tabindex":0,"table::align":0,"table::bgcolor":0,"table::border":0,"table::cellpadding":0,"table::cellspacing":0,"table::frame":0,"table::rules":0,"table::summary":0,"table::width":0,"tbody::align":0,"tbody::char":0,"tbody::charoff":0,"tbody::valign":0,"td::abbr":0,"td::align":0,"td::axis":0,"td::bgcolor":0,"td::char":0,"td::charoff":0,"td::colspan":0,"td::headers":6,"td::height":0,"td::nowrap":0,"td::rowspan":0,"td::scope":0,"td::valign":0,"td::width":0,"textarea::accesskey":0,"textarea::cols":0,"textarea::disabled":0,"textarea::name":8,"textarea::onblur":2,"textarea::onchange":2,"textarea::onfocus":2,"textarea::onselect":2,"textarea::readonly":0,"textarea::rows":0,"textarea::tabindex":0,"tfoot::align":0,"tfoot::char":0,"tfoot::charoff":0,"tfoot::valign":0,"th::abbr":0,"th::align":0,"th::axis":0,"th::bgcolor":0,"th::char":0,"th::charoff":0,"th::colspan":0,"th::headers":6,"th::height":0,"th::nowrap":0,"th::rowspan":0,"th::scope":0,"th::valign":0,"th::width":0,"thead::align":0,"thead::char":0,"thead::charoff":0,"thead::valign":0,"tr::align":0,"tr::bgcolor":0,"tr::char":0,"tr::charoff":0,"tr::valign":0,"ul::compact":0,"ul::type":0},html4.eflags={OPTIONAL_ENDTAG:1,EMPTY:2,CDATA:4,RCDATA:8,UNSAFE:16,FOLDABLE:32,SCRIPT:64,STYLE:128},html4.ELEMENTS={a:0,abbr:0,acronym:0,address:0,applet:16,area:2,b:0,base:18,basefont:18,bdo:0,big:0,blockquote:0,body:49,br:2,button:0,canvas:0,caption:0,center:0,cite:0,code:0,col:2,colgroup:1,dd:1,del:0,dfn:0,dir:0,div:0,dl:0,dt:1,em:0,fieldset:0,font:0,form:0,frame:18,frameset:16,h1:0,h2:0,h3:0,h4:0,h5:0,h6:0,head:49,hr:2,html:49,i:0,iframe:4,img:2,input:2,ins:0,isindex:18,kbd:0,label:0,legend:0,li:1,link:18,map:0,menu:0,meta:18,nobr:0,noframes:20,noscript:20,object:16,ol:0,optgroup:0,option:1,p:1,param:18,pre:0,q:0,s:0,samp:0,script:84,select:0,small:0,span:0,strike:0,strong:0,style:148,sub:0,sup:0,table:0,tbody:1,td:1,textarea:8,tfoot:1,th:1,thead:1,title:24,tr:1,tt:0,u:0,ul:0,"var":0},html4.ueffects={NOT_LOADED:0,SAME_DOCUMENT:1,NEW_DOCUMENT:2},html4.URIEFFECTS={"a::href":2,"area::href":2,"blockquote::cite":0,"body::background":1,"del::cite":0,"form::action":2,"img::src":1,"input::src":1,"ins::cite":0,"q::cite":0},html4.ltypes={UNSANDBOXED:2,SANDBOXED:1,DATA:0},html4.LOADERTYPES={"a::href":2,"area::href":2,"blockquote::cite":2,"body::background":1,"del::cite":2,"form::action":2,"img::src":1,"input::src":1,"ins::cite":2,"q::cite":2};var html=function(a){function x(b,c,d){var e=[];w(function(b,e){for(var f=0;f<e.length;f+=2){var g=e[f],h=e[f+1],i=null,j;if((j=b+"::"+g,a.ATTRIBS.hasOwnProperty(j))||(j="*::"+g,a.ATTRIBS.hasOwnProperty(j)))i=a.ATTRIBS[j];if(i!==null)switch(i){case a.atype.NONE:break;case a.atype.SCRIPT:case a.atype.STYLE:h=null;break;case a.atype.ID:case a.atype.IDREF:case a.atype.IDREFS:case a.atype.GLOBAL_NAME:case a.atype.LOCAL_NAME:case a.atype.CLASSES:h=d?d(h):h;break;case a.atype.URI:h=c&&c(h);break;case a.atype.URI_FRAGMENT:h&&"#"===h.charAt(0)?(h=d?d(h):h,h&&(h="#"+h)):h=null;break;default:h=null}else h=null;e[f+1]=h}return e})(b,e);return e.join("")}function w(b){var c,d;return v({startDoc:function(a){c=[],d=!1},startTag:function(e,f,g){if(!d){if(!a.ELEMENTS.hasOwnProperty(e))return;var h=a.ELEMENTS[e];if(h&a.eflags.FOLDABLE)return;if(h&a.eflags.UNSAFE){d=!(h&a.eflags.EMPTY);return}f=b(e,f);if(f){h&a.eflags.EMPTY||c.push(e),g.push("<",e);for(var i=0,j=f.length;i<j;i+=2){var k=f[i],l=f[i+1];l!==null&&l!==void 0&&g.push(" ",k,'="',r(l),'"')}g.push(">")}}},endTag:function(b,e){if(d)d=!1;else{if(!a.ELEMENTS.hasOwnProperty(b))return;var f=a.ELEMENTS[b];if(!(f&(a.eflags.UNSAFE|a.eflags.EMPTY|a.eflags.FOLDABLE))){var g;if(f&a.eflags.OPTIONAL_ENDTAG)for(g=c.length;--g>=0;){var h=c[g];if(h===b)break;if(!(a.ELEMENTS[h]&a.eflags.OPTIONAL_ENDTAG))return}else for(g=c.length;--g>=0;)if(c[g]===b)break;if(g<0)return;for(var i=c.length;--i>g;){var h=c[i];a.ELEMENTS[h]&a.eflags.OPTIONAL_ENDTAG||e.push("</",h,">")}c.length=g,e.push("</",b,">")}}},pcdata:function(a,b){d||b.push(a)},rcdata:function(a,b){d||b.push(a)},cdata:function(a,b){d||b.push(a)},endDoc:function(a){for(var b=c.length;--b>=0;)a.push("</",c[b],">");c.length=0}})}function v(c){return function(d,e){d=String(d);var f=null,g=!1,h=[],j=void 0,l=void 0,m=void 0;c.startDoc&&c.startDoc(e);while(d){var n=d.match(g?t:u);d=d.substring(n[0].length);if(g){if(n[1]){var o=b(n[1]),p;if(n[2]){var q=n[3];switch(q.charCodeAt(0)){case 34:case 39:q=q.substring(1,q.length-1)}p=k(i(q))}else p=o;h.push(o,p)}else if(n[4]){l!==void 0&&(m?c.startTag&&c.startTag(j,h,e):c.endTag&&c.endTag(j,e));if(m&&l&(a.eflags.CDATA|a.eflags.RCDATA)){f===null?f=b(d):f=f.substring(f.length-d.length);var r=f.indexOf("</"+j);r<0&&(r=d.length),l&a.eflags.CDATA?c.cdata&&c.cdata(d.substring(0,r),e):c.rcdata&&c.rcdata(s(d.substring(0,r)),e),d=d.substring(r)}j=l=m=void 0,h.length=0,g=!1}}else if(n[1])c.pcdata&&c.pcdata(n[0],e);else if(n[3])m=!n[2],g=!0,j=b(n[3]),l=a.ELEMENTS.hasOwnProperty(j)?a.ELEMENTS[j]:void 0;else if(n[4])c.pcdata&&c.pcdata(n[4],e);else if(n[5]&&c.pcdata)switch(n[5]){case"<":c.pcdata("&lt;",e);break;case">":c.pcdata("&gt;",e);break;default:c.pcdata("&amp;",e)}}c.endDoc&&c.endDoc(e)}}function s(a){return a.replace(m,"&amp;$1").replace(n,"&lt;").replace(o,"&gt;")}function r(a){return a.replace(l,"&amp;").replace(n,"&lt;").replace(o,"&gt;").replace(p,"&#34;").replace(q,"&#61;")}function k(a){return a.replace(j,g)}function i(a){return a.replace(h,"")}function g(a,b){return f(b)}function f(a){a=b(a);if(c.hasOwnProperty(a))return c[a];var f=a.match(d);if(f)return String.fromCharCode(parseInt(f[1],10));if(!!(f=a.match(e)))return String.fromCharCode(parseInt(f[1],16));return""}var b;"script"==="SCRIPT".toLowerCase()?b=function(a){return a.toLowerCase()}:b=function(a){return a.replace(/[A-Z]/g,function(a){return String.fromCharCode(a.charCodeAt(0)|32)})};var c={lt:"<",gt:">",amp:"&",nbsp:"240",quot:'"',apos:"'"},d=/^#(\d+)$/,e=/^#x([0-9A-Fa-f]+)$/,h=/\0/g,j=/&(#\d+|#x[0-9A-Fa-f]+|\w+);/g,l=/&/g,m=/&([^a-z#]|#(?:[^0-9x]|x(?:[^0-9a-f]|$)|$)|$)/gi,n=/</g,o=/>/g,p=/\"/g,q=/\=/g,t=new RegExp("^\\s*(?:(?:([a-z][a-z-]*)(\\s*=\\s*(\"[^\"]*\"|'[^']*'|(?=[a-z][a-z-]*\\s*=)|[^>\"'\\s]*))?)|(/?>)|[\\s\\S][^a-z\\s>]*)","i"),u=new RegExp("^(?:&(\\#[0-9]+|\\#[x][0-9a-f]+|\\w+);|<!--[\\s\\S]*?-->|<!\\w[^>]*>|<\\?[^>*]*>|<(/)?([a-z][a-z0-9]*)|([^<&>]+)|([<&>]))","i");return{escapeAttrib:r,makeHtmlSanitizer:w,makeSaxParser:v,normalizeRCData:s,sanitize:x,unescapeEntities:k}}(html4),html_sanitize=html.sanitize

// stop here if we're not in TiddlyWiki
// XXX: is this the correct way of checking for TiddlyWiki?
if (!window.TiddlyWiki || !window.store || !store instanceof TiddlyWiki) {
	return;
}

var tiddlyspace = config.extensions.tiddlyspace;

var _subWikify = Wikifier.prototype.subWikify;

var cleanedTitle = 'This section has been cleaned of any potentially harmful code';

var replaceFunctions = {
	html: function(w) {
		var sanitizedHTML, spanEl;
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			sanitizedHTML = $.sanitize(lookaheadMatch[1]);
			spanEl = createTiddlyElement(w.output, 'span', null, 'sanitized');
			spanEl.innerHTML = sanitizedHTML;
			spanEl.setAttribute('title', cleanedTitle);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	},
	customFormat: function(w) {
		switch(w.matchText) {
			case '@@':
				var e = createTiddlyElement(w.output, 'span');
				var styles = config.formatterHelpers.inlineCssHelper(w);
				if (styles.length === 0) {
					e.className = 'marked';
				}
				w.subWikifyTerm(e, /(@@)/mg);
				break;
			case '{{':
				var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
				lookaheadRegExp.lastIndex = w.matchStart;
				var lookaheadMatch = lookaheadRegExp.exec(w.source);
				if(lookaheadMatch) {
					w.nextMatch = lookaheadRegExp.lastIndex;
					e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
					w.subWikifyTerm(e,/(\}\}\})/mg);
				}
				break;
		}
	}
};

Wikifier.prototype.subWikify = function(output, terminator) {
	var tid = this.tiddler,
		spaceName = tiddlyspace.currentSpace.name,
		tidSpace, recipeName, stripped;
	try {
		recipeName = tid.fields['server.recipe'] ||
			tid.fields['server.workspace'];
		tidSpace = tiddlyspace.resolveSpaceName(recipeName);
		if (tidSpace !== spaceName) {
			// external tiddler, so replace dangerous formatters
			stripped = stripHTML(tid, this.formatter);
		}
	} catch(e) {
		// do nothing. There's no tiddler, so assume it's safe (?!?!?)
	}

	_subWikify.apply(this, arguments);

	if (stripped) {
		// change back to the original function
		unstripHTML(stripped, this.formatter);
	}
};

// replace potentially unsafe formatters with versions that strip bad HTML/CSS
var stripHTML = function(tid, formatter) {
	var popped = {}, _handler;
	for (var i = 0; i < formatter.formatters.length; i++) {
		var f = formatter.formatters[i];
		if (replaceFunctions[f.name]) {
			_handler = f.handler;
			popped[f.name] = _handler;
			f.handler = replaceFunctions[f.name];
		}
	};

	return popped;
};

// put the original formatters back where they belong
var unstripHTML = function(stripped, formatter) {
	for (var i = 0; i < formatter.formatters.length; i++) {
		var f = formatter.formatters[i];
		if (stripped[f.name]) {
			f.handler = stripped[f.name];
		}
	};
};

})(jQuery);
//}}}
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
+++[Email to Randy Schultz today ({{ts{25/07/14 10:35}}})]
So, yesterday I installed Mariadb & Apache24 without a hitch using the pkg system. However the php55 pkg install does not include Apache24 support for some reason. (What's the point of installing php without web server support? It's pointless) Here's what I found at http://forums.freebsd.org/viewtopic.php?t=42961

>"it just doesn't contain the Apache module. The port would need to be built for each web server we support (which would result in the same package name although it's been built for different Apache versions). That's one of the reasons why it's not in the package."

Still don't get it.

From the above discussion:
{{{
$ cd /usr/ports/lang/php55
$ make clean build deinstall install
}}}
Which should uninstall the pkg ?
BUT, in /usr/ports/UPDATING:
{{{
20140327:
  AFFECTS: users of lang/php5 and lang/php55 with Apache module
  AUTHOR: ale@FreeBSD.org

  The Apache PHP module has been separated from the main PHP port.
  If you had the APACHE OPTION selected, you have to perform the
  following steps:

  1) update your lang/php* options (i.e. 'make config')
  2) rebuild lang/php* port
  3) install www/mod_php* port

  It is *mandatory* to build both ports with the same DEBUG and ZTS
  options, so if you have a threaded Apache (i.e. worker or event MPM)
  you have to select the ZTS option in lang/php* port.
}}}
So, I should :
{{{
$ cd /usr/ports/lang/mod_php55
$ make config
$ make reinstall clean
$ make clean build deinstall install (which should do steps 2 & 3 above and remove the pkg install of php, right?)
}}}
=== 
1. Install Apache 24 support :
{{{
patmos% uname -a
FreeBSD patmos 10.0-RELEASE-p7 FreeBSD 10.0-RELEASE-p7 #0: Tue Jul  8 06:37:44 UTC 2014     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64
patmos% pwd
/usr/ports/www/mod_php55
patmos% sudo make reinstall clean
}}}
Take defaults. 
{{{
/!\ WARNING /!\
!!! If you have a threaded Apache, you must build lang/php55 with ZTS support to enable thread-safety in extensions !!!
}}}
: ''How do I know if I have a threaded Apache ??''
{{{
===>  License PHP301 accepted by the user
===>  Found saved configuration for mod_php55-5.5.14
===>   mod_php55-5.5.14 depends on file: /usr/local/sbin/pkg - found
=> php-5.5.14.tar.bz2 doesn't seem to exist in /var/ports/distfiles/.
=> Attempting to fetch http://dk1.php.net/distributions/php-5.5.14.tar.bz2
}}}
@@This seems to have worked!@@
{{{
===>  Installing for mod_php55-5.5.14
===>   Registering installation for mod_php55-5.5.14
[activating module `php5' in /usr/local/etc/apache24/httpd.conf]
Installing mod_php55-5.5.14... done
***************************************************************

Make sure index.php is part of your DirectoryIndex.

You should add the following to your Apache configuration file:

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>

***************************************************************
}}}
And +++[SECURITY REPORT:]>
{{{
===> SECURITY REPORT:
      This port has installed the following files which may act as network
      servers and may therefore pose a remote security risk to the system.
/usr/local/libexec/apache24/libphp5.so

      If there are vulnerabilities in these programs there may be a security
      risk to the system. FreeBSD makes no guarantee about the security of
      ports included in the Ports Collection. Please type 'make deinstall'
      to deinstall the port if this is a concern.

      For more information, and contact details about the security
      status of this software, see the following webpage:
http://www.php.net/
}}}
=== 
-- Done edit on {{{/usr/local/etc/apache24/httpd.conf}}} :
<<<
{{{
<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>
<FilesMatch "\.phps$">
    SetHandler application/x-httpd-php-source
</FilesMatch>
}}}
<<<
And removed other references to the php mime type. 
Also {{{LoadModule php5_module        libexec/apache24/libphp5.so}}} is present.
!!Test
with {{{/usr/local/www/apache24/data/phpinfo.php}}}. But http://patmos.earlham.edu/phpinfo.php times out.
In {{{/var/log/httpd-error.log}}} we have:
{{{
[Fri Jul 25 11:33:36.550613 2014] [:error] [pid 24813] [client 159.28.7.70:50678] PHP Warning:  phpinfo(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /usr/local/www/apache24/data/phpinfo.php on line 2
}}}
; Solution: 
In {{{/usr/local/etc/php.ini}}} Add:
{{{
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = America/Indianapolis
}}}
----
{{ts{25/07/14 16:13}}}
Having a lot of trouble getting phpinfo.php to display in firefox. Apache works. It will display in FF on my Mac! But times out on the PC!

----
!!Install php extensions
; In {{{/usr/ports/lang/php55-extensions}}}
: {{{sudo make config-recursive}}}, and then
: {{{sudo make install clean}}}
+++[error building extensions]
{{{
==>   php55-interbase-5.5.14 depends on shared library: libfbclient.so - not found
==>    Verifying for libfbclient.so in /usr/ports/databases/firebird25-client
==>  firebird25-client-2.5.2_2 your system does not support sysvipc.
*** Error code 1

Stop.
make[3]: stopped in /basejail/usr/ports/databases/firebird25-client
*** Error code 1

Stop.
make[2]: stopped in /basejail/usr/ports/databases/php55-interbase
*** Error code 1

Stop.
make[1]: stopped in /basejail/usr/ports/lang/php55-extensions
*** Error code 1

Stop.
make: stopped in /basejail/usr/ports/lang/php55-extensions
}}}
=== 
{{ts{16/09/13 10:57}}} problem still present. Forumng updated to version {{{2013082000}}} on Fri Sept-13 to the //same version// as on my sandbox system. 
!!Presenting problem
User clicks on My Home/My courses and gets :
<<<
Coding error detected, it must be fixed by a programmer: Unread discussion flag not obtained 
<<<
What it should look like (on sandbox system with updated forumng code installed):
[img[http://legacy.earlham.edu/~markp/screens/moodle/forumng-myhome.png]]
But //exactly the same code is on the Production site!//
!!!Also Activities : Forumng
<<<
Coding error detected, it must be fixed by a programmer: Unread discussion count not obtained
<<<
What this should look like (on sandbox system with updated forumng code installed):
[img[http://legacy.earlham.edu/~markp/screens/moodle/forumng-Activities.png]]
!!!What I've done:
* Switch debugging on -- no error messages thrown.
* Hide forumng activity -- still generates error
* Purge all caches -- no effect.
I'm baffled.
{{ts{16/09/13 14:42}}} Posted on Moodle Tracker as [[MDL-41821 ForumNG prevents access to My Home when there are unread discussions|https://tracker.moodle.org/browse/MDL-41821]]
Posted to [[ForumNg git issues instead|https://github.com/moodleou/moodle-mod_forumng]]
{{ts{16/09/13 16:12}}}
Sent the +++[following message]>
Dear Pat,
If you use  My Home to navigate between courses you may have seen the following error message :
Coding error detected, it must be fixed by a programmer: Unread discussion flag not obtained
and you will not be able to open My Home. This is caused by the Forumng activity in the course  QUAKEF Quaker Fellows setting some flag to say that there are unviewed discussions which this is not done correctly and causes an error. Last week I tracked the error down and found a latest version of Forumng which purported to fix it. Indeed, when I tested the code on my sandbox Moodle site it did fix the problem. So last Friday we took the production Moodle system offline and updated to this latest Forumng code. However, unfortunately, even though we used exactly the same code we are now finding that the problem is still there which is very perplexing. I have reported this problem in the Moodle forums but responses are likely to take some time to appear.
In the interim while I am pursuing a solution, I suggest the following:

    Use the Course Categories block to switch courses and suggest to your class that they do this too (I have taken the liberty of adding this to your courses that did not have it present).
    Use the regular Forum instead of Forumng for new Forums.

Apologies for this situation -- I am working to clear it up but it'll take time I'm afraid.
Your Moodle Tsar at your service,
Mark
=== to everyone currently using ForumNG as listed at [[OU module users]]

Also sparked by [[Moodle prod issue]]
[[More ForumNG -- SUSSED]]

Brings out the problem of aligning system settings
<!--{{{-->
<link rel="shortcut icon" href="/recipes/moodle_public/tiddlers/favicon.ico" />
<link href="/bags/moodle_public/tiddlers.atom" rel="alternate"
	type="application/atom+xml" title="moodle's public feed" />
<link rel="canonical" href="http://moodle.tiddlyspace.com/" />
<!--}}}-->
!!Latest thoughts ({{ts{17/07/12 10:20}}} )
* Go ahead with m23 site [[Moodle 2 on Naum]] and Add ins
* set up CLAMP m23 site with their version moodle 2.3
* Use standard theme but maybe add autohide css -- [[Reducing clutter]]
* Ready for moodletest by end of week
!!Now {{ts{23/07/12 16:17}}} see [[Moodle 2.3 -- which one?]]
+++!![Plugins]
|!Plugin|!version|!in m23|!in Clamp m23|!Comments|
|!Modules|~|~|~|~|
|Attendance|{{{2011071601}}}| Y | |release={{{2.4.0}}} {{{andreev-artem-moodle_mod_attforblock-2.4.0b-32-g2e9d05a.tar.gz}}}|
|Questionnaire|July 10 2012| | |{{{2.3.1 (Build - 20120708)}}} (2012070801) from [[moodle downloads|http://moodle.org/plugins/pluginversions.php?plugin=mod_questionnaire]] {{{mod_questionnaire_moodle23_2012070801.zip}}}|
|Scheduler|  2.x dev| Y | |[[moodle.org plugins|http://moodle.org/plugins/view.php?plugin=mod_scheduler]]  [[github -- development alpha|https://github.com/bostelm/moodle-mod_scheduler]] Not sure whether 2.3 compliant {{{version.php}}} = "It is intended for use with Moodle 2.0 and 2.1." But does work with 2.2 @@test carefully@@|
|ForumNG|>|>|>|not ready for 2.3 -- [[OU Modules latest]]|
|OUBlog|>|>|>|~|
|OUWiki|>|>|>|~|
|!Blocks|>|>|>|>|
|Quickmail| 2012061112| Y | |[[github version|https://github.com/lsuits/quickmail]] |
|Sharing Cart| | | |[[Sharing Cart]] -- not compatible with 2.3|
|Progress Bar| | | | ? |
|Course Menu|>|>|>|Replace with better navigation option?|
|myCourses|>|>|>|test [[Course Menu block Moodle 2]]|
|!Course formats and Themes|>|>|>|>|
|Collapsed Topics| 2.3.7.1 (2012071100)| Y | |[[moodle.org plugins|http://moodle.org/plugins/pluginversions.php?plugin=format_topcoll]] just released for 2.3 11 July|
=== 
* Also see [[Moodle plugins 2 migrate]]
* And [[LAE test construction : modules]]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d" stroke-linecap="butt" fill="none">
   <rect id="rect3637" style="stroke-dasharray:none;" ry="0" height="13.033" width="13.033" stroke-miterlimit="4" y="51.156" x="21.11" stroke-width="1.3672"/>
   <path id="path3639" d="m20.989,54.423,12.783,0" stroke-width="0.80000001px"/>
   <path id="path3641" d="m21.256,57.619,12.783,0" stroke-width="0.80000001px"/>
   <path id="path3643" d="m21.211,60.682,12.65,0" stroke-width="0.80000001px"/>
   <path id="path3645" d="m18.032,10.562,0,16.034" transform="matrix(0.8, 0, 0, 0.8, 13, 43)" stroke-width="1px"/>
  </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
* [[Questionnaire new features on test site|https://moodle.org/mod/forum/discuss.php?d=208936]]
* [[Github project|https://github.com/remotelearner/moodle-mod_questionnaire/tree/WIP_CONTRIB-3937_MOODLE_23_STABLE]]

/*{{{*/
/* created by QuickOpenTagPlugin */
#sidebarTabs .tabContents a.button { display:inline;}
.tagglyTagged .quickopentag, .tagged .quickopentag 
	{ border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }
.quickopentag .tiddlyLink { padding:2px; padding-left:3px; display:inline; }
.quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px; display:inline;}
/* extra specificity to make it work right */
#displayArea .viewer .quickopentag a.button, 
#displayArea .viewer .quickopentag a.tiddyLink, 
#mainMenu .quickopentag a.tiddyLink, 
#mainMenu .quickopentag a.tiddyLink 
	{ border:0px solid black; display:inline;}
#displayArea .viewer .quickopentag a.button, 
#mainMenu .quickopentag a.button 
	{ margin-left:0px; padding-left:2px; display:inline;}
#displayArea .viewer .quickopentag a.tiddlyLink, 
#mainMenu .quickopentag a.tiddlyLink 
	{ margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }
a.miniTag {font-size:150%;} 
#mainMenu .quickopentag a.button 
	/* looks better in right justified main menus */
	{ margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; display:inline;}
#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }
#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }
#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; display:inline; }
/*}}}*/
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
/***
|''Name''|BinaryTiddlersPlugin|
|''Description''|renders base64-encoded binary tiddlers as images or links|
|''Author''|FND|
|''Version''|0.3.2|
|''Status''|@@beta@@|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/BinaryTiddlersPlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5|
!Code
***/
//{{{
(function($) {

"use strict";

var ctfield = "server.content-type";

var plugin = config.extensions.BinaryTiddlersPlugin = {
	isWikiText: function(tiddler) {
		var ctype = tiddler.fields[ctfield];
		if(ctype) {
			if (ctype === 'text/x-tiddlywiki') {
				return true;
			}
			return !this.isBinary(tiddler) && !this.isTextual(ctype);
		} else {
			return true;
		}
	},
	// NB: pseudo-binaries are considered non-binary here
	isBinary: function(tiddler) {
		var ctype = tiddler.fields[ctfield];
		return ctype ? !this.isTextual(ctype) : false;
	},
	isTextual: function(ctype) {
		return ctype.indexOf("text/") === 0
			|| this.endsWith(ctype, "+xml")
			|| ctype === 'application/json'
			|| ctype === 'application/javascript';
	},
	endsWith: function(str, suffix) {
		return str.length >= suffix.length &&
			str.substr(str.length - suffix.length) === suffix;
	},
	isLink: function(tiddler) {
		return this.isBinary(tiddler) && tiddler.text.indexOf("<html>") !== -1;
	}
};

// Disable edit for linked tiddlers (for now)
// This will be changed to a GET then PUT
config.commands.editTiddler.isEnabled = function(tiddler) {
    var existingTest = config.commands.editTiddler.isEnabled;
    if (existingTest) {
        return existingTest && !plugin.isLink(tiddler);
    } else {
        return !plugin.isLink(tiddler);
    }
};

// hijack text viewer to add special handling for binary tiddlers
var _view = config.macros.view.views.wikified;
config.macros.view.views.wikified = function(value, place, params, wikifier,
		paramString, tiddler) {
	var ctype = tiddler.fields["server.content-type"];
	if(params[0] === "text" && ctype && ctype !== 'text/x-tiddlywiki' &&
			!tiddler.tags.contains("systemConfig") && !plugin.isLink(tiddler)) {
		var el;
		if(plugin.isBinary(tiddler)) {
			var uri = "data:%0;base64,%1".format([ctype, tiddler.text]); // TODO: fallback for legacy browsers
			if(ctype.indexOf("image/") === 0) {
				el = $("<img />").attr("alt", tiddler.title).attr("src", uri);
			} else {
				el = $("<a />").attr("href", uri).text(tiddler.title);
			}
		} else {
			el = $("<pre />").text(tiddler.text);
		}
		el.appendTo(place);
	} else {
		_view.apply(this, arguments);
	}
};

// hijack edit macro to disable editing of binary tiddlers' body
var _editHandler = config.macros.edit.handler;
config.macros.edit.handler = function(place, macroName, params, wikifier,
		paramString, tiddler) {
	if(params[0] === "text" && plugin.isBinary(tiddler)) {
		return false;
	} else {
		_editHandler.apply(this, arguments);
	}
};

// hijack autoLinkWikiWords to ignore binary tiddlers
var _autoLink = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function() {
	return plugin.isWikiText(this) ? _autoLink.apply(this, arguments) : false;
};

}(jQuery));
//}}}
/***
|''Name''|ImageMacroPlugin|
|''Version''|0.9.4|
|''Description''|Allows the rendering of svg images in a TiddlyWiki|
|''Author''|Osmosoft|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Notes''|Currently only works in modern browsers (not IE)|
|''Requires''|BinaryTiddlersPlugin|
!Usage
{{{<<image SVG>>}}} will render the text of the tiddler with title SVG as an SVG image (but not in ie where it will fail silently)
!!Parameters
width/height: specify width/height parameters
link: make the image link to a given location
tiddlyLink: link to a tiddler

!Notes
Binary tiddlers in TiddlyWeb when passed through the wikifier will be shown as images.
eg. {{{<<view text wikified>>}}} on a binary tiddler will show the image.
{{{<<view fieldname image>>}}}
will render the value of the tiddler field 'fieldname' as an image. This field can contain a tid
{{{<<image SiteIcon>>}}}
will create an image tag where the tiddler has content type beginning image and not ending +xml
will attempt to create svg object in other scenarios
{{{<<image /photos/x.jpg>>}}}
will create an image tag with src /photos/x.jpg as long as there is not a tiddler called /photos/x.jpg in 
which case it will render that tiddler as an image. Note for the case of svg files it will attempt to render as an svg if possible via the image
tag. It doesn't embed the svg in the dom for security reasons as svg code can contain javascript.
!Code
***/
//{{{
(function($) {

var macro = config.macros.image = {
	shim: "/bags/common/tiddlers/shim",
	ieVersion: config.browser.isIE ? parseInt(config.browser.ieVersion[1], 10) : false,
	svgns: "http://www.w3.org/2000/svg",
	xlinkns: "http://www.w3.org/1999/xlink", 
	svgAvailable: document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
	_fixPrefix: 1,
	_external_cache: {},
	_image_tag_cache: {},
	_image_dimensions: {},
	locale: {
		badImage: "This image cannot be displayed."
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler){
		var imageSource = params[0];
		// collect named arguments
		var args = macro.getArguments(paramString, params);
		this.renderImage(place, imageSource, args);
	},
	init: function() {
		var startupImages = store.getTaggedTiddlers("systemImage");
		var place = $("<div />").attr("id", "systemImageArea").appendTo("body").hide()[0];
		for(var i = 0; i < startupImages.length; i++) {
			var image = startupImages[i];
			macro.renderImage(place, image.title, { idPrefix: "" });
		}
		var data = new Image();
		data.onload = function() {
			// note ie 8 only supports data uris up to 32k so cannot be relied on
			macro.supportsDataUris = this.width != 1 || this.height != 1 ? false : true;
			macro.supportsDataUris = macro.ieVersion && macro.ieVersion < 9 ? false : macro.supportsDataUris;
		};
		data.onerror = data.onload;
		data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
	},
	refreshImage: function(src) {
		var elements = macro._image_tag_cache[src] ? macro._image_tag_cache[src] : [];
		if(macro._image_dimensions[src]) {
			macro._image_dimensions[src] = false;
		}
		for(var i = 0; i < elements.length; i++) {
			var el = $(elements[i]);
			var newSrc = "%0?nocache=%1".format(src, Math.random());
			el.attr("src", newSrc); // force reload
		}
	},
	isBinaryImageType: function(contentType) {
		return (contentType && contentType.indexOf("image") === 0 &&
			contentType.indexOf("+xml") != contentType.length - 4) ? true : false;
	},
	isImageTiddler: function(tiddler) {
		return macro.isSVGTiddler(tiddler) || macro.isBinaryImageTiddler(tiddler);
	},
	isSVGTiddler: function(tiddler) {
		var type = tiddler ? tiddler.fields['server.content-type'] : false;
		return type == "image/svg+xml";
	},
	isBinaryImageTiddler: function(tiddler) {
		return macro.isBinaryImageType(tiddler.fields['server.content-type']);
	},
	renderImage: function(place, imageSource, options) {
		var imageTiddler = store.getTiddler(imageSource);
		var container;
		var classes = ["image"];
		if(options.link) {
			classes = classes.concat(["imageLink", "externalLink"]);
			container = $("<a />").attr("href", options.link).appendTo(place)[0];
		} else if(options.tiddlyLink) {
			classes.push("imageLink");
			container = createTiddlyLink(place, options.tiddlyLink, false);
		} else {
			container = $("<span />").appendTo(place)[0];
		}
		$(container).addClass(classes.join(" "));

		options = options ? options : {};
		if(imageTiddler && macro.isBinaryImageTiddler(imageTiddler)) { // handle the case where we have an image url
			return macro._renderBinaryImageTiddler(container, imageTiddler, options);
		} else if(imageTiddler){ // handle the case where we have a tiddler
			return macro._renderSVGTiddler(container, imageTiddler, options);
		} else { // we have a string representing a url
			return macro._renderBinaryImageUrl(container, imageSource, options);
		}
	},
	_renderAlternateText: function(container, options) {
		var img;
		var src = options.src || "";
		if(options.width && options.height) {
			img = $("<img />").attr("src", src).addClass("svgImageText").attr("width", options.width).
				attr("height", options.height).appendTo(container);
		}
		var alt = options.alt;
		if(img && alt) {
			img.attr("alt", alt).attr("title", alt);
		} else if(alt) {
			$(container).addClass("svgImageText").text(alt);
		}
		macro._image_tag_cache[src] = img;
	},
	_renderSVGTiddler: function(place, tiddler, options) {
		if(!options) {
			options = {};
		}
		merge(options, { tiddler: tiddler, fix: true});

		if(macro.svgAvailable) {
			this._importSVG(place, options); // display the svg
		} else if(options.altImage) {
			var image = options.altImage;
			delete options.altImage;
			this._renderBinaryImageUrl(place, image, options);
		} else {
			this._renderAlternateText(place, options); // instead of showing the image show the alternate text.
		}
	},
	_renderBinaryImageTiddler: function(place, tiddler, options) {
		var resourceURI;
		var fields = tiddler.fields;
		if(fields["server.type"] == "tiddlyweb") { // construct an accurate url for the resource
			resourceURI = "%0/%1/tiddlers/%2".format(config.defaultCustomFields["server.host"],
				fields["server.workspace"], encodeURI(fields["server.title"]));
		} else { // guess the url for the resource
			resourceURI = tiddler.title;
		}
		var ctype = fields["server.content-type"] || tiddler.type;
		var text = tiddler.text;
		if(macro.supportsDataUris && ctype && text.indexOf("<html") == -1) {
			var uri = "data:%0;base64,%1".format(ctype, text);
			options.src = resourceURI;
			return macro._renderBinaryImageUrl(place, uri, options);
		} else if(options.src) {
			return macro._renderBinaryImageUrl(place, options.src, options);
		} else {
			return macro._renderBinaryImageUrl(place, resourceURI, options);
		}
	},
	_renderImageTag: function(container, src, width, height, options) {
		var img;
		img = $("<img />").appendTo(container);
		if(height) {
			img.attr("height", height);
		}
		if(width) {
			img.attr("width", width);
		}
		if(macro.ieVersion && macro.ieVersion < 7 && macro.shim && options.ie6png) {
			$(img).css({width: userW, height: userH,
					filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%0', sizingMethod='scale')".format(src)
				}).attr("src", macro.shim);
		} else {
			img.attr("src", src);
		}
		if(!macro._image_tag_cache[options.srcUrl]) {
			macro._image_tag_cache[options.srcUrl] = [];
		}
		img = $(img).addClass(options.imageClass)[0];
		macro._image_tag_cache[options.srcUrl].push(img);
		return img;
	},
	_getDimensions: function(realDimensions, reqDimensions, preserve) {
		var w = realDimensions.width;
		var h = realDimensions.height;
		var reqh = reqDimensions.height;
		var reqw = reqDimensions.width;
		var finalw = w, finalh = h;
		var ratiow = reqw / w, ratioh = reqh / h;
		var scaledw = ratioh * w;
		var scaledh = ratiow * h;
		if(!reqw && reqh) {
			finalw = scaledw;
			finalh = reqh;
		} else if(reqw && !reqh) {
			finalw = reqw;
			finalh = scaledh;
		} else if(reqh && reqw) {
			var preserveWidth = w > h ? true : false;
			if(preserve) {
				if(preserveWidth && scaledh < reqh) {
					finalh = scaledh;
					finalw = reqw;
				} else {
					finalh = reqh;
					finalw = scaledw;
				}
			} else {
				finalw = reqw;
				finalh = reqh;
			}
		}
		return { width: parseInt(finalw, 10), height: parseInt(finalh, 10) };
	},
	_renderBinaryImageUrl: function(container, src, options) {
		var srcUrl = options.src ? options.src : src;
		srcUrl = srcUrl.indexOf("/") === -1 ? "/%0".format(srcUrl) : srcUrl; // for IE. 
		var image_dimensions = macro._image_dimensions[srcUrl];
		var image = new Image(); // due to weird scaling issues where you use just a width or just a height
		var createImageTag = function(dimensions, error) {
			if(error) {
				var altImage = options.altImage;
				if(altImage) {
					delete options.altImage;
					macro._renderBinaryImageUrl(container, altImage, options);
				} else {
					options.src = src;
					macro._renderAlternateText(container, options);
				}
			} else {
				var dim = macro._getDimensions(dimensions, { 
					width: options.width, height: options.height }, options.preserveAspectRatio);
				options.srcUrl = srcUrl;
				macro._renderImageTag(container, src, dim.width, dim.height, options);
			}
		};

		if(!image_dimensions) {
			image.onload = function() {
				var dimensions = { width: image.width, height: image.height};
				macro._image_dimensions[srcUrl] = dimensions;
				createImageTag(dimensions);
			};
			image.onerror = function() {
				createImageTag(null, true);
			};
			image.src = src;
		} else {
			createImageTag(image_dimensions);
		}
	},
	_generateIdPrefix: function(){
		return "twsvgfix_" + (this._fixPrefix++).toString() + "_";
	},
	_fixSVG: function(childNodes, idPrefix) {
		var urlPattern = /url\(\#([^\)]*)\)*/ig;
		var fixes = [
		{ attr: "id", pattern: /^(.*)$/ig },
		{ attr: "href", namespace: macro.xlinkns, pattern: /^#(.*)$/ig }
		];
		var url_fixes = ["filter", "fill", "mask", "stroke", "style"];
		for(var i = 0; i < url_fixes.length; i++) {
			fixes.push({ attr: url_fixes[i], pattern: urlPattern });
		}
		for(var t = 0; t < childNodes.length; t++) {
			var node = childNodes[t];
			for(var a = 0; a < fixes.length; a++) {
				var fix = fixes[a];
				var attr = fix.attr;
				var ns = fix.namespace || "";
				if(node.hasAttributeNS && node.hasAttributeNS(ns, attr)) {
					var v = node.getAttributeNS(ns, attr);
					fix.pattern.lastIndex = 0;
					var match = fix.pattern.exec(v);
					if(match) {
						// Make sure replacement string doesn't contain any single dollar signs
						var toReplace = match[1];
						if(toReplace.indexOf(idPrefix) !== 0 && toReplace.indexOf("twglobal_") !== 0) {
							var replacement = (idPrefix + toReplace).replace("$", "$$$$"); 
							v = v.replace(match[1], replacement);
						}
						node.setAttributeNS(ns, attr,v);
					}
				}
			}
			var children = node.childNodes;
			if(children.length > 0) {
				this._fixSVG(children, idPrefix);
			}
		}
	},
	_importSVG: function(place, options){
		options = options ? options : {};
		var svgDoc, tiddlerText = options.tiddler.text;
		if (window.DOMParser) {
			svgDoc = new DOMParser().parseFromString(tiddlerText, "application/xml").documentElement;
			var idPrefix = options.idPrefix || this._generateIdPrefix();
			this._fixSVG([svgDoc], idPrefix);
			var el = document.importNode(svgDoc, true);
			var svgHolder = document.createElementNS(macro.svgns,"svg");
			var width = options.width;
			var height = options.height;
			if(width || height) {
				if(width && height) { // set view box of containing svg element based on the svg viewbox and width and height.
					var viewBox = el.getAttribute("viewBox");
					var topLeft = "0 0";
					if(viewBox) {
						topLeft = viewBox.replace(/([0-9]*) +([0-9]*) +([0-9]*) +([0-9]*) */gi,"$1 $2");
					}
					svgHolder.setAttributeNS(macro.svgns, "viewBox", "0 0 %0 %1".format(width, height));
				} else {
					if(!width) {
						width = el.getAttribute("width");
					}
					if(!height) {
						height = el.getAttribute("height");
					}
				}
				svgHolder.setAttribute("width", width);
				svgHolder.setAttribute("height", height);

				el.setAttribute("width", "100%");
				el.setAttribute("height", "100%");
				svgHolder.setAttribute("class", "svgImage svgIcon %0".format(options.imageClass || ""));
				svgHolder.appendChild(el);
				place.appendChild(svgHolder);
			}
			else {
				var existing = el.className ? el.className.baseVal : "";
				el.setAttribute("class","svgImage %0".format(existing));
				place.appendChild(el);
			}
			// if a tiddler attribute is set this is read as a link
			$("[tiddler], [tiddlyLink]", place).attr("refresh", "link").click(function(ev) {
				var tiddler = $(ev.target).attr("tiddlyLink");
				if(tiddler) {
					story.displayTiddler(ev.target, tiddler);
				}
			});
		}
	},
	getArguments: function(paramString, params) {
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var options = {};
		for(var id in args) {
			if(true) {
				var p = args[id];
				if(id == "def") {
					options[id] = p;
				} else {
					options[id] = p[0];
				}
			}
		}
		var width = isNaN(params[1]) ? false : parseInt(params[1], 10);
		var height = isNaN(params[2]) ? false : parseInt(params[2], 10);

		options.width = macro.lookupArgument(options, "width", width);
		options.height = macro.lookupArgument(options, "height", height);
		options.preserveAspectRatio = args.preserveAspectRatio && 
			args.preserveAspectRatio[0] == "yes" ? true : false;
		options.tiddlyLink = macro.lookupArgument(options, "tiddlyLink", false);
		options.link = macro.lookupArgument(options, "link", false);
		return options;
	},
	lookupArgument: function(args, id, ifEmpty) {
		return args[id] ? args[id] : ifEmpty;
	}
};

// update views
var _oldwikifiedview = config.macros.view.views.wikified;
// update wikifier to check tiddler type before rendering
merge(config.macros.view.views, {
	wikified: function(value, place, params, wikifier, paramString, tiddler) {
		if(macro.isImageTiddler(tiddler) && params[0] == "text") {
			var newplace = $("<div />").addClass("wikifiedImage").appendTo(place)[0];
			macro.renderImage(newplace, tiddler.title, { alt: macro.locale.badImage });
		} else {
			_oldwikifiedview.apply(this, arguments);
		}
	},
	image: function(value, place, params, wikifier, paramString, tiddler) {
		// a field can point to another tiddler whereas text is the current tiddler.
		var title = params[0] == "text" ? tiddler.title : value;
		var args = macro.getArguments(paramString, params);
		macro.renderImage(place, title, args);
	}
});
config.shadowTiddlers.StyleSheetImageMacro = [".wikifiedImage svg, .wikifiedImage .image { width: 80%; }",
	".svgImageText { background-color:[[ColorPalette::Error]]; color:#ddd; display: inline-block; }",
	"span.svgImageText { display: inline-block; overflow: hidden; }"
].join("");
store.addNotification("StyleSheetImageMacro", refreshStyles);

})(jQuery);
//}}}
There is now an [[Open University 'set'|http://moodle.org/plugins/browse.php?list=set&id=10&p=0]] at moodle.org
!!Reports
!!!Reports: Dates
report_editdates
This 'report' is actually a tool to let you edit all the dates in a course on one page.
!!!Reports: Groups
report_editgroups
This 'report' is actually a tool to let you edit all the groups in a course on one page.
!!!Reports: ID Numbers
report_editidnumber
This 'report' is actually a tool to let you edit all the idnumbers in a course on one page.
/*{{{*/
Background: #f4eae0
Foreground: #1e140a
PrimaryPale: #f2e6db
PrimaryLight: #cc9d71
PrimaryMid: #81562d
PrimaryDark: #170f08
SecondaryPale: #e8dbf2
SecondaryLight: #a671cc
SecondaryMid: #5e2d81
SecondaryDark: #110817
TertiaryPale: #dbf2e4
TertiaryLight: #71cc94
TertiaryMid: #2d814d
TertiaryDark: #08170e
Error: #f88
ColorPaletteParameters: HSL([29|66], [0.47786494445483074|0.47786494445483074|0.47786494445483074|0.47786494445483074],[0.06266896796002441|0.34339107020882237|0.6241131724576203|0.9048352747064183])
/*}}}*/
Unless you're delighted with the default theme you can make some quick changes by generating a new random color palette, hit this button to cycle through some alternatives.

<<RandomColorPaletteButton saturation_pale:0.67 saturation_light:0.53
saturation_mid:0.43 saturation_dark:0.06 pale:0.99 light:0.85 mid:0.5 dark:0.31>>

You can also change the look and feel completely by installing a new theme. To do this, find one you like in the @themes space, note down the name, and include it in this space by going to the space menu. You can reach the space menu by clicking on the blue and pink circle at the top-right of the page and chooshing "THIS SPACE". Here are a few to check out:
* @pip
* @caspian-ii
* @basalt
* @simplicity
* @cheesecake
* @jelly-doughnut

(//Note that if you are using a custom TiddlySpace install, these themes may not be present.//)
In [[this blog posting|http://learn.open.ac.uk/mod/oublog/viewpost.php?post=115734]] says that :
<<<
Moodle 2.3 is about to be released but the OU will not be using it immediately. //There are  changes in Moodle 2.3 which break some of our modules, especially ForumNG//. If you rely on our modules and don't want to do without them, it would be advisable not to upgrade to 2.3 until we do.
<<<
and 
<<<
I would expect that we will have 2.3-compatible but untested versions of these modules in our code repositories at some point during September. It looks likely that our first 2.3 stable branch will be in early December.
<<<
So, don't even consider until December. Hopefully roll out for Spring 2013.
----
{{ts{19/12/12 14:10}}}
Looks like all the [[moodleou on github|https://github.com/moodleou]] is now 2.3 compatible.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="918 510 14 14" width="14pt" height="14pt"><metadata xmlns:dc="http://purl.org/dc/elements/1.1/"><dc:date>2010-06-06 13:07Z</dc:date><!-- Produced by OmniGraffle Professional 5.2.2 --></metadata><defs><radialGradient cx="0" cy="0" r="1" id="Gradient" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="white"/><stop offset="1" stop-color="#2b2b2b"/></radialGradient><radialGradient id="Obj_Gradient" xl:href="#Gradient" gradientTransform="translate(922.3752 513.7837) scale(11.4739436)"/></defs><g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1"><g><path d="M 929.6952 512.9018 C 927.1568 510.36337 923.0412 510.36337 920.5028 512.9018 C 917.9644 515.4402 917.9644 519.5558 920.5028 522.09418 C 923.0412 524.63257 927.1568 524.63257 929.6952 522.09418 C 932.2336 519.5558 932.2336 515.4402 929.6952 512.9018 M 925.099 515.7425 L 927.17633 513.66516 L 928.9318 515.42065 L 926.8545 517.498 L 928.9318 519.57532 L 927.17633 521.3308 L 925.099 519.25348 L 923.02167 521.3308 L 921.2662 519.57532 L 923.3435 517.498 L 921.2662 515.42065 L 923.02167 513.66516 Z" fill="url(#Obj_Gradient)"/></g></g></svg>
iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAEZ0FNQQAAsY58+1GTAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAACBpJREFUeNrtWXtMW+cVP9+1r40dwHZ4+RkegULI0hI1qzqVrHFa7a+mSxq1atU8iNRK09ZN3XtJK41oTRtN+yPVpHWTOmUeaH901bKu/+yPdiYNWjo1bR48mgLhEcAYA8EYQ/CD++18n7nXBoyvHQj/bEe63HvN9/h95zvn951zLsD/ZXOErHeA1/7s3UOJ9BQ+1gIlDThiBT7npTSZxGuEAmkHkIZoXHj/7An34KaDbj7vNUe00ksEyHF8rcNLm+MQ7bjAP+pc0NrsdsfvK+jm97z5sSj8nFL6Kr7mLx+JUHNhARjy9ESn04NW1EA0GgNJWoTZ8DzMzc3D4uLiysn9QOlp0SW8mwv4rEG/3uLdJxF6Hijffi5arVaylhYLDpsVCgryQaPRrNkfFwrBYAhGfD4YG5/g7ykg/hkj5OVfH3GPbBjok60f/4JQ8ivZDBjY6qpyweWwgyAIOZtXJBKF4VEf9A/eVsAzrROJHH3juPujdYM+1ep9B0f+jvzudNilupoqIZNWs5XZcBg6ur7id2VHCHn2rSPu9zP102QLmAgCfXDnDlJV4SL3ot10otfpUAk2tHsJgjMhWYvPNB5uutr+N09PzqBPtXzcjLefyObw9YZdQknx1o3nXEKgaKsFRFELk1PT7CcBgT+991DTh5cueAJZg2bci0v2sAE0gkbag4DNZtN9PTDMpkJ+nw7OsJsOr/1PvNDkafurJ7qyrZCO1ijQFtnpdtbX3nfAslRXVYCtrET2trpIBN5K124V6EhUeoV1YM8upz05yCbJjtoa0Ot1S7jpK3zXV4h2pZajEfo9bjeiltZWV2XN44voTKNjk+AP3MEtDkMsFud0aDHlQ1mpBbY5StE31BlHFEWoe6AGrnd0Lf0i/RL/HFjTph/79rHv4vqeS2xVOSmyWLIC3Dfgg08u34Ch4XFkgTAsIA8z0OxEnJmdA59/irdhp2SRpVB1vPwtRpiaDsLCQoR56vbHnmn6S/sFz5205kEpeZH/qNHQcqdDdXAqUbj8WTd8fr2Hg5TFoNdCUUEev8vC/v/F9V7492ddfFfUpKZSOXg1SCc/Tqvpn7V6nbiCswyzw1ZGykrVbfnTK1/C7dEEKwk4cmO9A47ur4dDj1bD/oe2wbd2l8MjD1hBqxFgMBACdviFZud5LOK0lXC6W0sMhjwYn5jku4VSiUzyO5lJFE2LVDoo27jdas3KJFIB/+BAAzz/zVqwb93C32UpMRng0Deq4UcHHwa9mNDR8OgE9A35VOewJhVXhBa3b5V5SFTYzlWPx7PJVKDqdDe6+xXArz69G2rsme2/sqwQvn9gN4iaxJQd3QPLTCqd2K1lSZqj8Pgq0BhZNrK70WBQDYKYpuQJ96JJbLeZs3JYBvzxXU7Fxod9ExnbMxPB0zihVKB70jkit/yCfKPq5IHJaeW5cacjJx5mdi/LeGBatX1BwRY5JnGmA13Mgxi9XnUgxsMyS1jNxpxAMxuXWWV6Jqza3mhQMjfXmieioFGP4GTTMOq0y5wuW2H9+JZnQX06UacEhWuClhbVB2IRGZP5aBwnpjmDZv0STqyuoHRKTP1lIZFVRFQHspgT6eHdSBz8wfmcAE/M3OX9+DimfNX26ZSYBE2Bp/VzdxdUByotTtJbe9dobml4d7I9i0nUJBpTItNgGspLgJ6dDavamstRopjIJQRxayyYFeCB8RBc7BhRTMxlVz912em5JIOrNU3IFdk55uYzb7kGbfHB+qolZ6Jw7h9XVYEzwL/98CrElrZ7V32lsvBMGTwrPSQMgRV7Vmp6ES4m+XNSPWCvtPNwMxX4e5d6YHyFjU/NLsCFy33w9gdfQCS2qOxUdblddY5QaDalViINrYqntRK0xwTwIxdYx/wBnkWoyaMP70ANUH5CMuAXO0f4xXiY0RpjCdnpUk3rkd11mCirU+WwLxmfYDb90aoor+0DT3zv4WNfw383xOJxzNlMYDQaVJNSF2pbrxdh8k5I8YU4msBdBBxP8XxmCg27tsNDO6owvlGnujhi6LrZK4957c0j+0+nzVxwOW+jITUlorhBKC7KLgmoqXRAVbmNa3wcM5dgaG5Z5lJSbIZyZ6mqDafK6JifA1+Kizxrpltvvui+drLlX224cftmZkK8fJVtjsics8JVxq/1CgN7a+C2QnViTPhTxsRWoOSnrB97/vKrXl7C2mzpvTWIOxVLaJmS3zefcAczgj5zzH2FADmXiDFicLOnd1MBBybv8DqfnGuIeXBGtYTAncYJJ/HWyZ79SH99/YObApjV9G50dieLkpScaH7OHc6qwtTm8Uh7DzVdwiCWZeZGVvVhGY3lPhZtgjjH59c6U5yPvHHmqNuTVbFGccpj7k5BIi/gI19pT18/v1LryhslzOGvXOtQ7BjPv1bRAafvqWr6yd89/Y2Hm3pZJZMtkFU2AxNTYDYX8orneoWddp3dN5EphlKUQd/VOYWXM30ZyCqCf93jfVIS6HlYSnnYoVKxzQmsqG4w5OUMlgEcHRtHXxlYxk7Ixz88c+SJcxvyJUCui4iS9A4l5KnUWWylxcRus8FWi0k1qA+H52DE50fnDiwHy7+9kGeRudqzKg/nqqVTLd6X0K1fS/32IlelthgMhCXGLM9kGQcL4Fk8PDe/wIOfNCFvHBniN4zW0rHEhoHmhUqvVxsdhecxWDpOKDyZcyGdaRZIK8Zvfzh71N13D/3XJ9xsqHSQFXuWaicVcmavpHGYFbEkAxf5HwGENm0cPsVTbgH+l+S/c0hKbtisAOEAAAAASUVORK5CYII=
It's been really hard to find a Moodle theme which has been explicitly designed for accessibility and screen readers. Basically, I'm looking for a theme that is designed explicitly for Screen Readers to make the process of course creation and maintenance in Moodle 2 as straightforward as possible for Teacher who is partially sighted.
There's lots of places that tell you what you ought to do, but little concrete outcomes.
But here are some links:
* The Forum posting [[New Accessibility Themes|https://moodle.org/mod/forum/discuss.php?d=85119]] is from 2007 and refers to themes for Moodle 1.9. The download link refers to a student account at the College of North West London and, not surprisingly does not work. Also a link to the [[JISC TechDis site|http://www.jisctechdis.ac.uk/]] -- see below.
* The Forum posting [[Accessibility and Moodle 2+ themes|https://moodle.org/mod/forum/discuss.php?d=189177]] from Oct 2011 was similarly not very helpful. Interestingly, Mary Cooch's response "there are no themes built with just accessibility in mind" makes me wonder whether this is a hole waiting to be filled.
* [[Univ Bath : Designing accessible e-learning materials|http://blogs.bath.ac.uk/elearninghowto/2009/03/09/designing-accessible-e-learning-materials/]] but this is from 2009 +++[some useful links from here:]>
If you would like to test out resources using a screenreader, then download Thunder, a free screenreader, at http://www.screenreader.net/  which also comes with Webbie, a text browser (http://www.webbie.org.uk/ )
Natural Reader is text-to-speech software. The free version can be downloaded at http://www.naturalreaders.com/ and will read text aloud e.g. from a Word document
Dspeech (which can be downloaded from http://dimio.altervista.org/eng/ ) is a free text-to-speech program which also allows you to convert your text to an MP3 file, if you wish to provide audio alternatives for text.
=== 
* [[Web Accessbility and Evaluation Tool (WAVE)|http://wave.webaim.org/help]] . There's also a useful Firefox plugin.
* Mark Johnson's [[Accessibility block|https://moodle.org/plugins/pluginversions.php?plugin=block_accessibility]]
* Interesting conversation but not a lot of help : [[Universal Design for Learning and Moodle|https://moodle.org/mod/forum/discuss.php?d=205677]]. Karl O'Keeffe seems to be doing work in this area.
* [[Learning Different e-Learning Portal|http://www.learndifferent.net/moodleCSU6703/course/view.php?id=3]] (login as Guest) for users with disabilities rather than Teachers.
* From the UK, the JISC Techdis Inclusion technology advice site [[Is Moodle accessible|http://www.jisctechdis.ac.uk/techdis/pages/detail/floating_pages/Is_Moodle_Accessible]] is a case in point. Links to [[Moodle Accessiblity pages|http://docs.moodle.org/24/en/Moodle_Accessibility_Specification]] -- ''empty'' (but [[Accessbility page|http://docs.moodle.org/dev/Accessibility]] does have lots of content -- or the Univ Bath (see above) are less than helpful. Again, most of this assumes that the Teacher is able and the students are needing accessibilty help.
** [[Accessibility Essentials|http://www.jisctechdis.ac.uk/techdis/resources/ae]] deals with the +++[following useful issues]>
* Making Electronic Documents More Readable
* Writing Accessible Electronic Documents with Microsoft® Word
* Creating Accessible Presentations
* ''Making the Most of PDFs''
=== The [[complete series of guides|http://accessibilityessentials.jisctechdis.ac.uk/]] for Office 2003 and 2007.
* Bob Puffer just ({{ts{18/03/13 15:38}}}) posted a link to [[A Comparison of Learning Management System Accessibility|http://blog.bargirangin.com/2013/03/a-comparison-of-learning-management.html]] which is an interesting comparison of Blackboard, Desire2Learn, Moodle and SAKAI.
** Also this [[A Model for Accessible LMS Discussion Boards|http://blog.bargirangin.com/2013/03/a-model-for-accessible-lms-discussion.html]] and this demo mockup [[Accessible Discussion Board|https://dl.dropbox.com/u/137779786/discussion_module_mockup/discussion_board-listview.html]]

<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 40 40"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata><defs><linearGradient id="lG3826" x1="7.0996" gradientUnits="userSpaceOnUse" y1="18.829" gradientTransform="matrix(1.5858347,0,0,1.8078238,1098.1851,351.13716)" x2="1.5461" y2="-0.95166"><stop stop-color="#000" offset="0"/><stop stop-color="#9c9b99" offset="1"/></linearGradient><linearGradient id="lG3828" y2="372.44" gradientUnits="userSpaceOnUse" y1="375.7" x2="1111.7" x1="1097.7"><stop style="stop-color:#ac9393;" offset="0"/><stop style="stop-color:#c8b7b7;" offset="1"/></linearGradient></defs><g transform="translate(-1080.9375,-357.3329)"><path style="stroke-width:0;stroke-miterlimit:4;fill:url(#lG3826);" d="m1080.9,357.32,39.996-0.0426-0.01,40.008c-15.507-25.519-15.36-25.95-39.988-39.965z"/><path style="stroke-dashoffset:0;stroke:#7aa3be;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.49999988;fill:#c1e6fd;" d="m1091.9,363.55c6.5716-6.4925,16.576-7.3925,23.147-0.90003,6.5717,6.4925,6.5717,17.019,0,23.511-4.4424-8.6113-12.288-15.713-23.147-22.611z"/><path style="stroke-dashoffset:0;stroke:#ce81b0;stroke-linecap:round;stroke-miterlimit:4;stroke-width:1.5;fill:#f4c4e2;" d="m1110.2,367.62c3.217,3.2168,3.217,8.4323,0,11.649-3.8194-4.2357-8.3307-8.1824-11.649-11.649,3.217-3.2168,8.4325-3.2168,11.649-0.00002z"/><path style="stroke-linejoin:bevel;stroke:#000000;stroke-linecap:round;stroke-dasharray:none;stroke-miterlimit:4;stroke-width:0.80000001;fill:url(#lG3828);" d="m1081,357.34c18.79,6.4752,32.53,16.56,39.894,39.892-11.19-17.028-14.878-19.19-27.352-14.96,6.2984-12.098,3.9371-13.19-12.542-24.932z"/></g></svg>
/***
|Name|ShowUpdatesPlugin|
|Created by|SaqImtiaz|
|Version|0.2 |
|Requires|~TW2.x|
!!!Description:
Allows you to list tiddlers that have changed since the users last visit. You can list only all changed tiddlers, or filter them to only show tiddlers that have or do not have a specific tag. By default a simple list of the titles of changed tiddlers is created. However, using an extremely versatile syntax you can provide a custom template for the generated text.

!!!Examples: 
[[ShowUpdatesDocs]]

!!!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.

!!!Syntax:
{{{<<showUpdates>>}}}
additional optional params:
{{{<showUpdates excludeTag:TagToExclude onlyTag:TagToList maxEntries:10 write:CustomWriteParameter >>}}}
excludeTag: ~TagToExclude
onlyTag: ~TagToList
maxEntries: max number of entries displayed when there are no updates. (default is 10, which can be changed in the config.macros.showUpdates.settings part of the code)
write: if a write parameter is not provided, an un-numbered list of the updates is generated. Alternatively, you can specify a custom 'template' for the text generated. The syntax for the write parameter is identical to that of the forEachTiddler macro. Additonal documentation on this syntax will be provided soon.
Some of the variables available in the write parameter are 'index', 'count' and 'lastVisit' where lastVisit is the date of the last visit in the format YYYYMMDDHHMM. Also areUpdates is a boolean that is true if there are new updates since the users last visit.

!!!To Do:
*refactor code to facilitate translations
*a streamlined version without the custom write parameter


!!!Code
***/
//{{{
window.lewcidLastVisit = '';
window.old_lewcid_whatsnew_restart = window.restart;
window.restart = function()
{
        if(config.options.txtLastVisit)
                 lewcidLastVisit= config.options.txtLastVisit;
        config.options.txtLastVisit = (new Date()).convertToYYYYMMDDHHMM();
        saveOptionCookie('txtLastVisit');
        window.old_lewcid_whatsnew_restart();
}

TiddlyWiki.prototype.lewcidGetTiddlers = function(field,excludeTag,includeTag,updatesOnly)
{
              var results = [];
              this.forEachTiddler(function(title,tiddler)
                      {
                      if(excludeTag == undefined || !tiddler.isTagged(excludeTag))
                                    if(includeTag == undefined ||  tiddler.isTagged(includeTag))
                                            if ( updatesOnly == false || tiddler.modified.convertToYYYYMMDDHHMM()>lewcidLastVisit)
                                                  results.push(tiddler);
                      });
              if(field)
                  results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
              return results;
}

config.macros.showUpdates={};
config.macros.showUpdates.settings =
{
         maxEntries: 10  //max items to show, if there are no updates since last visit
}

config.macros.showUpdates.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
          var args = paramString.parseParams("list",null,true);
          var write = getParam(args, "write", undefined);
          var onlyTag = getParam(args, "onlyTag", undefined);
          var excludeTag = getParam(args, "excludeTag", undefined);
          var sortBy = "modified";
          var maxEntries = getParam(args,"maxEntries",this.settings.maxEntries);

          if (lewcidLastVisit) 
                {var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,true);
                 var areUpdates = tiddlers.length>0? true:false;}

          if (!lewcidLastVisit)
               {var countLine = "!!Recent Updates:";
               var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,false);
               var areUpdates = false;}
          else if (tiddlers.length == 0)
               {var countLine = "!!@@color:red;No new updates@@ since your last visit. @@color:#999;font-size:70%;" + (Date.convertFromYYYYMMDDHHMM(lewcidLastVisit)).formatString(" (DD/MM/YY)") + "@@\n!!Recent Updates:";
               var tiddlers = store.lewcidGetTiddlers(sortBy,excludeTag,onlyTag,false);}
          else
               {var countLine ="!!@@color:red;"+ tiddlers.length + "@@ new " + (tiddlers.length==1?"update":"updates") + " since your last visit: @@color:#999;font-size:70%;" + (Date.convertFromYYYYMMDDHHMM(lewcidLastVisit)).formatString(" (DD/MM/YY)") + "@@";}

          tiddlers = tiddlers.reverse();
          var lastVisit = lewcidLastVisit? lewcidLastVisit:undefined;
          var count = areUpdates == true? tiddlers.length : maxEntries;
          var sp = createTiddlyElement(place,"span","showUpdates");
          if (write==undefined)
                 {
                  wikify(countLine,sp);
                  var list = createTiddlyElement(sp,"ul");
                  for (var i = 0; i < count; i++)
                          {
                           var tiddler = tiddlers[i];
                           createTiddlyLink(createTiddlyElement(list,"li"), tiddler.title, true);
                          }
                 }
          else
                {
                 var list = '';
                 for (var index = 0; index < count; index++) {
                 var tiddler = tiddlers[index];
                 list += eval(write); }
                 wikify(list, sp);
                }
}
//}}}
!![[Owncloud|http://owncloud.org/]]
* [[features|http://owncloud.org/features/]] @@impressive@@
* [[Installation directions|http://owncloud.org/support/install/]] for Linux as well as MAMP!
* Moodle discussion [[owncloud.org as webdav repository|http://moodle.org/mod/forum/discuss.php?d=191623]]

{{ts{16/11/12 17:47}}}
[[ownCloud: An ‘academic dropbox’?|https://orbital.blogs.lincoln.ac.uk/2012/08/06/owncloud-an-academic-dropbox/]] -- interesting.
{{ts{28/02/13 15:27}}}
[[owncloud.org as webdav repository|https://moodle.org/mod/forum/discuss.php?d=191623]]
http://owncloud.org/news/
+++[Styling]
Style individual committees with
{{{
<div style="float: left; padding: 5px 5px; border-right: thin solid black;">Administrative Review Committee (ARC)</div>
}}}
But better to have central style defintion and then style each with a class. So:
In Site Admin > Appearance > Themes > Bootstrap (COnfiguration) : Custom CSS
{{{
.comdocs {
float: left; 
padding: 5px 5px; 
border-right: thin solid black;
}
}}}
And the HTML is now 
{{{<div class="comdocs">Administrative Review Committee (ARC)</div>}}}
=== 
!Procedure to move Comm Docs
!!On Moodle.earlham.edu
# Open [[Community Documents|https://moodle.earlham.edu/course/view.php?id=147]]
# Click on the Community resource to open, eg [[Earlham Student Government|https://moodle.earlham.edu/mod/resource/view.php?id=2553]]
# click [Edit files] to take you to the Files area
# click [Select all] to check all the boxes for sub directories
# select With chosen files -> create Zip archive. 
** Change the name from //new.zip// to the committee name, eg {{{Earlham Student Government}}} with //spaces// and capital letters. 
** Click [Create zip archive]
# Click on the zip file and Save to local machine
!! On moodle2 Pilot
We're trying to replicate the approximate layout of Community Docs on moodle2
# Open [[Community Docs on Moodle2|https://moodle2.earlham.edu/course/view.php?id=998]] -- try the Handy Links pulldown menu!
# Click [[Turn editing On]
# To change Topic Name hit the [Edit summary] button in the appropriate Topic section
** ''uncheck'' use default section name
** Type in Alphabetic Title. Set up Topic titles to be the same as in COMDOCS:2011
# With the Topic section visible and the previously downloaded zip file visible, @@drag@@ the zip file and @@drop@@ it into the appropriate topic section
** Choose //Unzip files and create folder// -- the default. Click [Upload]. ''BAM''
# Now hit the Pencil icon to Edit the title and press Ctrl-C to copy the highlighted text. Hit [Enter]
# Now you are going to add it to the list up at the top.
# Under the Community Documents table of contents you'll see an 'Edit summary' icon. Click this.
# Now strike the [HTML] (HTML Source) button manfully.
# Scroll to the bottom of the page and hit [Enter] to add a new line. Press Ctrl-V delicately. This is the link text to the folder you just created.
# Now you want to style it with the 'commdocs' style class so highlight {{{<div class="comdocs">}}} and copy
** paste in front of the text
# Highlight {{{</div>}}}
** paste behind the text. You should now have created something like {{{<div class="comdocs">Earlham Student Government</div>}}}
# Click [Update]
# Click [Save Changes]
** Lo and behold, your new entry is //automagically linked//

Repeat the process //ad finitum//

Advantages of using Moodle to track :
# Attendance. Participant list already there and easy to print. T.A can take attendance and you can check. Can convert to grade automatically. Student can see attendance record -- zero argument.
# Attendance & participation. Register class participation while it's still fresh in your mind. Simple scale allows objective assessment of participation. Convert directly to grade in gradebook. Up front and fair to all students.
!!Configuration
1. Create the Attendance activity (How?)  [Save and Display]
+++!![2. Add sessions]
[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/attendance-addsession.png]]
# Check 'Create multiple sessions'
# Choose the date and time //of the first class//. Note day-month-year euro format
# Choose the class duration time
# Choose End date -- Reading Day is a good date to choose here
# Check the days your class meets
# Most classes meet every week
# click [Add session] and all the sessions will be created
!!!Totals
* Mon / Wed / Fri, 3 class meetings per week -- 47 initial sessions
* Tues / Thurs, 2 class meetings per week -- 31 initial sessions
Now remove individual session for mid term and Fall breaks
* Mon / Wed / Fri, 4 sessions removed. Net total @@43 class meetings@@
* Tues / Thurs, 3 sessions removed. Net total @@28 class sessions@@
=== 
+++!![3. Settings : Participation levels]
Suggest three levels of participation and two absences :
|!Participation Level|!Description #1|!Description #2|
| 1 |Participation -- Active|comments or questions relevant and insightful (good)|
| 2 |Participation -- Neutral|comments or questions relevant, but didn’t involve much insight (average)|
| 3 |Participation -- Unsatisfactory|minimal response (1-2 words), no depth (below average)|
| E | Excused absence | Excused absence |
| A | Absent |absent; didn't participate at all; off-task|
!!Add variables
* go to ''Settings'' tab
* use [Add] and [Update] to add Participation descriptors and Acronyms like this:
[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/attendance-settings-nograde-small.png]]
!!Grading participation
Depending on the frequency of class meetings and therefore the total number of class sessions, the pints settings for each participation level will be different.
|!Participation Level|!Description #1|!points for 3 classes/wk|!points for 2 classes/week|
| 1 |Participation -- Active| ''2'' | ''3'' |
| 2 |Participation -- Neutral| ''-2'' | ''-1'' |
| 3 |Participation -- Unsatisfactory| ''-3'' | ''-2'' |
| E | Excused absence | ''-3'' | ''-2'' |
| A | Absent | ''-5'' | ''-4'' |
[[More details|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bGrading%20Participation%5d%5d]]
Fill in the grade levels with the appropriate value and click [Update]
!!Effect on final grade (2 sessions / week course)
These two screenshots show how absences and participation affect final grade (for a 2 sessions/week course)
* [[Effect of absences & participation: neutral|http://legacy.earlham.edu/~markp/moodledocs/graphics/attendance-effect-A-PN.png]]<<imagebox>>
* [[Effect of excused absences & participation: unsatisfactory|http://legacy.earlham.edu/~markp/moodledocs/graphics/attendance-effect-PU-E.png]]<<imagebox>>
!!!Summary
|!|!|>|>|!Grade for|
|!#|!Attendance variable|!1 instance|!2 instances|!3 instances|
| 1 |Participation -- Active| A | A | A |
| 2 |Participation -- Neutral| ''A'' | ''A-'' | ''B'' |
| 3 |Participation -- Unsatisfactory| ''A'' | ''B+'' | ''B-'' |
| E | Excused absence | ''A'' | ''B+'' | ''B-'' |
| A | Absent | ''A-'' | ''B'' | ''C'' |
=== 
4. Taking Attendance / Participation
5. Using Report
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" style="stroke-dasharray:none;" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" fill="none">
  <path id="path2855" style="stroke-dasharray:none;" d="m-21.958,17.211a9.5984,2.6909,0,1,1,-0.0051,0.0064" transform="matrix(0.780457, 0, 0, 1.24977, 37.521, 38.2999)" stroke-width="2.0250746"/>
  <path id="path3642" style="stroke-dasharray:none;" d="m-32.658,7.2382a0.85997,0.85997,0,1,1,-0.00046,0.00205" transform="matrix(0.8, 0, 0, 0.8, 53.2133, 54.7178)" stroke-width="2.5"/>
  <path id="path3646" style="stroke-dasharray:none;" d="m19.258,53.669,1.0653,2.6187" stroke-width="2"/>
  <path id="path3648" style="stroke-dasharray:none;" d="m36.573,53.936-1.6958,2.262" stroke-width="2"/>
  <path id="path3650" style="stroke-dasharray:none;" d="m32.711,51.8-1.1627,3.0268" stroke-width="2"/>
  <path id="path3654" style="stroke-dasharray:none;" d="m27.789,51.268,0.16048,3.2032" stroke-width="2"/>
  <path id="path3658" style="stroke-dasharray:none;" d="m23.014,51.839,0.83281,3.1279" stroke-width="2"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
/***
|Name|DisableWikiLinksPlugin|
|Source|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|Version|1.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|selectively disable TiddlyWiki's automatic ~WikiWord linking behavior|
This plugin allows you to disable TiddlyWiki's automatic ~WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links.  To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.
!!!!!Usage
<<<
You can block automatic WikiWord linking behavior for any specific tiddler by ''tagging it with<<tag excludeWikiWords>>'' (see configuration below) or, check a plugin option to disable automatic WikiWord links to non-existing tiddler titles, while still linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles.  You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]] (see configuration below), separated by whitespace.  This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.  

Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)
<<<
!!!!!Configuration
<<<
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords //contained in// shadow tiddlers
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
Disable automatic WikiWord links for words listed in: <<option txtDisableWikiLinksList>>
Disable automatic WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>
<<<
!!!!!Revisions
<<<
2008.07.22 [1.6.0] hijack tiddler changed() method to filter disabled wiki words from internal links[] array (so they won't appear in the missing tiddlers list)
2007.06.09 [1.5.0] added configurable txtDisableWikiLinksTag (default value: "excludeWikiWords") to allows selective disabling of automatic WikiWord links for any tiddler tagged with that value.
2006.12.31 [1.4.0] in formatter, test for chkDisableNonExistingWikiLinks
2006.12.09 [1.3.0] in formatter, test for excluded wiki words specified in DisableWikiLinksList
2006.12.09 [1.2.2] fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).  
2006.12.09 [1.2.1] revised logic for handling links in shadow content
2006.12.08 [1.2.0] added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
2006.05.24 [1.1.0] added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
2006.02.05 [1.0.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.09 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.DisableWikiLinksPlugin= {major: 1, minor: 6, revision: 0, date: new Date(2008,7,22)};

if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks=false;
if (config.options.txtDisableWikiLinksList==undefined) config.options.txtDisableWikiLinksList="DisableWikiLinksList";
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;
if (config.options.txtDisableWikiLinksTag==undefined) config.options.txtDisableWikiLinksTag="excludeWikiWords";

// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
	config.formatters[i].coreHandler=config.formatters[i].handler;
	config.formatters[i].handler=function(w) {
		// supress any leading "~" (if present)
		var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
		var title=w.matchText.substr(skip);
		var exists=store.tiddlerExists(title);
		var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);
		// check for excluded Tiddler
		if (w.tiddler && w.tiddler.isTagged(config.options.txtDisableWikiLinksTag))
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		// check for specific excluded wiki words
		var t=store.getTiddlerText(config.options.txtDisableWikiLinksList);
		if (t && t.length && t.indexOf(w.matchText)!=-1)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		// if not disabling links from shadows (default setting)
		if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
			return this.coreHandler(w);
		// check for non-existing non-shadow tiddler
		if (config.options.chkDisableNonExistingWikiLinks && !exists)
			{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
		// if not enabled, just do standard WikiWord link formatting
		if (!config.options.chkDisableWikiLinks)
			return this.coreHandler(w);
		// just return text without linking
		w.outputText(w.output,w.matchStart+skip,w.nextMatch)
	}
}

Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
	// if all automatic links are not disabled, just return results from core function
	if (!config.options.chkDisableWikiLinks)
		return this.coreAutoLinkWikiWords.apply(this,arguments);
	return false;
}

Tiddler.prototype.disableWikiLinks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
	this.disableWikiLinks_changed.apply(this,arguments);
	// remove excluded wiki words from links array
	var t=store.getTiddlerText(config.options.txtDisableWikiLinksList,"").readBracketedList();
	if (t.length) for (var i=0; i<t.length; i++)
		if (this.links.contains(t[i]))
			this.links.splice(this.links.indexOf(t[i]),1);
};
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke-miterlimit="4">
  <g id="g2873" transform="translate(-5.75544, -1.55954)" stroke="#A00">
   <path id="path2875" style="stroke-dasharray:none;" d="m32.71,59.791c0,0.71068-0.57612,1.2868-1.2868,1.2868s-1.2868-0.57612-1.2868-1.2868,0.57612-1.2868,1.2868-1.2868,1.2868,0.57612,1.2868,1.2868z" fill-rule="evenodd" transform="matrix(0.844979, 0, 0, 0.844979, 6.38812, 2.07297)" stroke-linecap="round" stroke-width="4" fill="#CCC"/>
   <rect id="rect2877" style="stroke-dasharray:none;" ry="1.4818" height="8.8906" width="5.1947" stroke-linecap="butt" y="55.64" x="30.465" stroke-width="1.4708" fill="none"/>
  </g>
  <g id="g2867" stroke="#4d4d4d" transform="translate(-10.5083, 1.70807)">
   <path id="path2869" style="stroke-dasharray:none;" d="m32.71,59.791c0,0.71068-0.57612,1.2868-1.2868,1.2868s-1.2868-0.57612-1.2868-1.2868,0.57612-1.2868,1.2868-1.2868,1.2868,0.57612,1.2868,1.2868z" fill-rule="evenodd" transform="matrix(0.844979, 0, 0, 0.844979, 6.38812, 2.07297)" stroke-linecap="round" stroke-width="4" fill="#CCC"/>
   <rect id="rect2871" style="stroke-dasharray:none;" ry="1.4818" height="8.8906" width="5.1947" stroke-linecap="butt" y="55.64" x="30.465" stroke-width="1.4708" fill="none"/>
  </g>
  <g id="g3620" stroke="#4d4d4d" transform="translate(0.259923, -0.148528)">
   <path id="path3288" style="stroke-dasharray:none;" d="m32.71,59.791c0,0.71068-0.57612,1.2868-1.2868,1.2868s-1.2868-0.57612-1.2868-1.2868,0.57612-1.2868,1.2868-1.2868,1.2868,0.57612,1.2868,1.2868z" fill-rule="evenodd" transform="matrix(0.844979, 0, 0, 0.844979, 6.38812, 2.07297)" stroke-linecap="round" stroke-width="4" fill="#CCC"/>
   <rect id="rect3629" style="stroke-dasharray:none;" ry="1.4818" height="8.8906" width="5.1947" stroke-linecap="butt" y="55.64" x="30.465" stroke-width="1.4708" fill="none"/>
  </g>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4">
  <path id="path3640" style="stroke-dasharray:none;" d="m21.877,50.312,0,14.926" stroke-width="2.50369096" fill="none"/>
  <rect id="rect3642" style="stroke-dasharray:none;" transform="matrix(0.707107, -0.707107, 0.707107, 0.707107, 0, 0)" ry="0" height="2.1305" width="2.1305" y="59.855" x="-17.174" stroke-width="2.4" fill="none"/>
  <rect id="rect3644" ry="0" style="stroke-dasharray:none;" transform="matrix(0.707107, -0.707107, 0.707107, 0.707107, 0, 0)" height="2.1305" width="2.1305" y="66.038" x="-23.357" stroke-width="2.4" fill="none"/>
  <path id="path3646" style="stroke-dasharray:none;" d="m22.664,54.557,3.0416,0" stroke-width="2.4" fill="none"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
<<paletteView ColorPalette>>
There are a lot of interesting people using ~TiddlySpace that you might like to keep track of and interact with. There are a number of ways of doing this.

If you see a number in the speech bubble in one of your tiddlers, it means that someone is writing about the same thing as you. You can find out what they're saying by clicking on it. Likewise, if you see something interesting in someone else's space, you can respond to it and write up your own thoughts on the subject by clicking "Reply to this tiddler".

Additionally, if you find anyone interesting, or you find an interesting looking space and you'd like to know when it's changed, you can "follow" that space. To do this, simply create a tiddler with the title: {{{@space-name}}} and tag it {{{follow}}}. If you want, you can store some notes about that space in the body of the tiddler.

If you then want to know what happening, simply [[include|How do I include/exclude spaces?]]@docs the @tivity space and then visit your activity stream at [[/activity|/activity]], or just visit the @tapas space directly.

!Not sure who to follow?
Here's a few suggestions:
* @fnd
* @cdent
* @pmario
* @bengillies
* @dickon
/***
|''Name''|TiddlySpaceFollowingPlugin|
|''Version''|0.7.1|
|''Description''|Provides a following macro|
|''Author''|Jon Robson|
|''Requires''|TiddlySpaceConfig TiddlySpaceTiddlerIconsPlugin ErrorHandler|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
Tag a tiddler with "follow" to express a list of followers.
Using the {{{<<followTiddlers X>>}}}
will reveal the number of tiddlers with name X in the set of spaces the *current* user viewing your space follows.
{{{<<following jon>>}}} will list all the users following Jon.
{{{<<followers jon>>}}} will list all the followers of jon.
{{{<linkedTiddlers>>}}} will list all tiddlers across TiddlySpace linked to the current tiddler
{{{<linkedTiddlers follow:yes>>}}} will list all tiddlers across TiddlySpace that come from your list of followers
adds spaceLink view type {{{<<view server.bag spaceLink>>}}} creates a link to the space described in server.bag
{{{<<view server.bag spaceLink title>>}}} makes a link to the tiddler with title expressed in the field title in space server.bag
If no name is given eg. {{{<<following>>}}} or {{{<<follow>>}}} it will default the current user.
!StyleSheet
.followTiddlersList li {
	list-style:none;
}

.followButton {
	width: 2em;
}

.followTiddlersList li .siteIcon {
	height:48px;
	width: 48px;
}

#sidebarTabs .followers li a,
.followers .siteIcon,
.followers .siteIcon div {
	display: inline;
}

.followTiddlersList li .externalImage, .followTiddlersList li .image {
	display: inline;
}

.scanResults li {
	list-style: none;
}
!Code
***/
//{{{
(function($) {
var LIMIT_FOLLOWING = 100;

var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;

var shadows = config.shadowTiddlers;
config.annotations.ScanTemplate = "This tiddler is the default template used in the display of tiddlers founding using the tsScan macro. To access attributes use the view macro e.g. {{{<<view title text>>}}}";
shadows.ScanTemplate = "<<view modifier SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title link>>";
shadows.FollowersTemplate = "<<view server.bag SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view server.bag spaceLink>>";
shadows.FollowingTemplate = "<<view title SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title spaceLink>>";
shadows.FollowTiddlersBlackList = "";
shadows.FollowTiddlersHeading = "There are tiddlers in spaces you follow using the follow tag which use the title <<view title text>>";
shadows.FollowTiddlersTemplate = ["* <<view server.space SiteIcon width:24 height:24 spaceLink:yes label:no>> ",
	"<<view server.space spaceLink title external:no>> modified by <<view modifier spaceLink>> ",
	"in the <<view server.space spaceLink>> space (<<view modified date>> @ <<view modified date 0hh:0mm>>).\n"].join("");

var name = "StyleSheetFollowing";
shadows[name] = "/*{{{*/\n%0\n/*}}}*/".
	format(store.getTiddlerText(tiddler.title + "##StyleSheet"));
store.addNotification(name, refreshStyles);

// provide support for sucking in tiddlers from the server
tiddlyspace.displayServerTiddler = function(src, title, workspace, callback) {
	var adaptor = store.getTiddlers()[0].getAdaptor();
	var localTitle = tiddlyspace.getLocalTitle(title, workspace);
	var tiddler = new Tiddler(localTitle);
	tiddler.text = "Please wait while this tiddler is retrieved...";
	tiddler.fields.doNotSave = "true";
	store.addTiddler(tiddler);
	src = story.displayTiddler(src || null, tiddler.title);
	tweb.getStatus(function(status) {
		var context = {
			host: tweb.host, // TODO: inherit from source tiddler?
			workspace: workspace,
			headers: { "X-ControlView": "false" }
		};
		var getCallback = function(context, userParams) {
			var tiddler = context.tiddler;
			tiddler.title = localTitle;
			store.addTiddler(tiddler);
			story.refreshTiddler(localTitle, null, true); // overriding existing allows updating
			if(callback) {
				callback(src, tiddler);
			}
		};
		adaptor.getTiddler(title, context, null, getCallback);
	});
};

tiddlyspace.scroller = {
	runHandler: function(title, top, bottom, height) {
		var i;
		var handlers = tiddlyspace.scroller.handlers;
		var tidEl = story.getTiddler(title);
		if(tidEl) {
			var topEl = $(tidEl).offset().top + 20;
			if(top === false || (topEl > top && topEl < bottom)) {
				var h = handlers[title];
				for(i = 0; i < h.length; i++) {
					h[i]();
				}
				tiddlyspace.scroller.clearHandlers(title);
			}
		} else {
			tiddlyspace.scroller.clearHandlers(title);
		}
	},
	clearHandlers: function(title) {
		tiddlyspace.scroller.handlers[title] = [];
	},
	registerIsVisibleEvent: function(title, handler) {
		tiddlyspace.scroller.handlers[title] = tiddlyspace.scroller.handlers[title] || [];
		tiddlyspace.scroller.handlers[title].push(handler);
	},
	init: function() {
		this.handlers = {};
		this.interval = window.setInterval(function() {
			var top = $(window).scrollTop();
			var height = $(window).height();
			var bottom = top + height;
			var title;
			for(title in tiddlyspace.scroller.handlers) {
				if(title) {
					tiddlyspace.scroller.runHandler(title, top, bottom, height);
				}
			}
		}, 2000); // every 2 seconds check scroll position
	}
};
tiddlyspace.scroller.init();

var followMacro = config.macros.followTiddlers = {
	locale: {
		followListHeader: "Here are tiddlers from spaces you follow using the follow tag which use this title.",
		noTiddlersFromFollowers: "None of the spaces you follow contain a tiddler with this name.",
		errorMessage: "There was a problem retrieving tiddlers from the server. Please try again later."
	},
	init: function() {
		followMacro.lookup = {};
	},
	followTag: "follow",
	getHosts: function(callback) {
		tweb.getStatus(function(status) {
			callback(tweb.host, tiddlyspace.getHost(status.server_host, "%0"));
		});
	},
	getBlacklist: function() {
		return store.getTiddlerText("FollowTiddlersBlackList").split("\n");
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var args = paramString.parseParams("anon")[0];
		var containingTiddler = story.findContainingTiddler(place).getAttribute('tiddler');
		var title = (args.anon && args.anon[0]) || tiddler.fields["server.title"] || tiddler.title;
		var tid = store.getTiddler(title);
		var user = params[1] || false;
		if(tid) {
			followMacro.makeButton(place, {
				url: "/search?q=title:%22" + encodeURIComponent(title) + "%22",
				containingTiddler: containingTiddler,
				blacklisted: followMacro.getBlacklist(), title: title, user: user,
				consultFollowRelationship: (args.follow &&
					args.follow[0] === 'false') ? false : true });
		}
	},
	makeButton: function(place, options) { // this is essentially the same code in TiddlySpaceFollowingPlugin
		var title = options.title;
		var blacklisted = options.blacklisted;
		var tiddler = store.getTiddler(title);
		var btn = $('<div class="followButton" />').addClass("notLoaded").appendTo(place)[0];
		if(blacklisted.contains(title)) {
			$(btn).remove();
			return;
		} else {
			var user = options.user;
			window.setTimeout(function() { // prevent multiple calls due to refresh
				tiddlyspace.scroller.registerIsVisibleEvent(options.containingTiddler, function() {
					var mkButton = function(followers, ignore) {
						if(!followers && !ignore) {
							$(btn).remove();
						} else {
							$("<a />").appendTo(btn);
							var scanOptions = { url: options.url,
								spaceField: options.spaceField || "bag", template: null, sort: "-modified",
								callback: function(tiddlers) {
									$(btn).removeClass("notLoaded");
									followMacro.constructInterface(btn, tiddlers);
								}
							};
							if(!ignore) {
								scanOptions.showBags = followMacro._getFollowerBags(followers);
							}
							scanOptions.hideBags = [tiddler.fields["server.bag"]];
							scanMacro.scan(null, scanOptions, user);
						}
					};
					if(options.consultFollowRelationship) {
						followMacro.getFollowers(mkButton);
					} else {
						mkButton([], true);
					}
				});
			}, 1000);
		}
	},
	constructInterface: function(container, tiddlers) {
		var txt = tiddlers.length;
		var className = txt > 0 ? "hasReplies" : "noReplies";
		var el = $(story.findContainingTiddler(container));
		$(container).empty().addClass(className);
		var btn = $("<a />").addClass("followedTiddlers").text(txt).
			click(function(ev) {
				followMacro.followingOnClick(ev);
			}).appendTo('<div class="followedTiddlers" />').appendTo(container)[0];
		$.data(btn, "tiddlers", tiddlers);
	},
	followingOnClick: function(ev) {
		var target = ev.target;
		var locale = followMacro.locale;
		var el = $('<div class="followTiddlersList" />')[0];
		var popup = Popup.create(target,"div");
		$(popup).addClass("taggedTiddlerList followList").click(function(ev) { // make it so only clicking on the document outside the popup removes the popup
			if(ev.target.parentNode != document) {
				ev.stopPropagation();
			}
		}).append(el);
		var tiddlers = $.data(target, "tiddlers") || [];
		scanMacro.template(el, tiddlers.slice(0,1), "FollowTiddlersHeading");
		scanMacro.template(el, tiddlers, "FollowTiddlersTemplate");
		if(tiddlers.length === 0) {
			$("<li />").text(locale.noTiddlersFromFollowers).appendTo(el);
		}
		Popup.show();
		ev.stopPropagation();
		return popup;
	},
	_getFollowerBags: function(followers) { // XXX: private or not?
		return $.map(followers, function(name, i) {
			return name != currentSpace ? "%0_public".format(name) : null;
		});
	},
	getFollowers: function(callback, username) {
		// returns a list of spaces being followed by the existing space
		var followersCallback = function(user) {
			if(!user.anon) {
				scanMacro.scan(null, { 
					url: "/search?q=bag:%0_public tag:%1 _limit:%2".format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
					spaceField: "title", template: null, cache: true,
					callback: function(tiddlers) {
						var followers = [];
						for(var i = 0; i < tiddlers.length; i++) {
							followers.push(tiddlyspace.resolveSpaceName(tiddlers[i].title));
						}
						callback(followers);
					}
				});
			} else {
				callback(false);
			}
		};
		return !username ? tweb.getUserInfo(followersCallback) : followersCallback({ name: username });
	}
};

var scanMacro = config.macros.tsScan = {
	init: function () {
		this.scanned = {};
	},
	_tiddlerfy: function(jsontiddlers, options) {
		var tiddlers = [];
		var spaceField = options.spaceField || "bag"; // TODO: phase out use view types instead
		$.each(jsontiddlers, function(i, t) {
			var use = false;
			if(!options.showBags || (options.showBags && options.showBags.contains(t.bag))) {
				use = true;
			}
			if(options.hideBags && options.hideBags.contains(t.bag)) {
				use = false;
			}
			if(use) {
				var spaceName = t[spaceField];
				var tiddler = config.adaptors.tiddlyweb.toTiddler(t, tweb.host);
				tiddler.fields["server.space"] = tiddlyspace.resolveSpaceName(spaceName);
				tiddlers.push(tiddler);
			}
		});
		return tiddlers;
	},
	_scanCallback: function(place, jsontiddlers, options) {
		var locale = followersMacro.locale;
		var tiddlers = scanMacro._tiddlerfy(jsontiddlers, options);
		
		if(options.sort) {
			tiddlers = store.sortTiddlers(tiddlers, options.sort);
		}
		if(options.filter) {
			var _store = new TiddlyWiki();
			config.lastStore = _store;
			for(var i = 0; i < tiddlers.length; i++) {
				var clone = tiddlers[i];
				clone.title = tiddlyspace.getLocalTitle(clone.title, clone.fields['server.workspace']);
				_store.addTiddler(clone);
			}
			tiddlers = _store.filterTiddlers(options.filter);
		}
		if(place) {
			$(place).empty();
			var list = $("<ul />").appendTo(place)[0];
			scanMacro.template(list, tiddlers, options.template);
			if(tiddlers.length === 0) {
				$("<li />").text(options.emptyMessage || locale.noone).appendTo(list);
				$(list).addClass("emptyList");
			}
		}
		if(options.callback) {
			options.callback(tiddlers);
		}
	},
	constructSearchUrl: function(host, options) {
		if(options.url) {
			return options.url;
		}
		var inputs = options.searchValues;
		var tag = options.tag;
		var searchField = options.searchField || "title";
		var searchQuery = [];
		for(var i = 0; i < inputs.length; i++) {
			searchQuery.push('%0:"%1"'.format(searchField, inputs[i]));
		}
		var query = searchQuery.join(" OR ");
		query = tag ? "(%0) AND tag:%1".format(query, tag) : query;
		query = options.query ? "%0;%1;".format(query, options.query) : query;
		query = options.fat ? "%0&fat=1".format(query) : query;
		return '%0/search?q=%1'.format(host, query);
	},
	scan: function(place, options) { // TODO: make use of list macro with url filter
		var locale = followersMacro.locale;
		options.template = options.template ? options.template : "ScanTemplate";
		followMacro.getHosts(function(host, tsHost) {
			$(place).text(followersMacro.locale.pleaseWait);
			options = options ? options: {};
			var url = scanMacro.constructSearchUrl(host, options);
			if(options.cache && scanMacro.scanned[url]) {
				var tiddlers = scanMacro.scanned[url].tiddlers;
				var run = function(tiddlers) {
					scanMacro._scanCallback(place, tiddlers, options);
				};
				if(tiddlers) {
					run(tiddlers);
				} else {
					scanMacro.scanned[url].callbacks.push(run);
				}
			} else {
				var callback = function(tiddlers) {
					scanMacro._scanCallback(place, tiddlers, options);
				};
				if(scanMacro.scanned[url] && scanMacro.scanned[url].callbacks) {
					scanMacro.scanned[url].callbacks.push(callback);
				} else {
					scanMacro.scanned[url] = {
						callbacks: [callback]
					};
				}
				ajaxReq({
					url: url,
					dataType: "json",
					success: function(tiddlers) {
						scanMacro.scanned[url].tiddlers = tiddlers;
						var callbacks = scanMacro.scanned[url].callbacks;
						while(callbacks.length > 0) {
							callbacks.pop()(tiddlers);
						}
					},
					error: function(xhr) {
						$(place).empty();
						$("<span />").addClass("annotation error").text(locale.error.format(xhr.status)).appendTo(place);
					}
				});
			}
		});
	},
	template: function(place, tiddlers, template) { // TODO: make use of list macro.
		for(var i = 0; i < tiddlers.length; i++) {
			var tiddler = tiddlers[i];
			var item = $('<li class="spaceName" />').appendTo(place)[0];
			var spaceName = tiddler.fields["server.space"] || "";
			var templateText = store.getTiddlerText(template).replace(/\$1/mg, spaceName);
			wikify(templateText, item, null, tiddler);
		}
	},
	getOptions: function(paramString, tiddler) {
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var options = { query: false, sort: false, tag: false, template: false, showBags: args.show || false,
			hideBags: args.hide || false, filter: false, spaceField: "bag", searchField: "title", fat: false,
			emptyMessage: false };
		for(var name in args) {
			if(name != "name") {
				if(name == "fat") {
					options[name] = true;
				} else {
					options[name] = args[name][0];
				}
			}
		}
		// if user has set searchField to modifier, then use the modifiers value if available otherwise use searchValues.
		var searchField = options.searchField;
		var searchValues = args[searchField] ? args[searchField] : args.searchValues;
		// if neither of those were used use the first parameter
		var defaultValues = tiddler ? [ tiddler.title ] : [];
		options.searchValues = searchValues ? searchValues : ( args.name ? [args.name[0]] : defaultValues);
		return options;
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var container = $("<div />").addClass("scanResults resultsArea").appendTo(place)[0];
		var options = scanMacro.getOptions(paramString, tiddler);
		scanMacro.scan(container, options);
	}
};

var followersMacro = config.macros.followers = {
	locale: {
		loggedOut: "Please login to see the list of followers",
		noSupport: "We were unable to retrieve followers as your browser does not support following.",
		pleaseWait: "Please wait while we look this up...",
		error: "Error %0 occurred whilst retrieving data from server",
		noone: "None."
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var locale = followersMacro.locale;
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var username = args.name ? args.name[0] : false;
		var container = $('<div class="followers" />').text(locale.pleaseWait).
			appendTo(place)[0];
		var followersCallback = function(user) {
			if(user.anon) {
				$("<span />").text(locale.loggedOut).appendTo(container);
			} else {
				var options = scanMacro.getOptions(paramString);
				$.extend(options, {
					url: "/search?q=title:@%0 OR title:%0 tag:%1 _limit:%2".
						format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
					spaceField: "bag",
					template: options.template ? options.template : "FollowersTemplate"
				});
				scanMacro.scan(container, options);
			}
		};
		return !username ? followersCallback({ name: currentSpace }) : followersCallback({ name: username });
	}
};

var followingMacro = config.macros.following = {
	locale: {
		pleaseWait: followersMacro.locale.pleaseWait,
		loggedOut: "Please login to see who you are following",
		noSupport: followersMacro.locale.noSupport,
		error: followersMacro.locale.error,
		noone: followersMacro.locale.noone
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var locale = followingMacro.locale;
		var args = paramString.parseParams("name", null, true, false, true)[0];
		var fat = args.fat ? true : false;
		var username = args.name ? args.name[0] : false;
		var container = $('<div class="following" />').text(locale.pleaseWait).
			appendTo(place)[0];
		var followingCallback = function(user) {
			if(user.anon) {
				$("<span />").text(locale.loggedOut).appendTo(container);
			} else {
				var options = scanMacro.getOptions(paramString);
				$.extend(options, {
					url: "/search?q=bag:%0_public tag:%1 _limit:%2".format(user.name, followMacro.followTag, LIMIT_FOLLOWING),
					spaceField: "title",
					template: options.template ? options.template : "FollowingTemplate"
				});
				scanMacro.scan(container, options);
			}
		};
		return !username ? followingCallback({ name: currentSpace }) : followingCallback({ name: username });
	}
};

var linkedMacro = config.macros.linkedTiddlers = {
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var args = paramString.parseParams("anon")[0];
		var title = params[0] || tiddler.fields["server.title"] || tiddler.title;
		var tid = store.getTiddler(title);
		var containingTiddler = story.findContainingTiddler(place).getAttribute('tiddler');
		if(tid) {
			followMacro.makeButton(place, {
				spaceField: "recipe",
				url: "/bags/%0/tiddlers/%1/backlinks".format(tid.fields['server.bag'],
					encodeURIComponent(tid.title)),
				blacklisted: followMacro.getBlacklist(),
				title: title,
				containingTiddler: containingTiddler,
				user: params[1] || false,
				consultFollowRelationship: args.follow ? true : false });
		}
	}
};

if(config.options.chkFollowTiddlersIsLinkedTiddlers) {
	merge(config.macros.followTiddlers, config.macros.linkedTiddlers);
	config.shadowTiddlers.FollowTiddlersHeading = "These are the other tiddlers that link to this tiddler.";
}

})(jQuery);
//}}}
<<tiddler SideBarTabs>>
/%
*Renaming this tiddler, will make the right sidebar invisible.
*Using this tiddler with the theme, makes it possible to keep the original SideBarTabs tiddler. 
 
!!!old content
<<tiddler SidebarButtons>>
<<slider chkSliderSideBarTabs SideBarTabs "Index »" "display the timeline">> 
%/


/***
|Name:|QuickOpenTagPlugin|
|Description:|Changes tag links to make it easier to open tags as tiddlers|
|Version:|3.0.1 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
config.quickOpenTag = {

	dropdownChar: (document.all ? "\u25bc" : "\u25be"), // the little one doesn't work in IE?

	createTagButton: function(place,tag,excludeTiddler) {
		// little hack so we can do this: <<tag PrettyTagName|RealTagName>>
		var splitTag = tag.split("|");
		var pretty = tag;
		if (splitTag.length == 2) {
			tag = splitTag[1];
			pretty = splitTag[0];
		}
		
		var sp = createTiddlyElement(place,"span",null,"quickopentag");
		createTiddlyText(createTiddlyLink(sp,tag,false),pretty);
		
		var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,
                        config.views.wikified.tag.tooltip.format([tag]),onClickTag);
		theTag.setAttribute("tag",tag);
		if (excludeTiddler)
			theTag.setAttribute("tiddler",excludeTiddler);
    		return(theTag);
	},

	miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var tagged = store.getTaggedTiddlers(tiddler.title);
		if (tagged.length > 0) {
			var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,
                        	config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);
			theTag.setAttribute("tag",tiddler.title);
			theTag.className = "miniTag";
		}
	},

	allTagsHandler: function(place,macroName,params) {
		var tags = store.getTags(params[0]);
		var filter = params[1]; // new feature
		var ul = createTiddlyElement(place,"ul");
		if(tags.length == 0)
			createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
		for(var t=0; t<tags.length; t++) {
			var title = tags[t][0];
			if (!filter || (title.match(new RegExp('^'+filter)))) {
				var info = getTiddlyLinkInfo(title);
				var theListItem =createTiddlyElement(ul,"li");
				var theLink = createTiddlyLink(theListItem,tags[t][0],true);
				var theCount = " (" + tags[t][1] + ")";
				theLink.appendChild(document.createTextNode(theCount));
				var theDropDownBtn = createTiddlyButton(theListItem," " +
					config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);
				theDropDownBtn.setAttribute("tag",tags[t][0]);
			}
		}
	},

	// todo fix these up a bit
	styles: [
"/*{{{*/",
"/* created by QuickOpenTagPlugin */",
".tagglyTagged .quickopentag, .tagged .quickopentag ",
"	{ margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }",
".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }",
".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}",
"/* extra specificity to make it work right */",
"#displayArea .viewer .quickopentag a.button, ",
"#displayArea .viewer .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink ",
"	{ border:0px solid black; }",
"#displayArea .viewer .quickopentag a.button, ",
"#mainMenu .quickopentag a.button ",
"	{ margin-left:0px; padding-left:2px; }",
"#displayArea .viewer .quickopentag a.tiddlyLink, ",
"#mainMenu .quickopentag a.tiddlyLink ",
"	{ margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }",
"a.miniTag {font-size:150%;} ",
"#mainMenu .quickopentag a.button ",
"	/* looks better in right justified main menus */",
"	{ margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }", 
"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }",
"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }",
"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }",
"/*}}}*/",
		""].join("\n"),

	init: function() {
		// we fully replace these builtins. can't hijack them easily
		window.createTagButton = this.createTagButton;
		config.macros.allTags.handler = this.allTagsHandler;
		config.macros.miniTag = { handler: this.miniTagHandler };
		config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;
		store.addNotification("QuickOpenTagStyles",refreshStyles);
	}
}

config.quickOpenTag.init();

//}}}

!!Publicity
I think that we do need to publicize this system. Are we going to run it in parallel with written evaluations in December? Students are probably not going to want to do both.
Besides spreading the word I propose that we provide two hands-on 'getting familiar with the system' exercises for the faculty.
!!!!1. Hands-on with EvalKit Course
# We set up the survey with the standard FAC approved list of questions plus any extras we may wish to try out
# Faculty self enroll into a demo course, eg 'Defence against the Dark Arts' that's more or less blank
# At a certain point we add the EvalKit block which provides the link to the survey
# Faculty click the link and take the survey //as though they were students in the course//. This will give them a good feel for how it works for a student.
# Soon afterwards, I compile the results into a pdf and post it into the course for the participants to see what the Teacher gets back.
!!!2. Testing with an actual course
I do have at least one faculty who has expressed an interest in having his students assess the course at mid term. This would help us test the system with a real class before kick-off.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4">
  <path id="path2868" stroke-linejoin="miter" style="stroke-dasharray:none;" d="m54.317,7.6768a1.9973,1.9973,0,1,1,-3.9947,0,1.9973,1.9973,0,1,1,3.9947,0z" transform="matrix(0.8, 0, 0, 0.8, -13.3206, 45.4412)" stroke-width="2" fill="none"/>
  <path id="path2870" stroke-linejoin="miter" style="stroke-dasharray:none;" d="m28.659,61.002,1.5965,3.6122,3.918-0.52745,0.36073,2.2515m-14.924-6.2337,0.69646,2.1742,4.0617-1.7571,3.9354,0.03647" stroke-width="2.4" fill="none"/>
  <path id="path2872" stroke-linejoin="round" style="stroke-dasharray:none;" d="m30.528,55.591,3.4621,1.1984-1.7754,2.7075" stroke-width="2.4" fill="none"/>
  <path id="path2874" stroke-linejoin="round" style="stroke-dasharray:none;" d="m26.399,55.461-3.7651,0.63128-1.5048-3.1324" stroke-width="2.4" fill="none"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
|!Item|!# on bread|!# Wraps|
|Ham | 1| 1|
|Hummus | 5| 5|
|Turkey | 3| 3|
|''Total''| ''9''| ''9''|
/*{{{*/
.headerForeground {
	position: relative;
	text-align: right;
}

.header {
	width: 100%; /* for ie */
}

#contentWrapper {
	position: relative;
	padding-top: 1px;
	top: -1px;
}

.header {
	position: relative;
	background-color: [[ColorPalette::PrimaryLight]];
}

.siteTitle {
	display: block;
}

/*}}}*/
/*{{{*/
body {
	font-size: 1em;
	font-family: helvetica, arial, sans-serif;
	background-color: #fff;
	color: [[ColorPalette::Foreground]];
}

body ul { margin: 0; }

#popup {
	background-color: [[ColorPalette::TertiaryPale]];
}

#popup.confirmationPopup, .followList {
	font-size: 0.8em;
	padding: 1em;
	border: solid 1px [[ColorPalette::SecondaryMid]];
	background-color: [[ColorPalette::SecondaryPale]];
}

.followList .listTitle {
	text-decoration: underline;
}

#popup .followTiddlersList a {
	display: inline;
	padding: 0;
}

#popup li a {
	color: [[ColorPalette::PrimaryMid]];
	font-weight: bold;
}

#popup li a:hover {
	color: [[ColorPalette::PrimaryPale]];
	background: [[ColorPalette::PrimaryMid]];
}

#popup li.listTitle {
	border-bottom: 1px solid #000;
	font-weight: bold;
	margin-bottom: 10px;
}

#popup.followList {
	margin-left: 50px;
	margin-top: -30px;
}

.followTiddlersList .label {
	display: block;
	left: 10px;
	top: 0px;
	line-height: 16px;
	position: relative;
}

#popup .followTiddlersList .siteIcon{
	height: auto;
}

#popup .followTiddlersList li{
	clear: both;
	display: block;
	height: 48px;
	margin-bottom: 8px;
	position: relative;
}

#popup .followTiddlersList a{
	display: inline;
}

#displayArea {
	margin: 0;
	top: 0px;
	left: 0px;
	width: 100%;
	position: relative;
}

.revisionCloak {
	position: absolute;
	position: fixed !important;
	height: 100%;
	width: 100%;
	top: 0;
	left: 0;
	border: 0;
	margin: 0;
	padding: 0;
	opacity: 0.5;
	filter: alpha(opacity=50);
	background-color: #000;
}

/* *** Header *** */
.header {
	position: relative;
	background-color: [[ColorPalette::PrimaryMid]];
	_width: 100%; /* ie 6 demands */
}

.headerForeground {
	background-color: [[ColorPalette::PrimaryMid]];
	float: left;
	margin: 24px 16px 0px 72px;
	padding: 0;
	position: relative;
	top: 0;
	_width: 70%; /*ie6: needed for the background to actually be transparent*/
	_background-color: transparent; /*ie6: needed to show the search box*/
}

.clearFloat {
	clear: both;
}

#contentWrapper {
	position: relative;
	padding-top: 1px;
	top: -1px;
}

#tiddlerDisplay {
	_position: relative; /* ie 6*/
}

.siteTitle {
	clear: both;
	display: block;
	font-size: 32px;
	font-weight: bold;
	line-height: 32px;
}

.siteSubtitle {
	display: block;
	font-size: 14px;
	height: 16px;
	margin-bottom: 8px;
}

#sidebarSearch {
	padding: 0;
	position: absolute;
	right: 80px;
	top: 8px;
	width: 176px;
}

#sidebarSearch .txtOptionInput {
	width: 100%;
	margin-top: 5px;
	_color: #bbb; /* ie6 danger */
}

#sidebarSearch .txtOptionInput:focus {
	color: #000;
}

#sidebarSearch .searchButton {
	display: none;
}

/* *** Menu Bar *** */

#mainMenu {
	position: static;
	text-align: left;
	margin-left: 72px;
	float: left;
	width: auto;
	padding: 0;
	font-size: 1em;
	line-height: normal;
}

#mainMenu a {
	color: #fff;
	padding: 8px;
	font-size: 0.9em;
	margin-right: 16px;
}

#mainMenu a:hover {
	background-color: [[ColorPalette::PrimaryMid]];
	color: [[ColorPalette::Background]]
}

#sidebarOptions {
	margin-right: 72px;
	float: right;
	font-size: 1.1em;
	line-height: 1.6em;
	min-height: 1em;
	padding-top: 0;
}

#sidebarOptions a {
	margin-right: 8px;
}

.confirmationPopup .button,
#sidebarOptions .button {
	cursor: pointer;
	line-height: 1.4em;
	text-align: center;
	margin-right: 8px;
	margin-left:-2px;
}

.confirmationPopup .button {
	font-size: 0.9em;
	padding: 2px;
}

#sidebarOptions .button {
	font-size: 0.7em;
	float: left;
	width: 80px;
	padding: 0px;
        color: #fff;
}

.confirmationPopup a.button,
#sidebarOptions a {
	border: none;
	margin: 0 0.2em;
	padding: 0.6em 0.25em;
	display: inline;
	color: #666;
}

.confirmationPopup a.button:hover,
#sidebarOptions a:hover {
	color: #000;
}

.confirmationPopup a.button:active,
#sidebarOptions a:active {
	border: solid 1px [[ColorPalette::PrimaryMid]];
	background-color: #fff;
	background: -webkit-gradient( linear, left bottom, left top, color-stop(0.1,rgb(200,200,200)), color-stop(1, rgb(100,100,100)));
	background: -moz-linear-gradient(center bottom , rgb(200,200,200) 10%,rgb(100,100,100) 100%) repeat scroll 0 0 transparent;
}
/* *** Sidebar *** */

#sidebar .wizard table {
	margin: 0px;
}

.tabContents .listTitle:first-child {
	margin-top: 0px;
}

#menuBar {
	background: [[ColorPalette::PrimaryLight]];
	left: 0;
	right: 0;
	position: relative;
	margin: 0;
	padding: 0.5em 0 0.5em 0;
	min-height: 1em;
	overflow: hidden;
	_width: 100%; /* for ie 6 */
}

#sidebarOptions a.button:hover {
	color: [[ColorPalette::PrimaryPale]];
    background: [[ColorPalette::PrimaryMid]];
}

#tiddlerDisplay, #searchResults {
	margin: 16px 448px 0 72px;
}

#sidebarTabs {
	position: absolute;
	right: 72px;
	width: 352px;
	top: 0;
}

#sidebarTabs .tabsetWrapper .tabset {
	width: 87px;
	border-top: 1px solid [[ColorPalette::PrimaryPale]];
	border-left: 1px solid [[ColorPalette::PrimaryPale]];
	border-bottom: 1px solid [[ColorPalette::PrimaryPale]];
	height: auto;
	float: left;
	word-wrap: break-word;
	top: 0;
	padding: 0;
}

#sidebarTabs .tabsetWrapper .tabContents {
	background-color: [[ColorPalette::PrimaryPale]];
	border: 3px solid [[ColorPalette::PrimaryMid]];
	width: 242px;
	_width: 238px;
	left: -3px;
	_left: -5px;
	position: relative;
	min-height: 34em;
	padding: 8px;
	font-size: 0.8em;
}

/* ---- Side style --- */

#sidebarTabs .tabsetWrapper .tabset .tab {
	font-size: 0.9em;
	padding: 0.7em 8px 0.5em;
	color: #fff;
	background: [[ColorPalette::PrimaryLight]];
	border: none;
	line-height: 16px;
	position: relative;
	display: block;
	margin: 0;
}

#sidebarTabs .tabsetWrapper .tabset .tabSelected {
	color: [[ColorPalette::PrimaryMid]];
	background: [[ColorPalette::PrimaryPale]];
	border-top: 3px solid [[ColorPalette::PrimaryMid]];
	border-bottom: 3px solid [[ColorPalette::PrimaryMid]];
	border-left: 3px solid [[ColorPalette::PrimaryMid]];
	z-index: 10;
	margin-top: -1px;
	font-weight: bold;
}

#sidebarTabs .tabContents li {
	border: none;
	margin-left: 0;
	word-wrap: break-word;
}

.tabContents .timeline {
	background: [[ColorPalette::PrimaryPale]];
	margin-bottom: 8px;
}

#sidebarTabs .timeline li.listTitle {
	color: #132E43;
	margin-left: 8px 0;
	padding: 0.3em 0.11em;
	font-size: 1em;
	border-bottom: none;
}

#sidebarTabs .tabContents li a {
	display: block;
	text-align: left;
	margin: 0 0 1px 0;
	padding: 0.3em 1em;
	background: [[ColorPalette::PrimaryPale]];
}

#sidebarTabs .tabsetWrapper .tabset a:hover,
#sidebarTabs .tabContents li a:hover {
	color: [[ColorPalette::PrimaryPale]];
	background: [[ColorPalette::PrimaryMid]];
}

/* Activity Stream */
#sidebarTabs .tabContents .activityStream .feedItem a {
	display: inline-block;
	padding: 0;
	background: none;
}

/* ---- Tagging box --- */
.tagInfo {
	border: 1px solid #cccccc;
	padding: 10px 15px;
	-moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2);
	box-shadow: 0 2px 2px rgba(0,0,0,0.2);
	color: [[ColorPalette::TertiaryMid]];
	background: -moz-linear-gradient(100% 100% 90deg, #f4f4f4, #e5e5e5);
	background: -webkit-gradient(linear, left top, right top, from(#e5e5e5), to(#f4f4f4));
	margin-top: 1em;
	font-size: 13px;
	margin: 0 0 0 56px;
}

.tagInfo ul {
	list-style: none;
	padding-left: 2.2em;
}

.tagInfo ul li {
	display: inline;
}

.tagInfo ul li.listTitle,
.tagInfo .tagging ul li.listTitle {
	color: [[ColorPalette::PrimaryMid]];
	font-size: 13px;
}

.tagInfo ul li a {
	border: none;
}

.tagInfo .tagging ul li {
	float: none;
	display: inline-block;
}

.tagInfo .tagging {
	padding: 0;
}

.viewRevision .toolbar {
	right: 48px;
	top: 8px;
}

.viewRevision .modifierIcon img,
.viewRevision .modifierIcon svg {
	margin-right: 8px;
}

.viewRevision .toolbar svg {
	width: 32px;
	height: 32px;
}

/* --- IE hacks from lattice --- */

/* ie hacks */
* html #menuBar {
	margin-bottom: 8px;
}
.toolbar .svgIconText {
	*display: inline;
}

div.tiddler .toolbar a {
	cursor: pointer;
	float: left\9;
	display: inline\9;
}

* html .toolbar {
	right: 8px;
}
* html .followButton a {
	margin-top: 0px;
	margin-right: 8px;
}
* html #tiddlerDisplay {
	margin-top: 0px;
}

/* for printing purposes */
@media print {
	#mainMenu,
	#sidebar,
	#messageArea,
	.toolbar,
	.followPlaceHolder,
	#backstageButton,
	#backstageArea,
	#sidebarTabs,
	#sidebarSearch .txtOptionInput,
	#sidebarOptions {
		display: none !important;
	}
	#displayArea {
		margin: 1em 1em 0em;
	}
	noscript {
		display:none; /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
	}
	#tiddlerDisplay {
		margin: 16px 16px;
	}
}

@media all and (max-width: 960px){
	#tiddlerDisplay,
	#searchResults {
		margin: 16px 366px 0 16px;
	}

	#mainMenu {
		margin-left: 16px;
	}

	.headerForeground {
		margin-left: 16px;
	}

	#sidebarSearch {
		right: 16px;
	}

	#sidebarOptions {
		margin-right: 16px;
	}

	#sidebarTabs {
		right: 16px;
		width: 326px;
	}

	#sidebarTabs .tabsetWrapper .tabset {
		font-size: 0.9em;
		width: 77px;
	}

	#sidebarTabs .tabsetWrapper .tabContents {
		width: 226px;
		_width: 222px;
	}

	#sidebarTabs .tabContents li a {
		font-size: 0.9em;
	}
}
/*}}}*/
[[StyleSheetTiddler]]
[[Moodle Accessibility Test - MSU|http://www.youtube.com/watch?v=GDGDnLh5QVA]] -- interesting Youtube video. Turns out that Moodle has good accessibility overall.
[[Surfing the Internet with JAWS and MAGic!|www.freedomscientific.com/training/Surfs-Up/_Surfs_Up_Start_Here.htm]]
[[JAWS 12 Desktop Keyboard Commands|http://www.csclearn.org/storercenter/JAWS%2012%20Desktop%20Keyboard%20Commands.htm]] -- this is for laptops as well -- but not for ipads. Humungously useful.
[[JAWS demo|http://www.freedomscientific.com/downloads/jaws/jaws-downloads.asp]] -- this is for JAWS13, JAWS 14 is out soon, so download this.
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
!Thoughts about the Moodle2 resources fiasco
!! The 1.x model
* Easy to understand
* Simple
* But with inherent flaws
express flaws in ways which the end user can appreciate
# Files belong to teacher only. So how can students do group work and share files?
** Allowing access to files area not a solution.

!! The 2.x model -- files as resources
* 
Confusion : Private files? Why can't I see files?
Limitations -- share resources between courses? How?
file management is impossible
no utilities for managing moodle resources across courses or independent of the course outline. No equivalent of Maharaha's Artifacts-Views-Communities model.

Email to Geosciences folks -- Cynthia, Andy, Meg on {{ts{23/07/12 12:32}}}
<<<
To summarize morning conversation between Cynthia, Andy & Mark, leaving aside projector stuff:

Andy talked about assessment with rubrics for two pedagogic activities in Earth History class, student Oral Lecture Presentations & Field Notebook review. In both of these activities the desire was to have students use the supplied rubric to grade or rate each other's presentation/Lecture and to see  annonymized comments and grades for their own efforts but not other people's. With Field Notebook review a similar thing is desired where students scan or digitally photo their own notebook and upload it for assessment by other students. Cynthia also expressed an interest in doing something similar.

My approach is to examine the Workshop module for Moodle  which seems to me to be a rather neat fit to the stated requirements. We left matters with the promise that I'd work with Andy to suss out how to implement Workshop for these teaching activities. In addition, I discovered that Floyd Saner who is organizing the MidWest Moodle Moot is also doing a workshop for the West Coast Moot entitled "Engage Participants with a Moodle Workshop Activity". I will be meeting him later this week at the MidWest Moot and will discuss with him the possibility of his doing a similar workshop on our campus (the issue being cost of course).
<<<
/*{{{*/
Name: MpBlue
Background: #ffd
Foreground: #000
PrimaryPale: #ccd
PrimaryLight: #57c
PrimaryMid: #114
PrimaryDark: #012
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
(function() {
var getCSRFToken = function(window) {
	// XXX: should not use RegEx - cf.
	// http://www.quirksmode.org/js/cookies.html
	// https://github.com/TiddlySpace/tiddlyspace/commit/5f4adbe009ed4bda3ce39058a3fb07de1420358d
	var regex = /^(?:.*; )?csrf_token=([^(;|$)]*)(?:;|$)/;
	var match = regex.exec(document.cookie);
	var csrf_token = null;
	if (match && (match.length === 2)) {
		csrf_token = match[1];
	}

	return csrf_token;
};

if (typeof config !== 'undefined' && config.extensions &&
		config.extensions.tiddlyspace &&
		config.extensions.tiddlyspace.getCSRFToken === null) {
	config.extensions.tiddlyspace.getCSRFToken = getCSRFToken;
} else {
	window.getCSRFToken = getCSRFToken;
}
})(window);
@@Please do not modify this tiddler; it was created automatically upon space creation.@@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns="http://www.w3.org/2000/svg" height="29pt" width="29pt" version="1.0" viewBox="13 43 29 29" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" gradientTransform="matrix(0, -0.544761, 0.529104, 0, 18.3357, 31.7966)" y1="27.646" x1="-57.66">
   <stop id="stop3209" stop-color="#be7800" offset="0"/>
   <stop id="stop3236" stop-color="#dcb400" offset="0.66462"/>
   <stop id="stop3211" stop-color="#be7800" offset="1"/>
  </linearGradient></defs>
 <g id="icon" stroke-linecap="round" stroke-miterlimit="4" fill-rule="evenodd">
  <path id="iconBG" stroke-linejoin="round" style="stroke-dasharray:none;" d="m25.151,68.079,12.404-12.643c1.3742,0,2.4805,1.0369,2.4805,2.325v10.318c0,1.288-1.1063,2.325-2.4805,2.325h-9.9235c-1.3742,0-2.4805-1.0369-2.4805-2.325z" stroke="#696969" stroke-width="1.28" fill="none"/>
 <path id="iconFG" stroke-linejoin="round" style="stroke-dasharray:none;" d="M27.143,67.989,37.527,57.183c0.69632,0,1.2569,0.52542,1.2569,1.1781v9.6286c0,0.65265-0.56057,1.1781-1.2569,1.1781h-9.1265c-0.69632,0-1.2569-0.52541-1.2569-1.1781z" stroke="#e6e6e6" stroke-width="0.96" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" transform="matrix(0.707107, 0.707107, -0.707107, 0.707107, 54.0298, -3.77985)" stroke="#4d4d4d" stroke-width="1.6" fill="#4d4d4d">
   <path id="path3252" style="stroke-dasharray:none;" d="M34.232,64.294,36.834,61.791"/>
   <path id="path3254" style="stroke-dasharray:none;" d="M36.834,61.791,34.232,59.34"/>
  </g>
<rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
 </g>
</svg>
/***
|''Name''|PaletteViewMacro|
|''Version''|0.2 mp01|
|''Author''|FND|
|''Modified''|pmario|
|''Source''|[[FND's DevPad|http://devpad.tiddlyspot.com/#PaletteViewMacro]]|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion''|2.1|
|''Type''|macro|
|''Requires''|N/A|
|''Overrides''|N/A|
|''Description''|Displays color palettes.|
!Notes
There is also [[ViewPalettePlugin|http://simon.tiddlyspot.com/#ViewPalettePlugin]], which currently does not work with TiddlyWiki v2.2 though.
pmario changed the regexp a bit to handle spaces more friendly.
!Usage
{{{
<<paletteView [tiddler name]>>
}}}
!!Example
<<paletteView [[ColorPalette]]>> 
!Revision History
!!v0.1 (2007-11-18)
* initial release
!!v0.2 (2007-11-20)
* limited processing to slices containing [[actual color values|http://www.w3.org/TR/CSS21/syndata.html#color-units]]
* changed fallback value to the tiddler the macro is called from (instead of using [[ColorPalette]])
!To Do
* selection list for all available palettes (tag-based)
* parameter for custom table class
* customizable column order
* documentation (e.g. using from within [[ViewTemplate]])
!Code
***/
//{{{
config.macros.paletteView = {};

config.macros.paletteView.handler = function(place, macroName, params, wikifier, paramString, tiddler) {
	var title = params[0] || tiddler.title;
	//var palettes = store.getTaggedTiddlers(params[0]); // DEBUG: yet to be implemented
	var colors = store.calcAllSlices(title);	
	var labels = [];
	for(var c in colors) {
		if(this.isColor(colors[c])) {
			labels.push(c);
		}
	}
	if(labels.length > 0) {
		var output = "|!Sample|!Value|!Name|h\n";
		for(var i = 0; i < labels.length; i++) {
			output += "|padding:0 4em;background-color:" + colors[labels[i]] + ";&nbsp;|"
				+ "{{{" + colors[labels[i]] + "}}}|"
				+ "[[" + labels[i] + "|" + title + "]]|\n";
		}
		wikify(output, place);
	}
};

config.macros.paletteView.isColor = function(s) {
	var colors = ["Black", "Green", "Silver", "Lime", "Gray", "Olive", "White", "Yellow",
		"Maroon", "Navy", "Red", "Blue", "Purple", "Teal", "Fuchsia", "Aqua", "Orange"];
	var match = s.match(/^ ?#[0-9A-F]{3} ?$|^ ?#[0-9A-F]{6} ?$|^ ?RGB\([\d,\s]{5,}\) ?$/i);
	if(match) return true;
	if(colors.contains(s)) return true;
	return false;
};
//}}}
/*{{{*/
Name: MpGreen
Background: #cec
Foreground: #000
PrimaryPale: #9b9
PrimaryLight: #385
PrimaryMid: #031
PrimaryDark: #020
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*}}}*/
/***
|''Name''|TiddlySpaceFollowingWizard|
|''Version''|0.7.0|
|''Description''|Provides a following wizard macro and deleteButton view type|
|''Author''|Jon Robson|
|''Requires''|TiddlySpaceConfig TiddlySpaceFollowingPlugin TiddlySpaceTiddlerIconsPlugin|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{ <<followWizard>> }}}
!StyleSheet
.followWizard ul,
.followWizard li .siteIcon,
.followWizard li {
	list-style: none;
	display: inline-block;
}

.followWizard li {
	margin-right: 8px;
	background-color: #eee;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	padding: 4px;
}
!Code
***/
//{{{
(function($) {

var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;

var shadows = config.shadowTiddlers;
shadows.FollowersTemplate = "<<view server.bag SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view server.bag spaceLink>>";
shadows.FollowingTemplate = "<<view title SiteIcon width:24 height:24 spaceLink:yes label:no>> <<view title spaceLink>> <<view title deleteButton>>";

var name = "StyleSheetFollowingWizard";
shadows[name] = "/*{{{*/\n%0\n/*}}}*/".
	format(store.getTiddlerText(tiddler.title + "##StyleSheet"));
store.addNotification(name, refreshStyles);

var wizard = config.macros.followWizard = {
	locale: {
		mission: "Which user or space would you like to follow?",
		badpermissions: "Only members of the space can maintain followers.",
		follow: "follow"
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var locale = wizard.locale;
		var container = $("<div />").addClass("followWizard").appendTo(place)[0];
		if(!readOnly) {
			var form = $("<form />").addClass("followForm").appendTo(container)[0];
			$("<span />").text(locale.mission).appendTo(form);
			var input = $("<input />").attr("name", "space").attr("type", "text").appendTo(form);
			$("<input />").attr("type", "submit").val(locale.follow).appendTo(form).click(function(ev) {
				wizard.addFollowing(ev, input.val());
				ev.preventDefault();
			});
		} else {
			$(container).addClass("annotation").text(locale.badpermissions);
		}
	},
	addFollowing: function(ev, space) {
		var name = tiddlyspace.resolveSpaceName(space);
		if(!name) {
			alert("That doesn't appear to be a valid space name. Please check and try again.");
			return;
		}
		var title = "@" + name;
		var tiddler = store.getTiddler(title);
		if(tiddler) {
			tiddler.tags.push("follow");
		} else {
			tiddler = new Tiddler(title);
			tiddler.tags.push("follow");
			merge(tiddler.fields, config.defaultCustomFields);
		}
		store.saveTiddler(tiddler);
		autoSaveChanges();
	}
};

config.macros.view.views.deleteButton = function(value,place,params,wikifier,paramString,tiddler) {
	var tid = store.getTiddler(value)
	if(tid && config.commands.deleteTiddler.isEnabled(tid)) {
		var handler = function(ev) {
			config.commands.deleteTiddler.handler(ev,ev.target,value);
		};
		createTiddlyButton(place, "X", "delete this tiddler", handler);
	}
};

})(jQuery);
//}}}
!Followers
<<followers>>
!Activity
[[Replies and Notifications]]

<<activity>>
!Following
All spaces tagged follow
<<list filter [tag[follow]][sort[title]]>>

<<followSuggestions>>
[[ConversionThingy 2|http://www.conversionthingy.net/Default.aspx]] says that it converts 1.9 backup files to 2.0 versions.
Active user name: <<option txtUserName>>
These options for customising [[TiddlyWiki]] are saved in your browser

select theme: <<selectTheme>>
select palette: <<selectPalette>>

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

----
Also see [[AdvancedOptions]]
Here are some possible summer projects for Moodle which would be good to implement.
# Quickmail -- this is dead useful for sending reminders to subsets of students in the course. However, currently the message context sucks compared to what the News posting looks like. +++[message from Cynthia]>
Is it possible to have messages sent from moodle2 marked with the course title and that it was sent through moodle? Maybe a signature that says something like, 'This message was sent to you via the [course number] [course title] moodle2 page.'
I'm finding it would be helpful context for the students...
=== [[Quickmail message|http://legacy.earlham.edu/~markp/screens/moodle/M2-quickmail-message.png]]<<imagebox>>  [[News message| http://legacy.earlham.edu/~markp/screens/moodle/M2-email-confirmation-news.png]]<<imagebox>>
# Email from scheduler. Similarly, the formatting of messages to students from within the Scheduler sucketh big time. The code is also a mess. I know this because I had to hack it to make the email work. It needs a deal of tidying up. Both of these are minor projects I would say.
# Search through pdf resources in a course. We have a huge need to search pdf files in Community Documents. I think that in the first instance ''OU Search'' could be looked as as providing a model for how such a utlity might work.



/*{{{*/
#sidebar .wizard table {
	margin: 0px;
}

#sidebarSearch {
	margin: 0.2em 1em 0;
	position: relative;
}

#sidebarSearch .txtOptionInput {
	width: 100%;
	margin-top: 5px;
}

#sidebarSearch .searchButton {
	padding: 0.2em;  
	color: [[ColorPalette::Background]];
}

/* the borders look wrong with the body background */
#sidebar .button {
	border-style: none;
}

/*-- new vor FreeStyle --*/
.tabContents {
	overflow: auto;
}

#sidebarTabs .tabContents{
	width: auto;
}

#sidebarTabs .sliderpanel a{
	display: inline;
} 

#sidebarTabs a.button,
#sidebarTools a.button {
	margin:0 0.2em; 
	padding:0.2em 0.3em; 
	display:block;
}

.sidebarBox {			/*-- new for FreeStyle --*/
	padding-top: 0.3em;
}

/***
This fixes a problem with the tabs slider
***/
#sidebarTabs .button {
	margin:0em 0.2em;
	padding:0.2em 0.3em;
	display:block;
}

#sidebarTools .sliderpanel,
#sidebarOptions .sliderpanel {
	margin: 0 0.5em; 
} 

/* remove fixed size from inputs eg: search and password in sidebar */
.txtOptionInput, .pasOptionInput {
	width: 90%;
}

/* adjust spacing for the above */
#sidebarOptions .input {
	margin: 0.4em 5%; 
}


/*}}}*/
Course, Jazz History. Not perhaps a typical course since it has a lot of nested categories (listening logs).
!!Categories and Items
|!Category Name|!Aggregation|!Max Grade|!Item|!Grade|!Notes|
|MUS369 Jazz History|Sum of grades| 100| | | |
|Listening Logs|Simple weighted mean| 20|25 listening logs| 100|grouped into 5 nested sub-categories|
|Class Attendance and Participation|Simple weighted mean| 25|Attendance and Participation| 100|use the Attendance module|
|Historical research paper|Simple weighted mean| 15|Final paper| 100|Assignment|
|Mid semester exam|Simple weighted mean| 10|Mid semester exam| 100|Assignment|
|Cultural/Contextual presentation/discussion|Simple weighted mean| 10|C/C presentation/discussion| 100|Assignment|
|Final Exam|Simple weighted mean| 20|Final Exam| 100|Assignment|
[[Screenshot of grading categories|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grading-categories.png]]<<imagebox>>
* The Listening logs had 5 dated nested subcategories to correspond with the grading schedule. They were nested so that students could see their cumulative grade.
* Categories are set up so that the students can add up all the 'real' numbers to obtain both the final grade and the current grade at any intermediate point in the course.
!! Grader report
I set the display of the Grader report so that the teacher (and his students) could see both the percentage obtained for each category and it's contribution towards the total (the 'real' value). Letter grades were only displayed in the course total. Apart from the Listening Logs we're not really interested in the item value (which is always out of 100%), just the total for each category.
[[Grader report that teacher views|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grader-report.png]]<<imagebox>> showing just category totals
!!LAE Grader Report
This required more tweaking:
!!!1. Display of category totals
I had the default display Course Settings LAE grader report : Accurate POINT TOTALS -> Show. It's not clear what this means, the sitewide setting has "Categories and course POINT TOTALS computed accurately" but does this mean that without this setting they are //not// computed accurately? The problem is that with this setting switched on the display for category total shows just a number rather than the real value with % in brackets. [[Screenshot LAE grader report with accurate totals on|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grader-report-LAE.png]]<<imagebox>>. Switching this off restores the desired display. [[Screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grader-report-LAE2.png]]<<imagebox>>
!!!2. Misalignment of columns. 
* With grade ranges displayed (laegrader report preferences : Show ranges : on) the columns are badly misaligned [[screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grader-report-LAE5.png]]<<imagebox>>. Switching this off improves matters.
* Changing Course settings : Aggregation position -> Last conveniently displays all the Listening Log subcategories together -- this is a major plus. [[Screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grader-report-LAE4.png]]<<imagebox>>
* The misalignment of columns causes the final grade to be located under the Category header 'Res Paper'. [[Screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-grader-report-LAE3.png]]<<imagebox>>
!!!3. User report display
* The regular user report displays the ranges in a somewhat clumsy way -- [[screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-user-report.png]]<<imagebox>>
* The LAE User report with ranges could cause confusion with the category totals which do not display the range as set in the Categories & items : max grade setting -- [[screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/demo-course-user-report-LAE.png]]<<imagebox>>
!Conclusions
# "Accurate point totals" destroys the display in the LAE Grader report and overrides the aggregation settings to sum everything. This is a disaster.
# Useful to have range display set for the LAE User report but not for the LAE Grader report.
# Misalignment of columns is a real problem for the teacher, but does not affect the user display.
# In the LAE user report the display of the category total range does not reflect the Max grade as set in the Categories & Items.
** This means that while the student can sum the category totals to get her current grade status it's not possible to see what this is out of since the range displays are faulty.
----
{{ts{6/07/12 15:44}}} @@Important browser note@@
Note that the LAEGrader displays line up correctly when using Safari on the Mac!!
Tested Bob Puffer's styles.php and index.php (styles.php just had css contents). Appended styles.php to styles.css but still didn't line up properly. Come back to this.
<<xList xCase "sort." "." "[tag[topMenu]]">>/%
see the descriptions about the above at: http://apm-plugins.tiddlyspot.com/#StylingPackage.
%/
The activity feed is best for sharing opinions on something. To make best use of it create a tiddler and tag it with a username you would like to share thought with on this subject.

For instance I might create a tiddler called [[Animal I'd least like to be stuck in a cage with]]. I might say 
<<<
I would least like to be stuck in a cage with a lion as it could tear me apart amongst other reasons.
<<<
I then tag it @matias to get @matias's attention to see what he think. This flags it in @matias's activity feed and tells him that I am interested in his thoughts. Of course @matias can ignore it, and if he is not using the activity feed feature he may not even know about the message. If he wants to respond all @matias then has to do is create his own tiddler [[Animal I'd least like to be stuck in a cage with]]. Matias might say
<<<
A lion would be not as bad as a great white shark... not only would you be stuck in a cage with it but you would  be underwater with a likelihood of drowning to increase suffering.
<<<
It's not over yet.. now I can refine my original post with the thoughts of Matias. I might think mm, @matias has got a point there with the water, but I think a crocodile would more likely eat me then a great white shark and I fancy my chances with the great white.

I then update my tiddler to say 
<<<
I would least like to be stuck in a cage with a crocodile as it could tear me apart amongst other reasons. A lion would also be scary however I'm not a good swimmer so would be less likely to be able to make an escape. A crocodile is worse than a shark as shark attacks on humans are rare, so I'd fancy my chances.
<<<

We continue replying this way revising our tiddlers till the process finishes and I have a tiddler which clearly explains the [[Animal I'd least like to be stuck in a cage with]] with very detailed reasoning.
To get to the course gradebook click either:
* Course Menu : Gradebook OR
* Administration : Grades
they both go to the same place. Important features:
# ''Grader report'' -- the default tab |View|. Displays a big table with grade Categories and Items as columns along the top and Student names as rows on the left. You can use the ''+'' ''-'' and ''o'' to expand or contract the display of each category. [[screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/gradebook-grader_report_view.png]]<<imagebox>> This is normally //view only// except when you [Turn editing on]
# ''User Report'' -- |View| tab. On the far right of the menu you can pull down a list of all the students in the course and see //exactly// what they will see in their gradebook display.
# ''Categories and Items'' tab. Is where you setup all your assessment categories and adjust weightings.
# ''Settings'' tab determines how the gradebook appears by default for students. If you want to change the number of decimal points displayed for each grade, or if you want to hide % in the User report you can do that here. Feel free to experiment!
# ''My Preferences'' tab changes the display of View : Grader report that is visible only to //you//.
# All existing assignments from imported courses need to be upgraded. This seems to go smoothly cos I never used the LAE add on.
** Assignment (2.2) are ones which need upgrading. 
# Have to work out a way of getting the Hogwarts users into the system since they did not come over with the Jazz course.
** I suspect that if the users are already there the grades would come over as well.
----
{{ts{18/07/12 10:31}}}
Uploaded Hogwarts users -- grades did not come over. I //think// that it probably needs the course to be saved in 2.x format.
Scheduler //seems// to work OK in a superficial test.
Attendance exactly the same as in 1.9
Test Questionnairre by looking at the CC one.
!!Course backup and restore
* as I've already discovered, user details (including grades) do ''not'' get transferred with a 1.9 backup
* but also, by default, teachers don't have permission to backup students details and therefore grade histories ([[course backup doc|http://docs.moodle.org/23/en/Course_backup]]). Apparently this is for 'security' reasons but it means that the teacher cannot save the course with grades.
* and with no user info the course backup disappears into a 'private backup' area which is not linked to Private Files. Is it accessible anywhere else?
!!User interface
This is cool:

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/m23-display-courses-categories.png]]

# from //moodle.xml// delete the {{{<USER>}}} record for {{{<ID>1246</ID>}}}
# global substitute {{{<USERID>1246</USERID>}}} with {{{<USERID>418</USERID>}}}
# repack course backup, upload, restore and check that now Cho Chang has the grades YES!! Michael Warner not in course
+++[List of users to match]>
|sortable|k
|!First|!Last|!username|!idnumber|!userid|!grade|!Hog first|!Hog 2nd|!Hog uname|!idnumber|!userid|h
|Michael|Warner|mrwarner09|56196|1246|96.19|Cho|Chang|choc||418|
|Nathan|Young|nlyoung07|9798|586|94.69|Fleur|Delacour|fleurd||420|
|Martin|Ventura|mkventu09|19041|1091|94.41|Seamus|Finnigan|seamusf||429|
|Mariah|Kennedy|mmkenne09|47210|1098|93.06|Hermione|Granger|hermioneg||424|
|Patrick|Hall|pmhall09|12418|959|92.49|Viktor|Krum|viktork||430|
|Jeremy|Reed|jsreed10|666992|1192|91.16|Neville|Longbottom|nevillel||426|
|Molly|Mahoney|memahon08|12963|1111|89.5|Luna|Lovegood|lunal||425|
|Dylan|Kyriacopoulos|dgkyria08|11970|938|89.34|Draco|Malfoy|dracom||419|
|David|Slucher|sssluch10|680474|784|88.64|Parvati|Patil|parvatip||427|
|Brittany|Greene|bmgreene08|12932|1525|87.09|Harry|Potter|harryp||423|
|Joel|Hogle|jlhogle08|12424|180|86.02|Fred|Weasley|fredw||421|
|Jacob|LaChance|jllacha09|28815|434|83.09|George|Weasley|georgew||422|
|Thomas|Webb|twwebb10|18091|1220|76.4|Ron|Weasley|ronw||428|
=== 
Repeat for all above users. Yes, the system works! All the hogwarts users have substituted grades.
File is //moodle-updated-final.xml//
An easier way :
# ignore the deletion of users and do this by unenrollment from the restored course.
# Use 'sed' to globally substitute <USERID> numbers -- something like
{{{
 sed -e '%s;<USERID>586</USERID>;<USERID>420</USERID>;g'
}}}
This should substitute all occurrences of userid 586 with 420 including those on the same line. Note use of ';' as delimiter since the subst string has a '/' in it.
!!Completion tracking
> completion tracking (progress) features at course level.
!!Conditional Access
> set conditions (based on date, grade, or completion) that control whether an activity can be accessed.
In [[Repositories and File management in 2.0 – Overview/Discussion|http://moodle.org/mod/forum/discuss.php?d=174702]] Elena Ivanova has summarized resource types and workflows:
!!1. 'Right in place' files
<<<
#    uploaded from a local computer
# copied from an existing repository, e.g. from Legacy Course Files (if enabled) or Alfresco (if available)
# copied from another “right-in-place” resource (File, Folder, embedded with text editor) that you have added previously
Note that you have to maintain all of the copies separately, since they are independent from each other.
<<<
[[possible workflow|https://lh4.googleusercontent.com/-prQJb_D1H8A/TcLv6PaV8yI/AAAAAAAAACU/CO2wAf7CQEM/s576/Moodle20Files_rightinplace.png]]<<imagebox "'Right in place' file workflow">>
!!2. Legacy course files workflow with external linking allowed:
[[possible workflow|https://lh5.googleusercontent.com/-VU3l2mQCwTU/TcLv6Kw6_cI/AAAAAAAAACU/0eho2g6bQ_I/s800/Moodle20Files_LCF.png]]<<imagebox "Legacy Course Files workflow">>
!!3. Outside repository workflow with external linking allowed:
[[possible workflow|https://lh5.googleusercontent.com/-bg0NqkPljo4/TcLv6JMOk_I/AAAAAAAAACU/n_OcQk3xZGY/s800/Moodle20Files_Outside.png]]<<imagebox "Outside repository workflow">>

!!2.0 repositories and their behaviour
[img(60%,auto)[https://lh4.googleusercontent.com/-0WfyYVfK2RE/TcLv6aFU41I/AAAAAAAAACU/0tIhlghvUrY/s750/repositories.jpg][https://lh4.googleusercontent.com/-0WfyYVfK2RE/TcLv6aFU41I/AAAAAAAAACU/0tIhlghvUrY/s750/repositories.jpg]]<<imagebox>>

[img(60%,auto)[http://moodle.org/pluginfile.php/140/mod_forum/post/800310/repositories.jpg][http://moodle.org/pluginfile.php/140/mod_forum/post/800310/repositories.jpg]]<<imagebox>>
Major revamp of Cafelite theme.
+++!![Fonts.] 
Using three fonts from google : {{{   <link href='http://fonts.googleapis.com/css?family=Ubuntu:500|Open+Sans:400,700' rel='stylesheet' type='text/css'> }}}
===
+++!![Original design]

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/theme-cafelite-change-sizes.png]]

Wanted to change sizes so that the content went from 13.3px to 12px.
Achieved this by simply setting {{{body {font-size : } }}} from //10pt// !! to //12px//.
Had to adjust a number of other settings to increase relative sizes
===
+++!![Final home page]

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/theme-cafelite-final-homepage.png]]

Note the new logo!
===
+++!![Final course page]

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/theme-cafelite-final-coursepage.png]]

Here I've fixed the left menu titles to 12px (though they could be made bigger). The //cafelite menu// bar scales to 10.6px and the //breadcrumb// bar to 10.8px. The 'Weekly outline' header stays at 20px but the sectional date headings (//h3.weekdates//) shrink from 15.6px to 14px.
===
+++!![cafelite-wr.css]
{{{cafelite-wr-old.css}}} -> {{{cafelite-wr-new.css}}}
Common:
{{{
  body {
        background-color: #300;
        color:#310;
}}}
Changes:
{{{
        font-family: "arial unicode ms", arial, helvetic      |     font-family: 'Open Sans', sans-serif;
        font-size : 10pt;                                     |     font-style: normal;
        text-align: center;                                   |     font-weight: 400;
                                                              >     font-size : 12px;
                                                              >     text-align: center;
}}}
;Note:
: Font size changes from ''10pt'' to ''12px'' and this changes everything, and especially {{{.content}}}. Everything gets ''smaller'' -- yes, smaller!
: try to figure a way to increase the line-height for .content
Common:
{{{
  /****************
   * core: header *
   ****************/
}}}
Changes:
{{{
                                                              > #header .headermain {
                                                              >     width: 100%;
                                                              >     height : 80px;
                                                              > }
                                                              > .headermain h1{
                                                              >     width : 96.6%;
                                                              >     font-family: 'Ubuntu', sans-serif;
                                                              >     font-size : 2.2em;
                                                              >     font-weight : 500;
                                                              >     color : #ffe;
                                                              >     background-color : #300;
                                                              >     padding : 10px 0 10px 30px;
                                                              > }
#header, #header-home {                                       | #header-home {
        width: 100%;                                          |     width: 100%;
}}}
Common:
{{{
 /****************
  * core: navbar *
  ****************/

.navbar {
}}}
Changes:
{{{
        font-size: 80%;                                       |         font-size: 90%;
}}}
Common:
{{{
  .headingblock, h2.headingblock { 
}}}
Changes:
{{{
         font-size: 150%;                                     |          font-size: 167%;
}}}
===
+++!![cafelite-wr-menu.css]
Just two size changes:
Common:
{{{
#cafelite-wr-menu { 
}}}
Changes:
{{{ font-size: 80%;}}} -> {{{       font-size: 94%;}}}
----
Common:
{{{
#cafelite-wr-menu ul li {
}}}
Changes:
{{{ font-size: 80%;}}} -> {{{       font-size: 94%;}}}
===
+++!![header.html]
{{{
 <?php } else if ($heading) {
     ?>

   <?php print_container_start(true, '', 'header'); ?>
      <div class="headermain">
          <h1><?php echo $heading ?></h1>
      </div>
<?php print_container_end(); ?>

     <div id="cafelite-wr-menu">
         <?php include('cafelite-wr-menu.php'); ?>
     </div>
}}}
Combined with these styles in //cafelite-wr.css// 
{{{
#header .headermain{
    width: 100%;
    height : 80px;
}
.headermain h1{
    font-family: 'Ubuntu', sans-serif;
    font-size : 2.2em;
    font-weight : 500;
    color : #ffe;
    background-color : #300;
    padding : 10px 0 10px 30px;
}
}}}
we get :
[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/theme-cafelite-final-page-header.png]]

where {{{#header .headermain{   height : 80px;} }}} is the crucial setting!
===
+++!![myCourses block]
fix font sizes in my_courses block: //blocks/myCourses/block_myCourses.php// :
{{{
    882         <style type="text/css">
    883             .treeMenuDefault {
    884                 font-size: 90%;
    885                 font-style: normal;
    886             }
    887
    888             .treeMenuBold {
    889                 font-size: 90%;
    890                 font-weight: bold;
    891             }
    892         </style>';
}}}
Change {{{font-size}}} to ''100%'' to match up with all the other blocks.
===
+++![Gradebook Overview]
<<tiddler [[Gradebook Overview]]>>
=== 
!1. Assessment
Here are some examples of how courses are assessed:
|!Course Activity|!number|!% of total grade|
|Laboratory assignments | 13| 52%|
|Written examinations | 3| 30%|
|Essay assignments | 4| 8%|
|Class participation | 10| 10%|
!2. Grading class activities
# There are 13 Lab assignments which are done in the Lab. One possibility is to make each one of these an 'Offline Assignment' activity. Or you might decide to put the grades //straight into the gradebook// with a gradebook item!
** Offline Assignment : These appear on the Course Outline page and can contain instructions, due dates etc and feedback.
** Gradebook item : Quicker to create and can give feedback. But no presence on Course Outline.
# Written exams. These could be take homes or done in class time. Either way a 'Upload a file' assignment might be a good bet. Choosing the 'Advanced uploading of files' option allows you to ZIP and download all the response files, mark them up and then upload back to the students with your comments.
# Essay assignments. Ditto above.
# Class participation. We're going to use the Attendance activity to record and grade class participation as well as attendance, though there are a number of different ways to approach this.
Each course activity item will be assessed out of 100 and then moodle will do the math to figure out points for each assessment category and perhaps display an equivalent letter grade. We'll adjust the grading display so that students can easily see their accumulated grade.
!3. Setup and configuration
# Configure course category (''important'') +++[how to do this]>
Go to Gradebook : |Categories and items| click the edit button.
My preference is to use ''Sum of grades'' aggregation here for reasons which will become clear later on.
;Category name
: "All that Jazz" or similar
; Aggregation
: change from 'simple weighted mean' to //''Sum of grades''//. The 'real' grade (ie the weighted grade) for each category will be added together.
; check
: Aggregate only non-empty grades (empty grades are assumed to be 'not yet graded' and missing student response will have a zero grade)
!!!Category Total
You can give this a name, eg ''Course Total''
;Maximum : 
:''100'' 
;Grade display type : 
:change to //Percentage (letter)// so that students can see their final percent and letter grade. Remember that all the categories will add up to 100.
;Decimal points : 
:can change to 2 or 0 depending on how you feel. Moodle calculates internally to zillions of decimal places.
;Hidden : 
:Can Hide the total until the end of the semester
;NOTE:
: Students can get worried when they see the total grade before the end of the semester and every assignment has been graded since the total is always out of 100 and not out of the running total of graded assignments.
=== 
# Create and configure grading categories. +++[how to do this]>
In Edit categories and items (as before)
Use activity assessments in the same order that you showed to your students.
click Add category
; Category name:
: Labs (52%) [note: add the %weight into the name]
; Aggregation:
: Simple weighted mean. We want the mean of all activities within this category
; check
: Aggregate only non-empty grades
!!!Category Total
; Maximum grade
: enter weight for this category here -- ''52''
Keep the 'Grade display type' at Real(percentage) so that students will see for example 46.8(90%) and know that they got 46.8/52 which was equivalent to 90%, an A-.
=== Create a category for each of the sections listed in the syllabus. Now we have all the categories present -- 
# Create gradable activities and allocate to appropriate category.  +++[how to do this]>
At this point we fill out the gradebook categories with moodle activities. The most commonly used are Assignment and Attendance.
Here's where the Category name comes in handy. For each moodle activity that you are going to grade, go to:
''Common Module settings'' and set
;Grade category
: Laboratories (or whatever is appropriate)
=== 
That's really all there is to it.
!!!Extras:
* If some of the assignments are marooned outside their Category. Here's how to put them in the right places. +++[how to do this]>
# Go to the Categories and Items tab in the gradebook
# click the up:down arrow [img[http://legacy.earlham.edu/~markp/moodledocs/graphics/up_down_arrow.png]] next to the lonely assignment
# click the empty box underneath the Category you want to move it to.
# Repeat with any others
=== 
* Reorder categories if necessary +++[how to do this]>
# again in Edit Categories and items
# click the [img[http://legacy.earlham.edu/~markp/moodledocs/graphics/up_down_arrow.png]] next to a ''Category''
# now move it and the contained assignment(s) into the correct relative position
=== 
All the totals should now add up to 100 which is the course total. The numbers are really easy to check in the Grader Report.
!4. Hiding grades
until you're ready to release them. Here's how it works. Open the ''Categories and Items'' tab and 
* when you click the eyeball on the Grade category (eg Participation) all the items within are hidden together with the total ([[screenshot|http://legacy.earlham.edu/~markp/moodledocs/graphics/gradebook-hiding.png]]<<imagebox>>)
* to hide individual items just click the eyeball. 
* You can also release a whole grade category at a predetermined date and time automatically!
!5. Doing the Grading
Once the Gradebook and activities have been set up the grading is a piece of cake.
When you have Activities only in the gradebook all the grading you do is //in the activity (eg assignment) itself//. 
!6. What the student sees
* Go to the User Report (in the |View| tab) and choose the student name from pulldown menu. You will see exactly what she sees in her gradebook display.
+++!![Compare weighted mean grades with sum of grades]
Another way of accumulating the Category grades is to assess them all out of 100 and then apply a weight to each with the course aggregation set to 'weighted mean'. So using the example above we'd have:
|!Course Activity|!number|!weight as a fraction of total|
|Laboratory assignments | 13| 0.52|
|Written examinations | 3| 0.30|
|Essay assignments | 4| 0.08|
|Class participation | 10| 0.10|
However, the student display looks rather different as below:
|>|!User report as seen by student|
|!course aggregation -- Sum of grades|!course aggregation -- Weighted mean|
|[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/gradebook-user_report_student.png]]|[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/gradebook-user_report_student-2.png]]|
With the sum of grades the students sees her 'real' grade in each category and can simply add them up to check that the total makes sense. However, with the weighted mean there's no place on the report that shows the weigh given for each category -- student is likely to add up all the totals and divide by four and then have an unpleasant surprise
===
* Moodle --2.4.5+-- 2.5.1+
* Theme : Clean
* LAE grader report version {{{$plugin->version   = 2013062100;}}} [[github link|https://github.com/bobpuffer/laegrader]]
# When all the gradeable activities are visible in the gradebook they appear in the LAE Grader Report display [[Screenshot|http://legacy.earlham.edu/~markp/screens/moodle/LAE-grader-M245-v.png]]<<imagebox>>
# But now hide two items on the Categories and Items screen [[Screenshot|http://legacy.earlham.edu/~markp/screens/moodle/LAE-grader-M245-cat-items.png]]<<imagebox>>
# Now return to the LAE Grader Report and see that while the Range and Overall Average columns are present, the grading columns and headers are not displayed [[Screenshot|http://legacy.earlham.edu/~markp/screens/moodle/LAE-grader-M245-missing-headers.png]]<<imagebox>>
# Switching off the display of range and average in the user preferences completely removes any evidence of the hidden items. [[Screenshot|http://legacy.earlham.edu/~markp/screens/moodle/LAE-grader-M245-miss-columns.png]]<<imagebox>>
{{ts{15/08/13 16:30}}} @@Now fixed with version {{{2013081200;}}}@@
https://github.com/bobpuffer/laegrader
//{{{
config.shadowTiddlers["StyleSheetSvgIcons"]="/*{{{*/\n"+
	"/*replace FG with BG if you want to toggle the BackGround insted of the ForeGround */\n"+
	".showFG {\n"+
	"	opacity: 0;\n"+
	"}\n\n"+
	"svg:hover .showFG {\n"+
	"	opacity: 1;\n"+
	"}\n"+
	"/*}}}*/";
store.addNotification("StyleSheetSvgIcons",refreshStyles);
//}}}


<<slider chkSliderOptionsPanel OptionsPanel "Options »" "display the options panel">>
/***
|''Name:''|TiddlySpaceIntraSpaceInclusion|
|''Description:''|Provides support for {{{<<tiddler Foo@bar>>}}} and {{{<<tiddler [[Foo]]@bar>>}}}|
|''Author:''|Jon Robson|
|''Source:''|https://github.com/jdlrobson/TiddlyWikiPlugins/raw/master/plugins/TiddlySpaceIntraSpaceInclusion/TiddlySpaceIntraSpaceInclusion.js|
|''Version:''|0.3.8a|
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.4|
***/
//{{{
(function() {
	var _tidtext = TiddlyWiki.prototype.getTiddlerText;
	var cache = {};

	// allmost the same regExp as in TiddlySpaceLinkPlugin but .. no "mg" parameter, because it didn't work for this usecase.
	config.textPrimitives.spacenameLinkRegExp = new RegExp(config.textPrimitives.unWikiLink + 
													 "?(" + config.textPrimitives.bareTiddlerLetter + "*)@(" + config.textPrimitives.spaceName + ")", "");
	config.textPrimitives.tiddlyLinkSpacenameLinkRegExp = new RegExp("\\[\\[(.*?)(?:\\|(.*?))?\\]\\]@(" + config.textPrimitives.spaceName + ")", "");
	
	TiddlyWiki.prototype.getTiddlerText = function(title, defaultText) {
		var ct = config.textPrimitives;
		var match = ct.spacenameLinkRegExp.exec(title);	// foo@bar
		var match2 = ct.tiddlyLinkSpacenameLinkRegExp.exec(title); 	// [[foo]]@bar
		
		if(match || match2) {
		//	console.log('inner: ', 'spacename: ', match, 'tiddlyLink: ', match2, 'place: ');
			var tidtitle, space;
			if(match[1] && match.length === 3) {
				tidtitle = match[1];
				space = match[2];
			} else if(match2 && match2.length === 4) {
				tidtitle = match2[1];
				space = match2[3];
			}
			var newtitle = tidtitle + "@" + space;
			if(tidtitle && space) {
				title = newtitle;
			}
			if(tidtitle && space && !store.getTiddler(newtitle)) {
				var tiddler = new Tiddler(title);
				// get the tiddler, where the macro is rendered. //XXX will need more testing
				var el = story.findContainingTiddler(place);
				var refreshTitle = (el) ? el.getAttribute('tiddler') : null;

				tiddler.text = "//retrieving from server//";
				tiddler.fields.doNotSave = "true";
				tiddler.tags = ["excludeLists", "excludeSearch", "excludeMissing"];
				merge(tiddler.fields, config.defaultCustomFields);
				tiddler.fields["server.bag"] = space + "_public";
				tiddler = store.addTiddler(tiddler);
				ajaxReq({ url: "/bags/" + space + "_public/tiddlers/" + tidtitle,
					dataType: "json",
					success: function(tid) {
						var tiddler = store.getTiddler(title);
						tiddler.text = tid.text;
						store.addTiddler(tiddler);
						// store.notify(title,true);
						story.refreshTiddler(refreshTitle,null,true);
						// story.refreshAllTiddlers(); // hacky but above link doesn't always seem to work!
					},
					error: function() {
						var tiddler = store.getTiddler(title);
						tiddler.text = "//error retrieving tiddler {{{" + title + "}}} from space @" + space + "//";
						store.addTiddler(tiddler);
						// store.notify(title,true);
						story.refreshTiddler(refreshTitle,null,true);
						// story.refreshAllTiddlers(); // hacky but above link doesn't always seem to work!
					}
				});
			}
		}
		return _tidtext.apply(this, [title, defaultText]);
	}
})();
//}}}
Search
<<gotoTiddler search inputstyle:"width:90%" liststyle:"z-index: 5;">>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onclick="if(jQuery) jQuery(document).trigger('cPermaview', {elem:this, comp:{menue:1}})" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})" title="Link to an URL, that retrieves all the currently displayed tiddlers">
 <metadata id="metadata14">
  <rdf:RDF>
   <cc:Work rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
    <dc:title/>
    <dc:rights>
     <cc:Agent>
      <dc:title>http://creativecommons.org/licenses/by-nc-sa/3.0/at/</dc:title>
     </cc:Agent>
    </dc:rights>
    <dc:source>http://iconbuilder.tiddlyspace.com</dc:source>
    <dc:creator>
     <cc:Agent>
      <dc:title>Mario Pietsch</dc:title>
     </cc:Agent>
    </dc:creator>
   </cc:Work>
  </rdf:RDF>
 </metadata>
 <defs id="defs_bBgTrans">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon">
 <rect id="iconBG" stroke="#696969" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" fill="none" class="showBG"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0,-1,1,0,0,0)" width="22" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showFG"/>
<g id="iconSymbol" stroke-linejoin="miter" transform="matrix(0.7571541,-0.1025239,0.1025239,0.7571541,-1.1616967,17.71349)" stroke="#4d4d4d" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="1.96827316" fill="none" class="showSY">
  <rect id="rect10" ry="3.1727" transform="matrix(0.8660254,-0.5,0.5,0.8660254,0,0)" height="10.086" width="12.486" y="59.54" x="-16.234"/>
  <rect id="rect3046" ry="3.1727" transform="matrix(0.8660254,-0.5,0.5,0.8660254,0,0)" height="10.086" width="12.486" y="59.183" x="-0.94148"/>
  <path id="path3089" d="m25.161,59.553,9.4272-5.2982" stroke-linecap="round"/>
 </g>
 <rect id="overlay" stroke="#696969" opacity="0" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" class="showOV"/>
</g>
</svg>
Utterly Brilliant!
!!New Features
From [[Moodle 2.4 release notes|http://docs.moodle.org/dev/Moodle_2.4_release_notes]] :
Huge # of performance improvements.
!!!Assignment enhancements
*     [[MDL-31284|http://tracker.moodle.org/browse/MDL-31284]] - Group assignments - It will now be possible to set an assignment which a group can work on collaboratively -and receive a common (or individual) grade.
*    [[MDL-31291|http://tracker.moodle.org/browse/MDL-31291]] - @@Blind marking@@ i.e. not knowing the identity of students when grading. Students' names will be replaced by randomly generated Participant numbers. [//Benamou will be pleased with this//]
*    [[MDL-31295|http://tracker.moodle.org/browse/MDL-31295]] - @@Submission date extensions@@ - Teachers can set a cut-off date (and time) beyond which submissions will no longer be accepted. They can also grant extensions for those who miss the deadline. [Earlham teachers never extend submission deadline ;-)]
*    [[MDL-31288|http://tracker.moodle.org/browse/MDL-31288]] - @@Submission statement@@ - It will be possible to set a submission statement so students have to check a box promising their work is original before submitting it. [We could have a system wide //anti-plagiarism statement//]
*    [[MDL-31276|http://tracker.moodle.org/browse/MDL-31276]] - @@Offline marking@@ - Teachers can download all assignments plus the grading sheet, view, grade and give feedback offline and then upload back to Moodle and have the grades/files/comments transferred into Moodle's gradebook. 
** Also [[useful doc|http://docs.moodle.org/24/en/Assignment_settings#Offline_grading_worksheet]] plus [[this test|http://www.somerandomthoughts.com/blog/2012/11/19/offline-grading-worksheet-in-moodle-2-4-assignment/]] in the 'Some Random Thoughts' blog.
!!!Misc
* MDL-29538 - Activities and topics can be [[restricted according to user profile fields|http://docs.moodle.org/24/en/Conditional_user_fields]]
* [[Offline grading for 2.4|http://www.somerandomthoughts.com/blog/2012/11/19/offline-grading-worksheet-in-moodle-2-4-assignment/]]
/***
|''Name:''|XListPlugin|
|''Description:''|Provides a {{{<<xList>>}}} macro, that prepares the list for drag and drop sorting|
|''Author:''|Mario Pietsch|
|''Version:''|0.2.0|
|''Date:''|2010.08.03|
|''Status:''|''beta''|
|''Source:''|http://apm-plugins.tiddlyspot.com/#XListPlugin|
|''License''|[[MIT License]]|
|''CoreVersion:''|2.5.0|
|''Requires:''|XCaseListPlugin |
|''Documentation:''|this file|
|''Keywords:''|list extended sort filter|
!!!Description
<<<
This macro is only needed if you want to use StylingPackage!
If you call {{{ <<xList>> }}} without any parameter you will get a non sortet list of all tiddlers.

!!!!UseCase
{{{
<<xList xCase [prefix] [regExp] [tag]>>
}}}
>*prefix .. can be any string. Default is "sort."
>*regExp .. can be any valid regExp, that runs against the tiddler title. Default is "." (any char except linebreaks)
>*tag .. "[tag[myTag]]" ''If you have spaces inside the tag, it has to be covered inside double quotes !!''
{{{
eg:
<<xList xCase "sort." "." "[tag[with spaces]]">>
}}}
>The above configuration will produce a custom field named {{{sort.with.spaces}}}. Because custom fields have to be lower case and spaces are not allowed. Since the tag name is used for the custom field, one tiddler can be part of different sorted lists. 
<<<

!!!ToDo
<<<
*Test together with MatchTagsPlugin
<<<

!!!History
<<<
*V 0.2.0 - 2010.08.03
**initial release
<<<

***/
/*{{{*/
config.macros.xList = {};
config.macros.xList.xCase = config.macros.list.xCase;

config.macros.xList.handler = function(place,macroName,params)
{
	var type = params[0] || "xCase";
	var sortField = params[1]  || "sort.";
	var tag = params[2] || ".";
	var tag = params[3] || "";

	tag = tag.toLowerCase();
	sortField = sortField.toLowerCase();

	var match = tag.match(/tag *\[(.+) *\] *\]/im);		// get the tag text
	if (match != null) tag = match[1];

	var res = tag.replace(/^\s+|\s+$/g, ""); 		// remove whitespace start and end
	if (res != null) tag = res;

	res = tag.replace(/ +/g, ".");				// replace spaces with a dot 
	if (res != null) tag = res;

	params[1] = sortField+tag;

	var list = document.createElement("ul");

	list.setAttribute('class', 'xList');
	list.setAttribute('tag', tag);
	list.setAttribute('sortfield', sortField);
	place.appendChild(list);
	if(this[type].prompt) {
		createTiddlyElement(list,"li",null,"listTitle",this[type].prompt);
	}
	var results;
	if(this[type].handler) {
// console.log('params: ', params)
		results = this[type].handler(params);
	}
	var li;
	for(var t = 0; t < results.length; t++) {
		li = document.createElement("li");
		li.setAttribute('id', typeof results[t] == "string" ? results[t] : results[t].title);
		list.appendChild(li);
		createTiddlyLink(li,typeof results[t] == "string" ? results[t] : results[t].title,true);
	}
};
/*}}}*/
<<activity show:reply show:notify>>
!Moodle 2013
Tomorrow morning (Tuesday June 26th) at 9am we'll be taking down the IS Moodle server for it's annual update and refit.
The update consists of miscellaneous bug squashes and security fixes. The refit comprises a new theme modeled on Earlham colours of maroon and grey and featuring a handy links bar, date display and other subtle enhancements (see how many you can spot!).
The updating process will take us longer than previously because not only are we going to tidy up the database, with magical SQL incantations, we will also be creating all the courses together with departmental categories for next semester and ordering everything in alphabetical order. So expect the system to be offline for at least the morning and possibly early afternoon. We have already run through all the procedures we need to follow but demon gremlins always threaten to derail hasty work so we err on the side of caution.
For more details of the appearance of  the refurbished moodle site [[CLICK HERE!|http://moodle.tiddlyspace.com/#IS-moodle-appearance-2013]]
[[Posting to IS Moodle News]]
<<tiddler ToggleLeftSidebarEm##show with: {{config.options.chkShowLeftSidebar?'◄':'►'}}{{config.options.chkShowRightSidebar?'hide':'show'}}>><<tiddler ToggleRightSidebarEm##show with: {{config.options.chkShowRightSidebar?'►':'◄'}}{{config.options.chkShowRightSidebar?'hide':'show'}}>><<slider chkSliderOptionsPanel OptionsPanel "»" "display the options panel">>
|''Name:''|[[NeUIemTheme02]]|
|''Description:''|Changes the right sidebar|
|''Generator:''|[[TW FreeStyle|http://FreeStyle.tiddlyspot.com]]|
|''Gen.Description:''|Handcrafted by @pmario|
|''PageTemplate:''|NeUIemTheme##PageTemplate|
|''ViewTemplate:''|NeUIemTheme##ViewTemplate|
|''EditTemplate:''|NeUIemTheme##EditTemplate|
|''RevisionTemplate:''|NeUIemTheme##RevisionTemplate|
|''StyleSheet:''|##StyleSheet|

!StyleSheet
/*{{{*/

[[NeUIemTheme##StyleSheet]]

#sidebarTabs .tabset{
	float: left;
	width: 1em;
	padding: 0;
}

#sidebarTabs .tabset:hover{
	width: auto;
	position:absolute;
	right: 86%;
	padding-right: 8%;
	z-index: 10;
}

#sidebarTabs .tabset .tab{
	overflow: hidden;
	display: block;
}
/*}}}*/
|''Name:''|[[NeUIemTheme01]]|
|''Description:''|Changes the right sidebar|
|''Generator:''|[[TW FreeStyle|http://FreeStyle.tiddlyspot.com]]|
|''Gen.Description:''|Handcrafted by @pmario|
|''PageTemplate:''|NeUIemTheme##PageTemplate|
|''ViewTemplate:''|NeUIemTheme##ViewTemplate|
|''EditTemplate:''|NeUIemTheme##EditTemplate|
|''RevisionTemplate:''|NeUIemTheme##RevisionTemplate|
|''StyleSheet:''|##StyleSheet|

!StyleSheet
/*{{{*/

[[NeUIemTheme##StyleSheet]]

#sidebarTabs .tabset{
	float: left;
	width: 1em;
	padding: 0;
}

#sidebarTabs .tabset:hover{
	width: auto;
}

#sidebarTabs .tabset .tab{
	overflow: hidden;
	display: block;
}
/*}}}*/
<<tiddler SidebarTools>>/%
If you prefere a Tools slider, use the line below
<<slider chkSliderToolsPanel  SidebarTools  "Tools »" "new, save, ...">>
%/
<<binaryUpload edit:tags edit:title>>
Elizabeth Heath is teaching two sections of INTP150-1 and -9 'Sustainable Agriculture'
She wants to use the OUWiki Activity for project proposals (and the projects themselves?) and has set up a OUWiki activity for this purpose configured as 'separate wikis for every user'. She wants students to be able to upload photos and other images into their wiki page and also comment on each other's proposals. However, the default course configuration does not let students do these things.
All my experimenting was done with http://rublev.lly.earlham.edu/~markp/test-12/ with course Defence Against the Dark Arts with the Hogwarts group of virtual students / faculty
!!Fix wiki commenting
+++!!![Attempt #1 -- Override permissions]
When you update an Activity the admin get a screen with three tabs :
* Settings
* Locally assigned roles
* Override permissions
First off I tried using Override Permission for the student role:
I set the following OUWiki capabilities to //Allow//:
> Allowed to annotate, Comment on wiki pages, Edit wiki pages, View wikis, Per-user sub-wikis:view all, View list of contributions organised by user, Per-user subwikis: view same group
This did not work -- students could go to other user's wiki pages but could not comment or annotate.
=== 
+++!!![Attempt #2 -- create new role and add students in course]
In Site Admin > Users > Permissions > Define Roles I created a //Wiki student// role based on the legacy student role and added the list of OUWiki capabilities given above.
Then Back to the course and open Admin : Enrollments to add students to the //Wiki student// role for the //whole course//. The advantage of this approach is that if it worked the students would be have permissions for all OUWiki activities created.
''However'', the new role does not appear to work very well and does not appear in the Participants list, so students in this role are de facto unenrolled from the course.
I'm sure that I'm doing something wrong here but I don't know what it is.
=== 
+++!!![Attempt #3 -- expand list of capabilities]
I noted that assigning students the teacher role //in the context of the OUwiki activity// did empower them to make comments. So I added some more capabilities that the Teacher role had access to:
* Delete wiki page comments, Allowed to lock and unlock pages, Override locked pages
* --Delete wiki page versions-- permission not allowed.
Give Spiggy Topes the Wiki student role in the OUWiki activity -- [Locally assigned roles] : Wiki student.
Can edit and annotate own pages and can view all other student pages but not annotate or edit.
Evidently some other permission is also needed
=== 
+++!!![Attempt #4 -- assign students to Teacher role]
Need a bigger sledgehammer here. Go back to [Update OUwiki] : [Locally assigned roles]
* Now enroll all students as Teacher role for this OUWiki Activity.
Having done this, the Edit , Annotate and History tabs appear and the students can edit and annotate each other's pages.
=== @@SORTED@@
!!Add ability to upload graphics
# Set Administration : Enrollments : [Override permissions] -- Student > Course : Manage files
To use, each student should create their own directory and store files there.
This allows students access to the Course Files area.



/*{{{*/
/* new nui */
.concertina {
	overflow: hidden;
	display: none;
	height: 0;
	background-color: white;
}

.concertina br {
	display: none;
}


.concertinaOn .concertina {
	display: auto;
	height: auto;
	border-bottom: 1px solid [[ColorPalette: :PrimaryDark]];
	overflow: auto;
}

.concertina .publishButton {
	border-radius: 1em;
	-webkit-border-radius: 15px;
	-moz-border-radius: 15px;
	border-radius: 15px;
	background-color: white;
	border: 1px solid black;
	display: block;
	padding: 0.3em;
	text-align: center;
	width: 12em;
}

.privateNotPublic .concertina,
.private .concertina {
	background: -webkit-gradient(linear,left bottom,left top,color-stop(0.05,#DE85B3),color-stop(0.5,#eee),color-stop(1, #fff));
	background: -moz-linear-gradient(top center , #fff 5%, #eee 20%, #DE85B3 100%);
	/* For Internet Explorer 5.5 - 7 */
	filter: "progid: DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff, endColorstr=#ffDE85B3)";
	/* For Internet Explorer 8 */
	-ms-filter: "progid: DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff, endColorstr=#ffDE85B3)";
}

.public .concertina,
.privateAndPublic .concertina {
	background: -webkit-gradient(linear,left bottom,left top,color-stop(0.05, #BBE7FD),color-stop(0.5,#eee),color-stop(1, #fff));
	background: -moz-linear-gradient(top center , #fff 5%, #eee 20%, #BBE7FD 100%);
	/* For Internet Explorer 5.5 - 7 */
	filter: "progid: DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff, endColorstr=#ffBBE7FD)";
	/* For Internet Explorer 8 */
	-ms-filter: "progid: DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff, endColorstr=#ffBBE7FD)";
}

.external .concertina {
	background-color: white;
	background: -webkit-gradient(linear,left bottom,left top,color-stop(0.05, #8BD69E),color-stop(0.5,#eee),color-stop(1, #fff));
	background: -moz-linear-gradient(top center , #fff 5%, #eee 20%, #8BD69E 100%);
	/* For Internet Explorer 5.5 - 7 */
	filter: "progid: DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff, endColorstr=#ff8BD69E)";
	/* For Internet Explorer 8 */
	-ms-filter: "progid: DXImageTransform.Microsoft.gradient(startColorstr=#ffffffff, endColorstr=#ff8BD69E)";
}

/* fix grayout from original tw. */
.selected .tagging,
.selected .tagged,
.selected .tagging:hover,
.selected .tagged:hover {
	background: none;
	border: none;
}

.tagging, .tagged {
	background: none;
	border: none;
	padding: 0.5em 0 0 0.5em;
}

.tagging {
	float: none;
}

/** nächste zeile wirkt nicht ??? */
.tagging ul {
	margin: 0.25em 0 0 0.3em;
}

.tagging li {
	display: inline;
	float: left;
}

.tagging .tiddlyLink {
	-webkit-border-radius: 5px 5px 5px 5px;
	-moz-border-radius: 5px 5px 5px 5px;
	border-radius: 5px 5px 5px 5px;
	background-color: white;
	display: block;
	margin: 0 0.2em 0.2em;
        padding: 0.8em;
}

/* nui */
.tagged {
	float: none;
	margin-top: 1em;
}

.tagged .quickopentag {
	-webkit-border-radius: 0px 15px 15px 0px;
	-moz-border-radius: 0px 15px 15px 0px;
	border-radius: 0px 15px 15px 0px;
	background-color: white;
	border: 2px 2px 2px 0 solid #ccc;
	display: block;
	margin: 0 0.2em 0.2em -1.1em;
	padding: 0 0.4em;
	font-size: 0.9em;
}

.tagged a.button,
.tagged a.tiddlyLink {
	border: none;
	display: inline;
	font-size: 0.9em;
	word-wrap: break-word;
}

.tagged a:hover {
	font-weight: bold;
	background: white;
	color: [[ColorPalette::PrimaryDark]]; 
}

/* for following nui */
#popup .siteIcon {
	height: 25px;
}

#popup {
	background-color: [[ColorPalette::TertiaryPale]];
}

.confirmationPopup, .followList {
	font-size: 0.7em;
	padding: 1em;
	border: solid 1px #000;
}

.followList .listTitle {
	text-decoration: underline;
}

#popup .followTiddlersList a {
	display: inline;
	padding: 0;
}

#popup li a {
	color: [[ColorPalette::PrimaryMid]];
	font-weight: bold;
}

#popup li a:hover {
	color: [[ColorPalette::PrimaryMid]];
	background: none;
}

#popup li.listTitle {
	border-bottom: 1px solid #000;
	font-weight: bold;
	margin-bottom: 10px;
}

#popup.followList {
	margin-left: 50px;
	margin-top: -30px;
}

.followTiddlersList .label {
	display: block;
	left: 10px;
	top: 0px;
	line-height: 16px;
	position: relative;
}

#popup .followTiddlersList .siteIcon{
	height: auto;
}

#popup .followTiddlersList li{
	clear: both;
	display: block;
	height: 48px;
	margin-bottom: 8px;
	position: relative;
}

#popup .followTiddlersList a{
	display: inline;
}

.heading {
	left: 0;
	margin-bottom: 3em;
	position: relative;
	top: 3em;
	position: relative;
}

.followButton a:hover {
	background: none;
	color: black;
}

.followPlaceHolder {
	position: absolute;
	left: 0.5em;
	top: 0.5em;
}

.followButton {
	cursor: pointer;
	-webkit-border-radius: 0.3em;
	-moz-border-radius: 0.3em;
	border-radius: 0.3em;
	background: none repeat scroll 0 0 #CCCCCC;
	color: red;
	min-width: 2em;
	height: 1em;
	text-align: center;
	padding: 0.4em;
	float: left;
}

.replyLink {
	margin-left: 1em;
	font-size: 80%;
	opacity: 0.3;
}

.selected .replyLink {
	opacity: 1;
}


.calendar {
	margin-top: 1em;
	cursor: pointer;

/* 	if calendar is to wide, enable next line */
/*	margin: 1em 1.5em;  */	
}

.calendar:hover {
	opacity: 0.8;
}

.calendar .month {
	color: [[ColorPalette::PrimaryPale]];
	font-size: 1.2em;
	border-left: solid 1px black;
	border-right: solid 1px black;
	border-top: solid 1px black;
	text-align: center;
	padding: 2px;
}

.calendar .date {
	color: [[ColorPalette::PrimaryDark]];
	font-size: 1.2em;
	font-weight: bold;
	text-align: center;
	border: solid 1px black;
}

.calendar .time {
	font-size: 0.7em;
	border-left: solid 1px black;
	border-right: solid 1px black;
	border-bottom: solid 1px black;
	text-align: center;
}

.toolbar svg {
	height: 20pt;
	width: 20pt;
}

.toolbar svg .glyph{
	fill: #ccc;
}

.toolbar a:hover .glyph{
	fill: #111;
}

.toolbar .command_savePublicTiddler .glyph {
	fill: #C0E5FC;
}

.originButton,
.modifierIcon .label {
	color: [[ColorPalette::TertiaryDark]];
	font-size: 0.8em;
	text-align: center;
	display: block;
}

.modifierIcon {
	background: [[ColorPalette::PrimaryLight]];
	margin-right: 1em;
}

.tiddler {
	overflow: hidden;	/* clear floats */
}

.tiddler .viewer {
	margin: 0;
	line-height: normal;
	padding-top: 0;
}

.tiddler .title {
	font-size: 1.7em;
	display: block;
	margin-bottom: 0.4em;
	border-bottom: 0.05em solid [[ColorPalette: :PrimaryDark]];
	padding-top: 0;
	word-wrap: break-word;
}

.spaceIcon img {
	height: 30px;
}

.siteIcon .label {
	color: [[ColorPalette: :TertiaryDark]];
}

.siteIcon {
	text-align: center;
}

.siteIcon img {
	height: 30px;
	width: 30px;
}

.tiddler .spaceSiteIcon {
	margin: 0;
	cursor: pointer;
}

.followButton a {
	color: red;
}

.tiddler {
	position: relative;
	-moz-box-shadow: 2px 2px 8px black;
	-webkit-box-shadow: 2px 2px 8px black;
	filter: progid: DXImageTransform.Microsoft.Shadow(color='#000000', Direction=135, Strength=3);
	box-shadow: 2px 2px 8px black;
	background-color: [[ColorPalette::PrimaryLight]];
	margin-bottom: 2em;
	padding: 0;
}


.tiddler .subtitle {
	font-size: 0.8em;
	margin-top: 0.2em;
}

.external .spaceSiteIcon a:hover {
	background-color: #8BD69E;
}

.privateNotPublic .spaceSiteIcon a:hover,
.private .spaceSiteIcon a:hover {
	background-color: #DE85B3;
}

.privateAndPublic .spaceSiteIcon a:hover,
.public .spaceSiteIcon a:hover {
	background-color: #BBE7FD;
}

.tiddler .toolbar .button {
	border: none;
	display: inline-block;
}

/*-- reset the button effect --*/
.tiddler .toolbar a:hover {
	background: none;
	border: none;
}

/**
.tiddler .button.command_closeTiddler {
	float: right;
}
**/

.tiddler .tagged .listTitle {
	display: none;
}

.revButton {
	float: right;
}

/*}}}*/
|''Name:''|[[NeUIemTheme04]]|
|''Description:''|Play with the toolbar visibility|
|''Generator:''|[[TW FreeStyle|http://FreeStyle.tiddlyspot.com]]|
|''Gen.Description:''|Handcrafted by @pmario|
|''PageTemplate:''|NeUIemTheme##PageTemplate|
|''ViewTemplate:''|NeUIemTheme##ViewTemplate|
|''EditTemplate:''|NeUIemTheme##EditTemplate|
|''RevisionTemplate:''|NeUIemTheme##RevisionTemplate|
|''StyleSheet:''|##StyleSheet|

!StyleSheet
/*{{{*/
[[NeUIemTheme03##StyleSheet]]

/* Play with the toolbar visibility */
.toolbar {
	visibility: hidden; 
/*	opacity: 0.2; */
}

.selected .toolbar {
	visibility: visible; 
/*	opacity: 1; */
}

/*}}}*/
/***
|''Name:''|FollowTiddlersButtonPlugin|
|''Description:''|Wraps followTiddlers macro into a button, which needs to be clicked to activate it.|
|''Author:''|Mario Pietsch|
|''Source:''||
|''Version:''|0.1.0|
|''Status:''|beta|
|''Date:''|2010.12.06|
|''Requires:''|TiddlySpaceFollowingPlugin|
|''License:''|BSD|
|''~CoreVersion:''||
Click the [?] button, to get {{{<<followTiddlers>>}}} macro activated.
!!!!Use
<<<
{{{
<<followTiddlersButton>> instead of <<followTiddlers>>
}}}
<<<
!!!!ViewTemplate 
<<<
{{{
	<div class='followPlaceHolder' macro='followTiddlersButton'>
		<span macro="view title replyLink"></span>
	</div>
}}}
<<<

***/
/*{{{*/
version.extensions.TiddlySpaceHacks = {major: 0, minor: 1, revision: 0, date: new Date(2010,12,06)};

(function ($) {

var ftb;		
config.macros.followTiddlersButton = ftb = {

	// should be done for easy localisation
	locale: {
		lblButton: '?',
		txtButton: 'Find other spaces, that contain a tiddler with the same title',
	},

	handler: function(place, macroName, params, wikifier, paramString, tiddler){
		if (!config.macros.followTiddlers) return false;
		var btn = null;

		// createTiddlyButton(parent, text, tooltip, action, className, id, accessKey, attribs)			
		btn = createTiddlyButton(place, ftb.locale.lblButton, ftb.locale.txtButton, ftb.onClick, 'followButton');

		// passing all arguments to the function
		$(btn).data('data', arguments);
	},

	onClick: function() {
		var a = $(this).data("data");

		if (a) {
			config.macros.followTiddlers.handler.apply(config.macros.followTiddlers, a);
			$(this).remove();
		}
		return false;
	}

}; // end of hello world

}) (jQuery);
/*}}}*/
/***
|Name|SearchOptionsPlugin|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|3.0.10 modified addClass removeClass hasClass removeChildren|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|extend core search function with additional user-configurable options|
Adds extra options to core search function including selecting which data items to search, enabling/disabling incremental key-by-key searches, and generating a ''list of matching tiddlers'' instead of immediately displaying all matches.  This plugin also adds syntax for rendering 'search links' within tiddler content to embed one-click searches using pre-defined 'hard-coded' search terms.
!!!!!Documentation
>see [[SearchOptionsPluginInfo]]
!!!!!Configuration
<<<
<<tiddler SearchOptions>>
<<option chkSearchResultsOptions>> Include {{{options...}}} slider in "search again" form
<<<
!!!!!Revisions
<<<
2011.04.08 3.0.10 fixed typo in CSS in formatSearchResults_buttons().  Restore missing options in Configuration section.
|please see [[SearchOptionsPluginInfo]] for additional revision details|
2005.10.18 1.0.0 Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.SearchOptionsPlugin= {major: 3, minor: 0, revision: 10, date: new Date(2011,3,18)};
//}}}
//{{{
var defaults={
	chkSearchTitles:	true,
	chkSearchText:		true,
	chkSearchTags:		true,
	chkSearchFields:	true,
	chkSearchTitlesFirst:	true,
	chkSearchList:		true,
	chkSearchHighlight:	true,
	chkSearchListTiddler:	false,
	chkSearchByDate:	false,
	chkIncrementalSearch:	true,
	chkSearchShadows:	true,
	chkSearchOpenTiddlers:	false,
	chkSearchResultsOptions:true,
	chkSearchExcludeTags:	true,
	txtSearchExcludeTags:	'excludeSearch',
	txtIncrementalSearchDelay:	500,
	txtIncrementalSearchMin:	3
}; for (var id in defaults) if (config.options[id]===undefined)
	config.options[id]=defaults[id];
if (config.macros.search.reportTitle==undefined)
	config.macros.search.reportTitle="SearchResults"; // note: not a cookie!
config.macros.search.label+="\xa0"; // a little bit of space just because it looks better
//}}}
// // searchLink: {{{[search[text to find]] OR [search[text to display|text to find]]}}}
//{{{
config.formatters.push( {
	name: "searchLink",
	match: "\\[search\\[",
	lookaheadRegExp: /\[search\[(.*?)(?:\|(.*?))?\]\]/mg,
	prompt: "search for: '%0'",
	handler: function(w)
	{
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var label=lookaheadMatch[1];
			var text=lookaheadMatch[2]||label;
			var prompt=this.prompt.format([text]);
			var btn=createTiddlyButton(w.output,label,prompt,
				function(){story.search(this.getAttribute("searchText"))},"searchLink");
			btn.setAttribute("searchText",text);
			w.nextMatch = this.lookaheadRegExp.lastIndex;
		}
	}
});
//}}}
// // incremental search uses option settings instead of hard-coded delay and minimum input values
//{{{
var fn=config.macros.search.onKeyPress;
fn=fn.toString().replace(/500/g, "config.options.txtIncrementalSearchDelay||500");
fn=fn.toString().replace(/> 2/g, ">=(config.options.txtIncrementalSearchMin||3)");
eval("config.macros.search.onKeyPress="+fn);
//}}}
// // REPLACE story.search() for option to "show search results in a list"
//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
	var co=config.options; // abbrev
	var re=new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
	if (config.options.chkSearchHighlight) highlightHack=re;
	var matches = store.search(re,co.chkSearchByDate?"modified":"title","");
	if (co.chkSearchByDate) matches=matches.reverse(); // most recent first
	var q = useRegExp ? "/" : "'";
	clearMessage();
	if (!matches.length) {
		if (co.chkSearchListTiddler) discardSearchResults();
		displayMessage(config.macros.search.failureMsg.format([q+text+q]));
	} else {
		if (co.chkSearchList||co.chkSearchListTiddler) 
			reportSearchResults(text,matches);
		else {
			var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);
			this.closeAllTiddlers(); story.displayTiddlers(null,titles);
			displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));
		}
	}
	highlightHack = null;
}
//}}}
// // REPLACE store.search() for enhanced searching/sorting options
//{{{
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag,match)
{
	var co=config.options; // abbrev
	var tids = this.reverseLookup("tags",excludeTag,!!match,sortField);
	var opened=[]; story.forEachTiddler(function(tid,elem){opened.push(tid);});

	// eliminate tiddlers tagged with excluded tags
	if (co.chkSearchExcludeTags&&co.txtSearchExcludeTags.length) {
		var ex=co.txtSearchExcludeTags.readBracketedList();
		var temp=[]; for(var t=tids.length-1; t>=0; t--)
			if (!tids[t].tags.containsAny(ex)) temp.push(tids[t]);
		tids=temp;
	}

	// scan for matching titles first...
	var results = [];
	if (co.chkSearchTitles) {
		for(var t=0; t<tids.length; t++) {
			if (co.chkSearchOpenTiddlers && !opened.contains(tids[t].title)) continue; 
			if(tids[t].title.search(searchRegExp)!=-1) results.push(tids[t]);
		}
		if (co.chkSearchShadows)
			for (var t in config.shadowTiddlers) {
				if (co.chkSearchOpenTiddlers && !opened.contains(t)) continue; 
				if ((t.search(searchRegExp)!=-1) && !store.tiddlerExists(t))
					results.push((new Tiddler()).assign(t,config.shadowTiddlers[t]));
			}
	}
	// then scan for matching text, tags, or field data
	for(var t=0; t<tids.length; t++) {
		if (co.chkSearchOpenTiddlers && !opened.contains(tids[t].title)) continue; 
		if (co.chkSearchText && tids[t].text.search(searchRegExp)!=-1)
			results.pushUnique(tids[t]);
		if (co.chkSearchTags && tids[t].tags.join(" ").search(searchRegExp)!=-1)
			results.pushUnique(tids[t]);
		if (co.chkSearchFields && store.forEachField!=undefined)
			store.forEachField(tids[t],
				function(tid,field,val) {
					if (val.search(searchRegExp)!=-1) results.pushUnique(tids[t]);
				},
				true); // extended fields only
	}
	// then check for matching text in shadows
	if (co.chkSearchShadows)
		for (var t in config.shadowTiddlers) {
			if (co.chkSearchOpenTiddlers && !opened.contains(t)) continue; 
			if ((config.shadowTiddlers[t].search(searchRegExp)!=-1) && !store.tiddlerExists(t))
				results.pushUnique((new Tiddler()).assign(t,config.shadowTiddlers[t]));
		}

	// if not 'titles first', or sorting by modification date,
	// re-sort results to so titles, text, tag and field matches are mixed together
	if(!sortField) sortField = "title";
	var bySortField=function(a,b){
		if(a[sortField]==b[sortField])return(0);else return(a[sortField]<b[sortField])?-1:+1;
	}
	if (!co.chkSearchTitlesFirst || co.chkSearchByDate) results.sort(bySortField);

	return results;
}
//}}}
// // HIJACK core {{{<<search>>}}} macro to add "report" and "simple inline" output
//{{{
config.macros.search.SOP_handler=config.macros.search.handler;
config.macros.search.handler = function(place,macroName,params)
{
	// if "report", use SearchOptionsPlugin report generator for inline output
	if (params[1]&&params[1].substr(0,6)=="report") {
		var keyword=params[0];
		var options=params[1].split("=")[1]; // split "report=option+option+..."
		var heading=params[2]?params[2].unescapeLineBreaks():"";
		var matches=store.search(new RegExp(keyword.escapeRegExp(),"img"),"title","excludeSearch");
		if (matches.length) wikify(heading+window.formatSearchResults(keyword,matches,options),place);
	} else if (params[1]) {
		var keyword=params[0];
		var heading=params[1]?params[1].unescapeLineBreaks():"";
		var seperator=params[2]?params[2].unescapeLineBreaks():", ";
		var matches=store.search(new RegExp(keyword.escapeRegExp(),"img"),"title","excludeSearch");
		if (matches.length) {
			var out=[];
			for (var m=0; m<matches.length; m++) out.push("[["+matches[m].title+"]]");
			wikify(heading+out.join(seperator),place);
		}
	} else
		config.macros.search.SOP_handler.apply(this,arguments);
};
//}}}
// // SearchResults panel handling
//{{{
setStylesheet(".searchResults { padding:1em 1em 0 1em; }","searchResults"); // matches std tiddler padding

config.macros.search.createPanel=function(text,matches,body) {

	function getByClass(e,c) { var d=e.getElementsByTagName("div");
		for (var i=0;i<d.length;i++) if (jQuery(d[i]).hasClass(c)) return d[i]; }
	var panel=createTiddlyElement(null,"div","searchPanel","searchPanel");
	this.renderPanel(panel,text,matches,body);
	var oldpanel=document.getElementById("searchPanel");
	if (!oldpanel) { // insert new panel just above tiddlers
		var da=document.getElementById("displayArea");
		da.insertBefore(panel,da.firstChild);
	} else { // if panel exists
		var oldwrap=getByClass(oldpanel,"searchResults");
		var newwrap=getByClass(panel,"searchResults");
		// if no prior content, just insert new content
		if (!oldwrap) oldpanel.insertBefore(newwrap,null);
		else {	// swap search results content but leave containing panel intact
			oldwrap.style.display='block'; // unfold wrapper if needed
			var i=oldwrap.getElementsByTagName("input")[0]; // get input field
			if (i) { var pos=this.getCursorPos(i); i.onblur=null; } // get cursor pos, ignore blur
			oldpanel.replaceChild(newwrap,oldwrap);
			panel=oldpanel; // use existing panel
		} 
	}
	this.showPanel(true,pos);
	return panel;
}

config.macros.search.renderPanel=function(panel,text,matches,body) {

	var wrap=createTiddlyElement(panel,"div",null,"searchResults");
	wrap.onmouseover = function(e){ jQuery(this).addClass("selected"); }
	wrap.onmouseout = function(e){ jQuery(this).removeClass("selected"); }
	// create toolbar: "open all", "fold/unfold", "close"
	var tb=createTiddlyElement(wrap,"div",null,"toolbar");
	var b=createTiddlyButton(tb, "open all", "open all matching tiddlers", function() {
		story.displayTiddlers(null,this.getAttribute("list").readBracketedList()); return false; },"button");
	var list=""; for(var t=0;t<matches.length;t++) list+='[['+matches[t].title+']] ';
	b.setAttribute("list",list);
	var b=createTiddlyButton(tb, "fold", "toggle display of search results", function() {
		config.macros.search.foldPanel(this); return false; },"button");
	var b=createTiddlyButton(tb, "close", "dismiss search results",	function() {
		config.macros.search.showPanel(false); return false; },"button");
	createTiddlyText(createTiddlyElement(wrap,"div",null,"title"),"Search for: "+text); // title
	wikify(body,createTiddlyElement(wrap,"div",null,"viewer")); // report
	return panel;
}

config.macros.search.showPanel=function(show,pos) {
	var panel=document.getElementById("searchPanel");
	var i=panel.getElementsByTagName("input")[0];
	i.onfocus=show?function(){config.macros.search.stayFocused(true);}:null;
	i.onblur=show?function(){config.macros.search.stayFocused(false);}:null;
	if (show && panel.style.display=="block") { // if shown, grab focus, restore cursor
		if (i&&this.stayFocused()) { i.focus(); this.setCursorPos(i,pos); }
		return;
	}
	if(!config.options.chkAnimate) {
		panel.style.display=show?"block":"none";
		if (!show) { jQuery(panel).empty(); config.macros.search.stayFocused(false); }
	} else {
		var s=new Slider(panel,show,false,show?"none":"children");
		s.callback=function(e,p){e.style.overflow="visible";}
		anim.startAnimating(s);
	}
	return panel;
}

config.macros.search.foldPanel=function(button) {
	var d=document.getElementById("searchPanel").getElementsByTagName("div");
	for (var i=0;i<d.length;i++) if (jQuery(d[i]).hasClass("viewer")) var v=d[i]; if (!v) return;
	var show=v.style.display=="none";
	if(!config.options.chkAnimate)
		v.style.display=show?"block":"none";
	else {
		var s=new Slider(v,show,false,"none");
		s.callback=function(e,p){e.style.overflow="visible";}
		anim.startAnimating(s);
	}
	button.innerHTML=show?"fold":"unfold";
	return false;
}

config.macros.search.stayFocused=function(keep) { // TRUE/FALSE=set value, no args=get value
	if (keep===undefined) return this.keepReportInFocus;
	this.keepReportInFocus=keep;
	return keep
}	

config.macros.search.getCursorPos=function(i) {
	var s=0; var e=0; if (!i) return { start:s, end:e };
	try {
		if (i.setSelectionRange) // FF
			{ s=i.selectionStart; e=i.selectionEnd; }
		if (document.selection && document.selection.createRange) { // IE
			var r=document.selection.createRange().duplicate();
			var len=r.text.length; s=0-r.moveStart('character',-100000); e=s+len;
		}
	}catch(e){};
	return { start:s, end:e };
}
config.macros.search.setCursorPos=function(i,pos) {
	if (!i||!pos) return; var s=pos.start; var e=pos.end;
	if (i.setSelectionRange) //FF
		i.setSelectionRange(s,e);
	if (i.createTextRange) // IE
		{ var r=i.createTextRange(); r.collapse(true); r.moveStart("character",s); r.select(); }
}
//}}}
// // SearchResults report generation
// note: these functions are defined globally, so they can be more easily redefined to customize report formats//
//{{{
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
	var cms=config.macros.search; // abbrev
	var body=window.formatSearchResults(text,matches);
	if (!config.options.chkSearchListTiddler) // show #searchResults panel
		window.scrollTo(0,ensureVisible(cms.createPanel(text,matches,body)));
	else { // write [[SearchResults]] tiddler
		var title=cms.reportTitle;
		var who=config.options.txtUserName;
		var when=new Date();
		var tags="excludeLists excludeSearch temporary";
		var tid=store.getTiddler(title); if (!tid) tid=new Tiddler();
		tid.set(title,body,who,when,tags);
		store.addTiddler(tid);
		story.closeTiddler(title);
		story.displayTiddler(null,title);
	}
}

if (!window.formatSearchResults) window.formatSearchResults=function(text,matches,opt)
{
	var body='';
	var title=config.macros.search.reportTitle
	var q = config.options.chkRegExpSearch ? "/" : "'";
	if (!opt) var opt="all";
	var parts=opt.split("+");
	for (var i=0; i<parts.length; i++) { var p=parts[i].toLowerCase();
		if (p=="again"||p=="all")   body+=window.formatSearchResults_again(text,matches);
		if (p=="summary"||p=="all") body+=window.formatSearchResults_summary(text,matches);
		if (p=="list"||p=="all")    body+=window.formatSearchResults_list(text,matches);
		if (p=="buttons"||p=="all") body+=window.formatSearchResults_buttons(text,matches);
	}
	return body;
}

if (!window.formatSearchResults_again) window.formatSearchResults_again=function(text,matches)
{
	var title=config.macros.search.reportTitle
	var body='';
	// search again
	body+='{{span{<<search "'+text.replace(/"/g,'&#x22;')+'">> /%\n';
	body+='%/<html><input type="button" value="search again"';
	body+=' onclick="var t=this.parentNode.parentNode.getElementsByTagName(\'input\')[0];';
	body+=' config.macros.search.doSearch(t); return false;">';
	if (!config.options.chkSearchResultsOptions) // omit "options..."
		body+='</html>';
	else {
		body+=' <a href="javascript:;" onclick="';
		body+=' var e=this.parentNode.nextSibling;';
		body+=' var show=e.style.display!=\'block\';';
		body+=' if(!config.options.chkAnimate) e.style.display=show?\'block\':\'none\';';
		body+=' else anim.startAnimating(new Slider(e,show,false,\'none\'));';
		body+=' return false;">options...</a>';
		body+='</html>@@display:none;border-left:1px dotted;margin-left:1em;padding:0;padding-left:.5em;font-size:90%;/%\n';
		body+='	%/<<tiddler SearchOptions>>@@';
	};
	body+='}}}\n\n';
	return body;
}

if (!window.formatSearchResults_summary) window.formatSearchResults_summary=function(text,matches)
{
	// summary: nn tiddlers found matching '...', options used
	var body='';
	var co=config.options; // abbrev
	var title=config.macros.search.reportTitle
	var q = co.chkRegExpSearch ? "/" : "'";
	body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
	var opts=[];
	if (co.chkSearchTitles) opts.push("titles");
	if (co.chkSearchText) opts.push("text");
	if (co.chkSearchTags) opts.push("tags");
	if (co.chkSearchFields) opts.push("fields");
	if (co.chkSearchShadows) opts.push("shadows");
	if (co.chkSearchOpenTiddlers) body+="^^//search limited to displayed tiddlers only//^^\n";
	body+="~~&nbsp; searched in "+opts.join(" + ")+"~~\n";
	body+=(co.chkCaseSensitiveSearch||co.chkRegExpSearch?"^^&nbsp; using ":"")
		+(co.chkCaseSensitiveSearch?"case-sensitive ":"")
		+(co.chkRegExpSearch?"pattern ":"")
		+(co.chkCaseSensitiveSearch||co.chkRegExpSearch?"matching^^\n":"");
	return body;
}

if (!window.formatSearchResults_list) window.formatSearchResults_list=function(text,matches)
{
	// bullet list of links to matching tiddlers
	var body='';
	var co=config.options; // abbrev
	var pattern=co.chkRegExpSearch?text:text.escapeRegExp();
	var sensitive=co.chkCaseSensitiveSearch?"mg":"img";
	var link='{{tiddlyLinkExisting{<html><nowiki><a href="javascript:;" onclick="'
		+'if(config.options.chkSearchHighlight)'
		+'	highlightHack=new RegExp(\x27'+pattern+'\x27.escapeRegExp(),\x27'+sensitive+'\x27);'
		+'story.displayTiddler(null,\x27%0\x27);'
		+'highlightHack = null; return false;'
		+'" title="%2">%1</a></html>}}}';
	for(var t=0;t<matches.length;t++) {
		body+="* ";
		if (co.chkSearchByDate)
			body+=matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" ";
		var title=matches[t].title;
		var fixup=title.replace(/'/g,"\\x27").replace(/"/g,"\\x22");
		var tid=store.getTiddler(title);
		var tip=tid?tid.getSubtitle():''; tip=tip.replace(/"/g,"&quot;");
		body+=link.format([fixup,title,tip])+'\n';
	}
	return body;
}

if (!window.formatSearchResults_buttons) window.formatSearchResults_buttons=function(text,matches)
{
	// embed buttons only if writing SearchResults to tiddler
	if (!config.options.chkSearchListTiddler) return "";
	// "open all" button
	var title=config.macros.search.reportTitle;
	var body="";
	body+="@@display:block;<html><input type=\"button\" href=\"javascript:;\" "
		+"onclick=\"story.displayTiddlers(null,[";
	for(var t=0;t<matches.length;t++)
		body+="'"+matches[t].title.replace(/\'/mg,"\\'")+"'"+((t<matches.length-1)?", ":"");
	body+="],1);\" accesskey=\"O\" value=\"open all matching tiddlers\"></html> ";
	// "discard SearchResults" button
	body+="<html><input type=\"button\" href=\"javascript:;\" "
		+"onclick=\"discardSearchResults()\" value=\"discard "+title+"\"></html>";
	body+="@@\n";
	return body;
}

if (!window.discardSearchResults) window.discardSearchResults=function()
{
	// remove the tiddler
	story.closeTiddler(config.macros.search.reportTitle);
	store.deleteTiddler(config.macros.search.reportTitle);
	store.notify(config.macros.search.reportTitle,true);
}
//}}}
// // DELIVER [[SearchOptions]] shadow payload
//{{{
config.shadowTiddlers.SearchOptions = store.getTiddlerText('SearchOptionsPlugin##panel','');
config.annotations.SearchOptions    = 'created by SearchOptionsPlugin';
//}}}
/***
//{{{
!panel
search in:
  {{nowrap{<<option chkSearchTitles>>titles <<option chkSearchText>>text <<option chkSearchTags>>tags}}} /%
%/{{nowrap{<<option chkSearchFields>>fields <<option chkSearchShadows>>shadows}}}
----
  {{nowrap{<<option chkCaseSensitiveSearch>>case-sensitive}}} /%
%/{{nowrap{<<option chkRegExpSearch>>match text patterns}}}
  {{nowrap{<<option chkIncrementalSearch>>key-by-key search:}}} /%
	%/{{threechar smallform nowrap{<<option txtIncrementalSearchMin>> or more characters}}} /%
	%/{{threechar smallform nowrap{<<option txtIncrementalSearchDelay>> msec delay}}}<hr>
  {{nowrap{<<option chkSearchList>>show results in a list &nbsp; &nbsp;}}} /%
%/{{nowrap{<<option chkSearchListTiddler>>save list in ''[[SearchResults]]''}}}
  {{nowrap{<<option chkSearchTitlesFirst>>show title matches first}}} /%
%/{{nowrap{<<option chkSearchByDate>>sort results by date}}} /%
%/{{nowrap{<<option chkSearchHighlight>>highlight matching text}}}
----
{{nowrap{<<option chkSearchOpenTiddlers>>search open tiddlers only}}}
{{nowrap{<<option chkSearchExcludeTags>>exclude tiddlers tagged with:}}}
{{editor{<<option txtSearchExcludeTags>>}}}
!end
//}}}
***/
 
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
Do a search in mdl_config_plugins for the theme name. 
{{{
SELECT * FROM `mdl_config_plugins` WHERE `plugin` LIKE '%cloudyday%' ;
}}}
Then delete:
{{{
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1248;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1346;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1347;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1348;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1349;
}}}

Do for :
* custom_corners {{{DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1121;}}}
* jupiter {{{DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1251;}}}
* mercury -- done
* pluto -- done
* recoil -- +++[4 hits]>
{{{
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1255;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1406;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1407;
DELETE FROM `26clmoo14`.`mdl_config_plugins` WHERE `mdl_config_plugins`.`id` = 1408;
}}}
=== 
* uranus -- done
<!--{{{-->
<div class='toolbar'
	macro='toolbar [[ToolbarCommands::ViewToolbar]] icons:yes height:16 width:16 more:popup'>
</div>
<div class='heading'>
	<span class='spaceSiteIcon'
		macro='tiddlerOrigin label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
	</span>
	<span class="titleBar">
		<div class='title' macro='view title text'></div>
		<span class="subtitle" macro='viewRevisions page:5'>
			last modified on
			<span macro="view modified date"></span>
		</span>
		<div macro="view title replyLink"></div>
	</span>
	<span class='followPlaceHolder' macro='followTiddlers'></span>
	<span class='modifierIcon'
		macro='view modifier SiteIcon label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
	</span>
	<div class='tagClear'></div>
</div>
<div class='content'>
	<div class='viewer' macro='view text wikified'></div>
</div>
<div class='tagInfo'>
	<div class='tidTags' macro='tags'></div>
	<div class='tagging' macro='tagging'></div>
</div>
<!--}}}-->
/***
|Name|GotoPlugin|
|Source|http://www.TiddlyTools.com/#GotoPlugin|
|Documentation|http://www.TiddlyTools.com/#GotoPluginInfo|
|Version|1.9.? - hacked because of: https://groups.google.com/forum/?fromgroups#!topic/tiddlywiki/Pwt4ogJIS-s|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|view any tiddler by entering it's title - displays list of possible matches|
''View a tiddler by typing its title and pressing //enter//.''  As you type, a list of possible matches is displayed.  You can scroll-and-click (or use arrows+enter) to select/view a tiddler, or press escape to close the listbox to resume typing.  When the listbox is not displayed, pressing //escape// clears the current input.
!!!Documentation
>see [[GotoPluginInfo]]
!!!Configuration
<<<
*Match titles only after {{twochar{<<option txtIncrementalSearchMin>>}}} or more characters are entered.<br>Use down-arrow to start matching with shorter input.  //Note: This option value is also set/used by [[SearchOptionsPlugin]]//.
*To set the maximum height of the listbox, you can create a tiddler tagged with <<tag systemConfig>>, containing:
//{{{
config.macros.gotoTiddler.listMaxSize=10;  // change this number
//}}}
<<<
!!!Revisions
<<<
2009.05.22 [1.9.2] use reverseLookup() for IncludePlugin
|please see [[GotoPluginInfo]] for additional revision details|
2006.05.05 [0.0.0] started
<<<
!!!Code
***/
//{{{
version.extensions.GotoPlugin= {major: 1, minor: 9, revision: 2, date: new Date(2009,5,22)};

// automatically tweak shadow SideBarOptions to add <<gotoTiddler>> macro above <<search>>
config.shadowTiddlers.SideBarOptions=config.shadowTiddlers.SideBarOptions.replace(/<<search>>/,"{{button{goto}}}\n<<gotoTiddler>><<search>>");

if (config.options.txtIncrementalSearchMin===undefined) config.options.txtIncrementalSearchMin=3;

config.macros.gotoTiddler= { 
	listMaxSize: 10,
	listHeading: 'Found %0 matching title%1...',
	searchItem: "Search for '%0'...",
	handler:
	function(place,macroName,params,wikifier,paramString,tiddler) {
		var quiet	=params.contains("quiet");
		var showlist	=params.contains("showlist");
		var search	=params.contains("search");
		params = paramString.parseParams("anon",null,true,false,false);
		var instyle	=getParam(params,"inputstyle","");
		var liststyle	=getParam(params,"liststyle","");
		var filter	=getParam(params,"filter","");
		var html=this.html;
		var keyevent=window.event?"onkeydown":"onkeydown"; // IE event fixup for ESC handling
		html=html.replace(/%keyevent%/g,keyevent);
		html=html.replace(/%search%/g,search);
		html=html.replace(/%quiet%/g,quiet);
		html=html.replace(/%showlist%/g,showlist);
		html=html.replace(/%display%/g,showlist?'block':'none');
		html=html.replace(/%position%/g,showlist?'static':'absolute');
		html=html.replace(/%instyle%/g,instyle);
		html=html.replace(/%liststyle%/g,liststyle);
		html=html.replace(/%filter%/g,filter);
		if (config.browser.isIE) html=this.IEtableFixup.format([html]);
		var span=createTiddlyElement(place,'span');
		span.innerHTML=html; var form=span.getElementsByTagName("form")[0];
		if (showlist) this.fillList(form.list,'',filter,search,0);
	},
	html:
	'<form onsubmit="return false" style="display:inline;margin:0;padding:0">\
		<input name=gotoTiddler type=text autocomplete="off" accesskey="G" style="%instyle%"\
			title="Enter title text... ENTER=goto, SHIFT-ENTER=search for text, DOWN=select from list"\
			onfocus="this.select(); this.setAttribute(\'accesskey\',\'G\');"\
			%keyevent%="return config.macros.gotoTiddler.inputEscKeyHandler(event,this,this.form.list,%search%,%showlist%);"\
			onkeyup="return config.macros.gotoTiddler.inputKeyHandler(event,this,%quiet%,%search%,%showlist%);">\
		<select name=list style="display:%display%;position:%position%;%liststyle%"\
			onchange="if (!this.selectedIndex) this.selectedIndex=1;"\
			onblur="this.style.display=%showlist%?\'block\':\'none\';"\
			%keyevent%="return config.macros.gotoTiddler.selectKeyHandler(event,this,this.form.gotoTiddler,%showlist%);"\
			onclick="return config.macros.gotoTiddler.processItem(this.value,this.form.gotoTiddler,this,%showlist%);">\
		</select><input name="filter" type="hidden" value="%filter%">\
	</form>',
	IEtableFixup:
	"<table style='width:100%;display:inline;padding:0;margin:0;border:0;'>\
		<tr style='padding:0;margin:0;border:0;'><td style='padding:0;margin:0;border:0;'>\
		%0</td></tr></table>",
	getItems:
	function(list,val,filter) {
		if (!list.cache || !list.cache.length || val.length<=config.options.txtIncrementalSearchMin) {
			// starting new search, fetch and cache list of tiddlers/shadows/tags
			list.cache=new Array();
			if (filter.length) {
				var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
				var tiddlers=store.sortTiddlers(fn.apply(store,[filter]),'title');
			} else 
				var tiddlers=store.reverseLookup('tags','excludeLists');
			for(var t=0; t<tiddlers.length; t++) list.cache.push(tiddlers[t].title);
			if (!filter.length) {
				for (var t in config.shadowTiddlers) list.cache.pushUnique(t);
				var tags=store.getTags();
				for(var t=0; t<tags.length; t++) list.cache.pushUnique(tags[t][0]);
			}
		}
		var found = [];
		var match=val.toLowerCase();
		for(var i=0; i<list.cache.length; i++)
			if (list.cache[i].toLowerCase().indexOf(match)!=-1) found.push(list.cache[i]);
		return found;
	},
	getItemSuffix:
	function(t) {
		if (store.tiddlerExists(t)) return "";  // tiddler
		if (store.isShadowTiddler(t)) return " (shadow)"; // shadow
		return " (tag)"; // tag 
	},
	fillList:
	function(list,val,filter,search,key) {
		if (list.style.display=="none") return; // not visible... do nothing!
		var indent='\xa0\xa0\xa0';
		var found = this.getItems(list,val,filter); // find matching items...
		found.sort(); // alpha by title
		while (list.length > 0) list.options[0]=null; // clear list
		var hdr=this.listHeading.format([found.length,found.length==1?"":"s"]);
		list.options[0]=new Option(hdr,"",false,false);
		for (var t=0; t<found.length; t++) list.options[list.length]=
			new Option(indent+found[t]+this.getItemSuffix(found[t]),found[t],false,false);
		if (search)
			list.options[list.length]=new Option(this.searchItem.format([val]),"*",false,false);
		list.size=(list.length<this.listMaxSize?list.length:this.listMaxSize); // resize list...
		list.selectedIndex=key==38?list.length-1:key==40?1:0;
	},
	keyProcessed:
	function(ev) { // utility function
		ev.cancelBubble=true; // IE4+
		try{event.keyCode=0;}catch(e){}; // IE5
		if (window.event) ev.returnValue=false; // IE6
		if (ev.preventDefault) ev.preventDefault(); // moz/opera/konqueror
		if (ev.stopPropagation) ev.stopPropagation(); // all
		return false;
	},
	inputEscKeyHandler:
	function(event,here,list,search,showlist) {
		if (event.keyCode==27) {
			if (showlist) { // clear input, reset list
				here.value=here.defaultValue;
				this.fillList(list,'',here.form.filter.value,search,0);
			}
			else if (list.style.display=="none") // clear input
				here.value=here.defaultValue;
			else list.style.display="none"; // hide list
			return this.keyProcessed(event);
		}
		return true; // key bubbles up
	},
	inputKeyHandler:
	function(event,here,quiet,search,showlist) {
		var key=event.keyCode;
		var list=here.form.list;
		var filter=here.form.filter;
		// non-printing chars bubble up, except for a few:
		if (key<48) switch(key) {
			// backspace=8, enter=13, space=32, up=38, down=40, delete=46
			case 8: case 13: case 32: case 38: case 40: case 46: break; default: return true;
		}
		// blank input... if down/enter... fall through (list all)... else, and hide or reset list
		if (!here.value.length && !(key==40 || key==13)) {
			if (showlist) this.fillList(here.form.list,'',here.form.filter.value,search,0);
			else list.style.display="none";
			return this.keyProcessed(event);
		}
		// hide list if quiet, or below input minimum (and not showlist)
		list.style.display=(!showlist&&(quiet||here.value.length<config.options.txtIncrementalSearchMin))?'none':'block';
		// non-blank input... enter=show/create tiddler, SHIFT-enter=search for text
		if (key==13 && here.value.length) return this.processItem(event.shiftKey?'*':here.value,here,list,showlist);
		// up or down key, or enter with blank input... shows and moves to list...
		if (key==38 || key==40 || key==13) { list.style.display="block"; list.focus(); }
		this.fillList(list,here.value,filter.value,search,key);
		return true; // key bubbles up
	},
	selectKeyHandler:
	function(event,list,editfield,showlist) {
		if (event.keyCode==27) // escape... hide list, move to edit field
			{ editfield.focus(); list.style.display=showlist?'block':'none'; return this.keyProcessed(event); }
		if (event.keyCode==13 && list.value.length) // enter... view selected item
			{ this.processItem(list.value,editfield,list,showlist); return this.keyProcessed(event); }
		return true; // key bubbles up
	},
	processItem:
	function(title,here,list,showlist) {
		if (!title.length) return;
		list.style.display=showlist?'block':'none';
		if (title=="*")	{ story.search(here.value); return false; } // do full-text search
		if (!showlist) here.value=title;
		story.displayTiddler(null,title); // show selected tiddler
		return false;
	}
}
//}}}
!!Administrative Assistants
* Cheri Gaddis (Mac)
* Bobbi Cayard-Roberts (Mac)
* Jane Niccum (Mac)
* Sarah Emmer (PC)
* Lyn Thomas (PC)
* JoBeth Buckley (?)
* Sandy Jackson (Mac?)
* ''[[Polly Wilde|Institutional Research]]'' (PC?)
* ''Sonia Smith'' (PC)
** Terry Shipley (Mac)
** Amanda Abney (PC)
** Erica Butler (Mac)
** Marcia Sparkes (Mac)
Mac -- 6
PC -- 5
!!Library Folks
* Neal
* Amy
* Jane
* Kate
* Lajmar
!!ITAM
* Wes
* Barbara
* Knoll
* Dakota
/*{{{*/
// Start with one of the following themes:
// "NeUIemTheme", "NeUIemTheme01", "NeUIemTheme02", "NeUIemTheme03", "NeUIemTheme04", 
// "TWDefaultTheme" 
config.options.txtTheme = "NeUIemTheme03"

// A temporary hack, to activate transclusions again
config.evaluateMacroParameters = "full";

// remove leading // at the lines below to aktivate left or right sidebar
// config.options.chkShowRightSidebar = false;		// false or true
// config.options.chkShowLeftSidebar  = false;		// false or true
/*}}}*/
<!--{{{-->
<div macro='slideRevision'></div>
[[NeUIemTheme##ViewTemplate]]
<!--}}}-->

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onclick="if(jQuery) jQuery(document).trigger('cSaveChanges', {elem:this, comp:{menue:1}})" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})" title="Save all tiddlers to the web">
 <metadata id="metadata14">
  <rdf:RDF>
   <cc:Work rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
    <dc:title/>
    <dc:rights>
     <cc:Agent>
      <dc:title>http://creativecommons.org/licenses/by-nc-sa/3.0/at/</dc:title>
     </cc:Agent>
    </dc:rights>
    <dc:source>http://iconbuilder.tiddlyspace.com</dc:source>
    <dc:creator>
     <cc:Agent>
      <dc:title>Mario Pietsch</dc:title>
     </cc:Agent>
    </dc:creator>
   </cc:Work>
  </rdf:RDF>
 </metadata>
 <defs id="defs_bBgTrans">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon">
 <rect id="iconBG" stroke="#696969" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" fill="none" class="showBG"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0,-1,1,0,0,0)" width="22" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showFG"/>
<g id="iconSymbol" stroke-linejoin="round" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" fill="none" class="showSY">
  <path d="m27.73,61.043,3.2374,1.8989-1.9264,0,0,3.2808-2.8131,0,0-3.2808-1.7352,0,3.2374-1.8989z" stroke-width="1.3"/>
  <g transform="matrix(1.0777574,0.08745459,-0.09502165,0.99192987,39.787119,-3.5323126)" fill="none">
   <path d="m-8.7109,55.478,8.1326-1.4778,0.13409,8.5172" stroke-width="1.3"/>
   <path d="m-8.623,55.846-1.7958,9.5134" stroke-width="1.5"/>
   <path d="M-30.522,13.653-13.966,26.834" transform="matrix(0.8,0,0,0.8,13,43)" stroke-width="2"/>
   <path d="m-32.798,31.699,17.733-19.616" transform="matrix(0.8,0,0,0.8,13,43)" stroke-width="2"/>
  </g>
 </g>
 <rect id="overlay" stroke="#696969" opacity="0" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" class="showOV"/>
</g>
</svg>
{{{
~/public_html/poomoo26/theme]$ sudo  cp -R shoelace ~/moo-code/15-spring/
~/public_html/poomoo26/theme/shoelace]$  git branch -a
~/public_html/poomoo26/theme/shoelace]$  git checkout -b fix_location
~/public_html/poomoo26/theme/shoelace]$  git branch -a
~/public_html/poomoo26/theme/shoelace]$  cd layout/
~/public_html/poomoo26/theme/shoelace/layout]$ vim secure.php
}}}
''edit the file location''
{{{
   <?php require_once(dirname(__FILE__).'/footerblocks.php'); ?>

:s;/footerblocks.php;/tiles/footer_blocks.php;
}}}
{{{
~/public_html/poomoo26/theme/shoelace/layout]$  cd ..
~/public_html/poomoo26/theme/shoelace]$  git commit -a -m 'Correct the location and name of footerblocks.php'
}}}
And we don't care if this branch gets overwritten at the next update -- in fact we want this to happen!
<<timeline "modified" "17" "YYYY-0MM-0DD">>
[[::complete timeline|Timeline]]
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink" version="1.1" viewBox="434 218 68 68"
width="30" height="30">
<g stroke="none" stroke-opacity="1" stroke-dasharray="none" fill="none" fill-opacity="1">
	<g>
		<path d="M 478.39694 232.53705 L 478.39694 232.53705 
		C 477.1145 231.85132 475.77875 231.30147 474.41058 230.88734 L 474.41058 218.24994 L 461.58942 218.24994 
		L 461.58942 230.88734 C 460.22125 231.30147 458.8855 231.85132 457.60306 232.53705 L 448.66824 223.60214 
		L 439.6022 232.66814 L 448.53717 241.60304 C 447.8515 242.8854 447.30157 244.22116 446.88745 245.58936 
		L 434.25 245.58936 L 434.25 258.41052 L 446.88745 258.41052 
		C 447.30157 259.77869 447.8515 261.11447 448.53717 262.39688 L 439.6022 271.33173 L 448.66824 280.3978 
		L 457.60306 271.46283 C 458.8855 272.14862 460.22125 272.69846 461.58942 273.11252 L 461.58942 285.74988 
		L 474.41058 285.74988 L 474.41058 273.11252 C 475.77875 272.69846 477.1145 272.14862 478.39694 271.46283 
		L 487.33176 280.3978 L 496.39767 271.33173 L 487.46286 262.39688 
		C 488.14853 261.11447 488.69836 259.77869 489.11255 258.41052 L 501.74988 258.41052 L 501.74988 245.58936 
		L 489.11255 245.58936 C 488.69836 244.22116 488.14853 242.8854 487.46286 241.60304 L 496.39767 232.66814 
		L 487.33176 223.60214 Z M 475.3328 244.66714 C 479.3825 248.71698 479.3825 255.2829 475.3328 259.33273 
		C 471.28296 263.3826 464.71704 263.3826 460.66724 259.33273 
		C 456.61737 255.2829 456.61737 248.71698 460.66724 244.66714 
		C 464.71704 240.61734 471.28296 240.61734 475.3328 244.66714" fill="#111"
		class="glyph"/>
	</g>
</g>
</svg>
{{noBullets{<<xList xCase "sort." "." "[tag[mainMenu]]">>}}}/%
see the descriptions about the above at: http://apm-plugins.tiddlyspot.com/#StylingPackage.
have fun!
-m
%/
Mail to the Moodle Sobor at {{ts{31/07/12 11:22}}}:

Before I ask Aaron to update the Moodle Production with what we've been running on moodletest I wanted to point out what will change. Basically in terms of code we're looking at a minor bug fix / security update to 1.9.18 from 1.9.16. And I'll pull in the latest course/enrollment update from Banner LMB. But the major change which you might notice is with the theme. While the theme format and colours stay the same the font sizes are slated to be slightly bigger, and more importantly, one consistent size throughout (14px). This should make for a decent display.
Current font sizes on Moodle Production:

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/prod-moodle-fontsize-theme.png]]

Font sizes with new theme :

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/moodletest-fontsize-theme.png]]

I just want to make sure that you're happy with this. Thanks are due to the roaming ITAM youth Dakota who switched me on to using 'rem' for font sizing rather than 'em'.
/***
!EmasticPercent
***/
/*{{{*/
.dp5, .dp10,.dp15,.dp20,.dp25,.dp30,.dp33,.dp35,.dp40,.dp45,.dp50,
.dp55,.dp60,.dp65,.dp67,.dp70,.dp75,.dp80,.dp85,.dp90,.dp95,.dp100
{float:left; display: inline; }
	
.dp5{width:5%;}
.dp10{width:10%;*width:9.9%;}  .dp15{width:15%;*width:14.9%;}    .dp20 {width:20%;*width:19.9%;}
.dp25{width:25%;*width:24.9%;} .dp30{width:30%;*width:29.9%;}    .dp33 {width:33.33%;*width:33.3%;}
.dp35{width:35%;*width:34.9%;} .dp40{width:40%;*width:39.9%;}    .dp45 {width:45%;*width:44.9%;}
.dp50{width:50%;*width:49.9%;} .dp55{width:55%;*width:54.9%;}    .dp60 {width:60%;*width:59.9%;}
.dp65{width:65%;*width:64.9%;} .dp67{width:66.67%;*width:66.6%;} .dp70 {width:70%;*width:69.9%;}
.dp75{width:75%;*width:74.9%;} .dp80{width:80%;*width:79.9%;}    .dp85 {width:85%;*width:84.9%;}
.dp90{width:90%;*width:89.9%;} .dp95{width:95%;*width:94.9%;}    .dp100{width:100%;*width:99.9%;}
/*}}}*/
/***
!EmasticGrid
***/
/*{{{*/
.main { width:70em;margin:0 auto;text-align:left;  }
.clear {clear:both;}

.dl1,.dl2,.dl5,.dl10,.dl15,.dl20,.dl25,.dl30,.dl35,.dl40,.dl45,.dl50,.dl55,.dl60,.dl65,.dl70,.dl75
{float:left; display: inline; }

.dr1,.dr2,.dr5,.dr10,.dr15,.dr20,.dr25,.dr30,.dr35,.dr40,.dr45,.dr50,.dr55,.dr60,.dr65,.dr70,.dr75
{float:right; display: inline; }

.dl1,  .dr1 {width:1em;}  .dl2,  .dr2 {width:2em;}  .dl5,  .dr5 {width:5em;}
.dl10, .dr10{width:10em;} .dl15, .dr15{width:15em;} .dl20, .dr20{width:20em;}
.dl25, .dr25{width:25em;} .dl30, .dr30{width:30em;} .dl35, .dr35{width:35em;}
.dl40, .dr40{width:40em;} .dl45, .dr45{width:45em;} .dl50, .dr50{width:50em;}
.dl55, .dr55{width:55em;} .dl60, .dr60{width:60em;} .dl65, .dr65{width:65em;}
.dl70, .dr70{width:70em;} .dl75, .dr75{width:75em;}

.ml1 {margin-left:1em;}  .ml2 {margin-left:2em;}  .ml3 {margin-left:3em;}  .ml4 {margin-left:4em;}    
.ml5 {margin-left:5em;}  .ml10{margin-left:10em;} .ml15{margin-left:15em;}
.ml20{margin-left:20em;} .ml25{margin-left:25em;} .ml30{margin-left:30em;}
.ml35{margin-left:35em;} .ml40{margin-left:40em;} .ml45{margin-left:45em;}
.ml50{margin-left:50em;} .ml55{margin-left:55em;} .ml60{margin-left:60em;}
.ml65{margin-left:65em;} .ml70{margin-left:70em;} .ml75{margin-left:75em;}

.mr5 {margin-right:5em;}  .mr10{margin-right:10em;} .mr15{margin-right:15em;} 
.mr20{margin-right:20em;} .mr25{margin-right:25em;} .mr30{margin-right:30em;}
.mr35{margin-right:35em;} .mr40{margin-right:40em;} .mr45{margin-right:45em;}
.mr50{margin-right:50em;} .mr55{margin-right:55em;} .mr60{margin-right:60em;}
.mr65{margin-right:65em;} .mr70{margin-right:70em;} .mr75{margin-right:75em;}

.mt1{margin-top:1em;}   .mt2{margin-top:2em;}   .mt3{margin-top:3em;}   .mt4{margin-top:4em;}
.mt5{margin-top:5em;}   .mt10{margin-top:10em;}
.mt20{margin-top:20em;} .mt30{margin-top:30em;} .mt40{margin-top:40em;}
.mt50{margin-top:50em;}

.fluid {width:auto; float:none;}

.hp{width:100%;  float:left; }

.clearfix, .main{ display:block;} 

.clearfix:after, .main:after {
     visibility: hidden;
     display: block;
     font-size: 0;
     content: " ";
     clear: both;
     height: 0;
	 
     }

/* IE5/MAC hack \*/
* html .clearfix{ display: inline;  height: 1px;}
/* close */ 
/*}}}*/
/***
!EmasticAbsolut
***/
/*{{{*/
.main{position:relative;}
.lf0,.lf5,.lf10,.lf15,.lf20,.lf25,.lf30,.lf35,.lf40,.lf45,.lf50,.lf55,.lf60,.lf65,.lf70,.lf75,.lf80,.lf85,.lfn5,.lfn10,.lfn15,.lfn20,.lfn25,.lfn30,
.tp0,.tp5,.tp10,.tp15,.tp20,.tp25,.tp30,.tp35,.tp40,.tp45,.tp50,
.bt0,.bt5,.bt10,.bt15,.bt20,.bt25,.bt30,.bt35,.bt40,.bt45,.bt50,
.rtn5,.rtn10,.rtn20,.rtn30{position:absolute;}
.lf0{left:0em;}   .lf5{left:5em;}   .lf10{left:10em;} .lf15{left:15em;} .lf20{left:20em;}
.lf25{left:25em;} .lf30{left:30em;} .lf35{left:35em;} .lf40{left:40em;} .lf45{left:45em;}
.lf50{left:50em;} .lf55{left:55em;} .lf60{left:60em;} .lf65{left:65em;} .lf70{left:70em;}
.lf75{left:75em;} .lf80{left:80em;} .lf85{left:85em;} .lfn5{left:-5em;} .lfn10{left:-10em;}

.lfn15{left:-15em;} .lfn20{left:-20em;} .lfn25{left:-25em;} .lfn30{left:-30em;}

.rtn5 {right:-5em;}  .rtn10{right:-10em;} .rtn15{right:-15em;} .rtn20{right:-20em;}
.rtn25{right:-25em;} .rtn30{right:-30em;}

.tp0 {top:0em;}  .tp5{top:5em;}   .tp10{top:10em;} .tp15{top:15em;} .tp20{top:20em;} .tp25{top:25em;}
.tp30{top:30em;} .tp35{top:35em;} .tp40{top:40em;} .tp45{top:45em;} .tp50{top:50em;} 

.bt0{bottom:0em;}   .bt5{bottom:0em;} .bt10{bottom:10em;} .bt15{bottom:15em;} .bt20{bottom:20em;}
.bt25{bottom:25em;} .bt30{bottom:30em;} .bt35{bottom:35em;} .bt40{bottom:40em;} .bt45{bottom:45em;}
.bt50{bottom:50em;}

.zi1{ z-index:1;} .zi2{ z-index:2;} .zi3{ z-index:3;} .zi4{ z-index:4;} .zi5{ z-index:5;}
/*}}}*/
/***
!EmasticGadgets
***/
/*{{{*/
/* CSS Document */
.rc {-moz-border-radius: 10px;  -webkit-border-radius: 10px;  border-radius: 10px; border:1px solid #fff; }
.fr {border:1px solid #ccc; padding:0.25em;}

.byline {
font-family: "Lucida Grande", Tahoma;
	font-size: 0.865em;
	font-weight: lighter;
	font-variant: normal;
	text-transform: uppercase;
	color: #666666;
	letter-spacing: 0.4em;
	display: block;
	margin-bottom: 1.734em;
	padding:0em 0em 0em 1em;
	}
	
.and {font-family: Baskerville, "Goudy Old Style", "Palatino", "Book Antiqua", serif;
	font-style: italic;
	color: #777;
	}

.tc {text-align:center;}
.tr {text-align:right;}
.tl {text-align:left;}
.b  {font-weight:bold;}
.pl1{padding-left:1em;}
.pl2{padding-left:2em;}
.pl3{padding-left:3em;}

.ppl2{padding-left:1.8%;}
.ppl3{padding-left:3.13%;}
.ppl5{padding-left:4.8%;}

.water{color:#5582d1;}
.earth{color:#4e3e2c;}
.air{color:#f1fff7;}
.fire{ color:#ff8a19;}
 /* drinks food */
 .wine{color:#4a040a;}
 .beer{color:#F0C030;}
 .caffe{color:#473523;}
 .caffe-cream{color:#b68d3d;}
 .espresso{color:#2c1901;}
 .caramel{color:#ab671f;}
 .chocolate{color:#290200;}
 .black-pepper{color:#444334;}
 .pepper-lite{color:#8d8a72;}
 
 .lipstick{color:#c20c0c;}
 .oldbook{font-family:"Book Antiqua","Warnock Pro","Goudy Old Style","Palatino",Georgia,serif;}
.note{font-family:Georgia, "Times New Roman", Times, serif; font-style:italic; font-size:0.9em; margin:0.1em; color:#333;} 
.mono{font-family:"Courier New", Courier, monospace;}
/*}}}*/
/***
!EmasticFreeStyle
***/
/*{{{*/
.dpfr{float:right;}
/*}}}*/
I got this email from the NanoGong folks on May 26:

The NanoGong voice recording/playback applet with integrated Moodle functionality is a very popular extension of Moodle 1, with many thousands of genuine downloads from our server to date. You may be interested to know that we have just released these packages for supporting NanoGong voice recording within Moodle 2:
*    NanoGong activity module
*    NanoGong plugin for the HTML editor (TinyMCE)
All information about NanoGong, including videos, demonstrations and downloads, is available at the NanoGong web site:
    http://nanogong.ust.hk
!!!Basic use of NanoGong:
*    record/playback/pause/jump to any point in time in the recording
*    speed up/slow down the recording
*    can post the recording to a web site
*    can save the recording to your hard disk
If you don't know about the basic things NanoGong can do you could take a look at this video:
    http://www.youtube.com/watch?v=-KyVU3IC7E4
There are two newly released features for integration with Moodle 2 which use NanoGong. Here is a brief summary of both.
!!!The NanoGong Activity within Moodle 2
*    Students can record themselves and submit voice messages to their teachers
*    Students can (optionally) hear other recordings from students
*    Teachers can listen to and (optionally) grade students' voice submissions
*    Teachers can (optionally) give voice/text feedback to students
*    Students can leave a message for the teacher, if needed
*    Accidentally deleted messages can be restored
Here are two videos which demonstrate the NanoGong Activity in Moodle 2.
;As a student:
:    http://www.youtube.com/watch?v=uCpw_oyungg
;As a teacher:
:    http://www.youtube.com/watch?v=yifwAWrBKxE
More information about the Moodle 2 NanoGong Activity is available here:
    http://nanogong.ust.hk/moodle2.html#activity
!!!The NanoGong Plugin for the HTML Editor within Moodle 2
Any user can create NanoGong audio content in any part of Moodle 2 which uses the TinyMCE Editor. This can be 'mixed' with text and anything else you can create in the TinyMCE editor, if desired. This means that you can record voice messages in anything which uses the TinyMCE editor. Here is a video which briefly illustrates three examples of using NanoGong in the HTML editor. Three examples are shown: in an assignment, in the news forum, and in a label.
    http://www.youtube.com/watch?v=uKw1bcHGKvQ
More information about the Moodle 2 NanoGong Plugin is available here:
    http://nanogong.ust.hk/moodle2.html#htmleditor
NanoGong activities can be backed up/restored using the Moodle 2 backup/restore feature.

Hope you find it useful.
Thanks,
Prof. David Rossiter and Dr. Gibson Lam,
wih great assistance from Ning Xie and Oz Lam,
The Gong Project
http://nanogong.ust.hk
* Attendance
* Online Assignment
* Quiz -- essay answers
* Quickmail
* Progress Bar
* Gradebook
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol">
 <rect id="rect3644" stroke-linejoin="round" style="stroke-dasharray:none;" height="3.8621" width="9.0721" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" y="60.465" x="20.233" stroke-width="2" fill="none"/>
 <rect id="rect3646" stroke-linejoin="round" style="stroke-dasharray:none;" height="3.8621" width="9.0721" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" y="61.407" x="26.134" stroke-width="2" fill="none"/>
 <path id="path4348" stroke-linejoin="miter" style="stroke-dasharray:none;" d="m20.733,53.2,2.6732-2.9894,0,1.7789,10.673,0.000001,0,2.5977-10.673,0,0,1.6024-2.6732-2.9894z" stroke="#4d4d4d" stroke-linecap="butt" stroke-miterlimit="4" stroke-width="1.48043621" fill="none"/>
</g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
Using [[ForumNG|http://legacy.earlham.edu/~markp/moodledocs/#ForumNG]]
Benefits:
[[Discussion Forums and their uses|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bDiscussion%20Forums%20and%20their%20uses%5d%5d]]
[[Q & A Forum|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bQ%20%26%20A%20Forum%5d%5d]]
[[Forum capabilities|http://legacy.earlham.edu/~markp/moodledocs/#%5b%5bForum%20capabilities%5d%5d]]
[[Using Forums with groups]]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke="#4d4d4d" stroke-miterlimit="4" fill="none">
  <path id="path3640" stroke-linejoin="round" style="stroke-dasharray:none;" d="m33.165,50.126-10.258,9.3293-2.0113,4.3956,4.2474-2.1224,9.8299-9.5985-1.8075-2.004z" stroke-linecap="butt" stroke-width="1.60000002"/>
  <path id="path3642" stroke-linejoin="miter" style="stroke-dasharray:none;" d="m13.981,27.04,12.705,0" transform="matrix(0.8, 0, 0, 0.8, 13, 43)" stroke-linecap="round" stroke-width="2"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
/***
|''Name''|LoadMissingExternalTiddler|
|''Version''|0.1.0|
|''Author''|Jon Robson|
***/
//{{{
var _loadMissing = Story.prototype.loadMissingTiddler;
Story.prototype.loadMissingTiddler = function(title,fields,callback) {
	var matches = title.match(/([^\*]*) \*\(@([^\)]*)\)\*/);
	if(matches && matches.length > 0) {
		var sTitle = matches[1];
		var space = matches[2];		config.extensions.tiddlyspace.displayServerTiddler(story.getTiddler(title),
			sTitle, "bags/%0_public".format(space));
	} else {
	_loadMissing.apply(this, arguments)
	}
};
//}}}
/***
https://raw.github.com/tiddlyweb/chrjs/master/main.js
***/
//{{{
// TiddlyWeb adaptor
// v0.14.3

/*jslint vars: true, unparam: true, nomen: true, white: true */
/*global jQuery */

var tiddlyweb = (function($) {

"use strict";

var tw = {
	routes: {
		// host is the TiddlyWeb instance's URI (including server_prefix)
		// placeholders "_type" & "name" refer to the respective bag/recipe
		root     : "{host}/",
		bags     : "{host}/bags",
		bag      : "{host}/bags/{name}",
		recipes  : "{host}/recipes",
		recipe   : "{host}/recipes/{name}",
		tiddlers : "{host}/{_type}s/{name}/tiddlers",
		tiddler  : "{host}/{_type}s/{name}/tiddlers/{title}",
		revisions: "{host}/{_type}s/{name}/tiddlers/{title}/revisions",
		revision : "{host}/{_type}s/{name}/tiddlers/{title}/revisions/{revision}",
		search   : "{host}/search?q={query}"
	}
};

var convertTimestamp, supplant;

// host (optional) is the URI of the originating TiddlyWeb instance
tw.Resource = function(type, host) {
	if(arguments.length) { // initialization
		this._type = type;
		if(host !== false) {
			this.host = host !== undefined ? host.replace(/\/$/, "") : null;
		}
	}
};
$.extend(tw.Resource.prototype, {
	// retrieves resource from server
	// callback is passed resource, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	// filters is an optional filter string (e.g. "select=tag:foo;limit=5")
	get: function(callback, errback, filters) {
		var uri = this.route();
		if(filters) {
			var separator = uri.indexOf("?") === -1 ? "?" : ";";
			uri += separator + filters;
		}
		var self = this;
		return $.ajax({
			url: uri,
			type: "GET",
			dataType: "json",
			success: function(data, status, xhr) {
				var resource = self.parse(data);
				resource.etag = xhr.getResponseHeader("Etag");
				callback(resource, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		});
	},
	// sends resource to server
	// callback is passed data, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	put: function(callback, errback) {
		var self = this;
		var options = {
			url: this.route(),
			type: "PUT",
			contentType: "application/json",
			data: JSON.stringify(this.baseData()),
			success: function(data, status, xhr) {
				callback(self, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		};
		if(this.ajaxSetup) {
			this.ajaxSetup(options);
		}
		return $.ajax(options);
	},
	// deletes resource on server
	// callback is passed data, status, XHR (cf. jQuery.ajax success)
	// errback is passed XHR, error, exception, resource (cf. jQuery.ajax error)
	"delete": function(callback, errback) {
		var self = this;
		var options = {
			url: this.route(),
			type: "DELETE",
			success: function(data, status, xhr) {
				callback(self, status, xhr);
			},
			error: function(xhr, error, exc) {
				errback(xhr, error, exc, self);
			}
		};
		if(this.ajaxSetup) {
			this.ajaxSetup(options);
		}
		return $.ajax(options);
	},
	// returns an object carrying only the essential information of the resource
	baseData: function() {
		var data = {},
			self = this;
		$.each(this.data, function(i, item) {
			var value = self[item];
			if(value !== undefined) {
				data[item] = value;
			}
		});
		return data;
	},
	// returns corresponding instance from a raw object (if applicable)
	parse: function(data) {
		return data;
	},
	// list of accepted keys in serialization
	data: [],
	// returns resource's URI
	route: function() {
		return supplant(tw.routes[this._type], this);
	}
});

var Container = function(type, name, host) {
	if(arguments.length) { // initialization
		tw.Resource.apply(this, [type, host]);
		this.name = name;
		this.desc = "";
		this.policy = new tw.Policy({});
	}
};
Container.prototype = new tw.Resource();
$.extend(Container.prototype, {
	tiddlers: function() {
		return new tw.TiddlerCollection(this);
	},
	parse: function(data) {
		var type = tw._capitalize(this._type),
			container = new tw[type](this.name, this.host);
		data.policy = new tw.Policy(data.policy);
		return $.extend(container, data);
	},
	data: ["desc", "policy"]
});

// attribs is an object whose members are merged into the instance (e.g. query)
tw.Collection = function(type, host, attribs) {
	if(arguments.length) { // initialization
		tw.Resource.apply(this, [type, host]);
		$.extend(this, attribs);
	}
};
tw.Collection.prototype = new tw.Resource();

tw.TiddlerCollection = function(container, tiddler) {
	if(arguments.length) { // initialization
		tw.Collection.apply(this, [tiddler ? "revisions" : "tiddlers"]);
		this.container = container || null;
		this.tiddler = tiddler || null;
	}
};
tw.TiddlerCollection.prototype = new tw.Collection();
$.extend(tw.TiddlerCollection.prototype, {
	parse: function(data) {
		var container = this.container;
		return $.map(data, function(item, i) {
			var tiddler = new tw.Tiddler(item.title, container),
				bag = item.bag;
			tiddler = tw.Tiddler.prototype.parse.apply(tiddler, [item]);
			if(!tiddler.bag && bag) { // XXX: bag always present!?
				tiddler.bag = new tw.Bag(bag, container.host);
			}
			if(!tiddler.recipe && item.recipe) {
				tiddler.recipe = new tw.Recipe(item.recipe, container.host);
			}
			delete item.recipe;
			return $.extend(tiddler, item);
		});
	},
	route: function() {
		var params = this.container;
		if(this.tiddler) {
			var container = this.tiddler.bag || this.tiddler.recipe;
			params = {
				_type: container._type,
				host: container.host,
				name: container.name,
				title: this.tiddler.title
			};
		}
		return supplant(tw.routes[this._type], params);
	}
});

tw.Search = function(query, host) {
	tw.Collection.apply(this, ["search", host]);
	this.query = query;
};
tw.Search.prototype = new tw.Collection();
$.extend(tw.Search.prototype, {
	parse: function(data) {
		this.container = { // XXX: hacky
			_type: "bag",
			host: this.host
		};
		var tiddlers = tw.TiddlerCollection.prototype.parse.apply(this, arguments);
		delete this.container;
		return tiddlers;
	}
});

// title is the name of the tiddler
// container (optional) is an instance of either Bag or Recipe
// optionally accepts a single object representing tiddler attributes
tw.Tiddler = function(title, container) {
	tw.Resource.apply(this, ["tiddler", false]);
	this.title = title;
	this.bag = container && container._type === "bag" ? container : null;
	this.recipe = container && container._type === "recipe" ? container : null;
	var self = this;
	$.each(this.data, function(i, item) {
		self[item] = undefined; // exposes list of standard attributes for inspectability
	});
	if(title && title.title) { // title is an object of tiddler attributes
		$.extend(this, title);
	}
};
tw.Tiddler.prototype = new tw.Resource();
$.extend(tw.Tiddler.prototype, {
	revisions: function() {
		return new tw.TiddlerCollection(this.bag || this.recipe, this);
	},
	route: function() {
		var container = this.bag || this.recipe;
		var params = $.extend({}, this, {
			host: container ? container.host : null,
			_type: this.bag ? "bag" : (this.recipe ? "recipe" : null),
			name: container ? container.name : null
		});
		return supplant(tw.routes[this._type], params);
	},
	parse: function(data) {
		var tiddler = new tw.Tiddler(this.title),
			container = this.bag || this.recipe;
		if(data.bag) {
			tiddler.bag = new tw.Bag(data.bag, container.host);
			delete data.bag;
		}
		delete data.recipe;
		tiddler.created = data.created ? convertTimestamp(data.created) : new Date();
		delete data.created;
		tiddler.modified = data.modified ? convertTimestamp(data.modified) : new Date();
		delete data.modified;
		if(this.recipe) {
			tiddler.recipe = this.recipe;
		}
		return $.extend(tiddler, data);
	},
	data: ["created", "creator", "modifier", "modified", "tags", "type", "text",
			"fields"],
	ajaxSetup: function(options) {
		var self = this;
		if(this.etag && (options.type === "PUT" || options.type === "DELETE")) {
			options.beforeSend = function(xhr) {
				xhr.setRequestHeader("If-Match", self.etag);
			};
		}
		if(options.type === "PUT") {
			var callback = options.success;
			options.success = function(data, status, xhr) {
				var loc = xhr.getResponseHeader("Location"),
					etag = xhr.getResponseHeader("Etag");
				if(loc && etag) {
					self.etag = etag;
					if(!self.bag) {
						var bag = loc.split("/bags/").pop().split("/")[0];
						self.bag = new tw.Bag(bag, self.recipe.host);
					}
					callback(self, status, xhr);
				} else { // IE
					self.get(callback, options.error);
				}
			};
		}
	}
});

tw.Revision = function(id, tiddler) {
	var container = tiddler.bag || tiddler.recipe;
	tw.Tiddler.apply(this, [tiddler.title, container]);
	this._type = "revision";
	this.revision = id;
};
tw.Revision.prototype = new tw.Tiddler();
$.extend(tw.Revision.prototype, {
	revisions: false,
	data: false,
	put: false,
	"delete": false
});

tw.Bag = function(name, host) {
	Container.apply(this, ["bag", name, host]);
};
tw.Bag.prototype = new Container();

tw.Recipe = function(name, host) {
	Container.apply(this, ["recipe", name, host]);
	this.recipe = [];
};
tw.Recipe.prototype = new Container();
$.extend(tw.Recipe.prototype, {
	data: ["recipe"].concat(Container.prototype.data)
});

tw.Policy = function(constraints) { // TODO: validation?
	var self = this;
	$.each(this.constraints, function(i, item) {
		self[item] = constraints[item];
	});
};
tw.Policy.prototype.constraints = ["read", "write", "create", "delete",
	"manage", "accept", "owner"];

/*
 * utilities
 */

tw._capitalize = function(str) {
	return str.charAt(0).toUpperCase() + str.slice(1);
};

// convert YYYYMMDDhhmmss timestamp to Date instance
convertTimestamp = function(t) {
	if (t.match(/^\d{12,17}$/)) {
		return new Date(Date.UTC(
			parseInt(t.substr(0, 4), 10),
			parseInt(t.substr(4, 2), 10) - 1,
			parseInt(t.substr(6, 2), 10),
			parseInt(t.substr(8, 2), 10),
			parseInt(t.substr(10, 2), 10),
			parseInt(t.substr(12, 2) || "0", 10),
			parseInt(t.substr(14, 3) || "0", 10)
		));
	} else {
		return new Date(Date.parse(t));
	}
};

// adapted from Crockford (http://javascript.crockford.com/remedial.html)
supplant = function(str, obj) {
	return str.replace(/{([^{}]*)}/g, function (a, b) {
		var r = obj[b];
		r = typeof r === "string" || typeof r === "number" ? r : a;
		return $.inArray(b, ["host", "query"]) !== -1 ? r : encodeURIComponent(r); // XXX: special-casing
	});
};

return tw;

}(jQuery));
//}}}
[[Latest report|http://moodle.org/mod/forum/discuss.php?d=211175]] of IE v9 issues with certain themes.
Note Mary Evan's helpful screenshots to make sure IE 9 set up the correct way (IE9 Browser Mode and IE9 Document Standards).
/*{{{*/
Background: #e3eaf2
Foreground: #0c141b
PrimaryPale: #ffffff
PrimaryLight: #adc3d9
PrimaryMid: #5b87b3
PrimaryDark: #0a0f15
SecondaryPale: #ffffff
SecondaryLight: #bed9ad
SecondaryMid: #7eb35b
SecondaryDark: #0e150a
TertiaryPale: #ffffff
TertiaryLight: #d9adc7
TertiaryMid: #b35b90
TertiaryDark: #150a11
Error: #f88
ColorPaletteParameters: HSL([210|66], [0.36509835156374804],[0.06232365550379004|1])
/*}}}*/
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AP8zZgAAAGYA//8zAADMMwD/mTMAAGYzAP8zMwAAADMAzP8AAADMAADMmQAAAGYAAMwzAAAAAADuzAAA3QAAALvMAACqAAAAiMwAAHcAAABVmQAARAAAACKZAAARAADuAJkA3QAAALsAmQCqAAAAiACZAHcAAABVAJkARAAAACIAZgARAADuAABm3QAAALsAAGaqAAAAiAAAZncAAABVAABmRAAAACIAAGYRAAAA7u7uM93d3QC7u7szqqqqAIiIiDN3d3cAVVVVM0RERAAiIiIzERERAAAAADMBAQEBAQEBAQEBpXl5eXl5eXl5eXmlAQEBAQEBAQEBAQEBAQEBAQEBgHl5eXl5eXl5eXl5eXl5gAEBAQEBAQEBAQEBAQEB/Xp5eXlVT04qKioqTk9VeXl5ev0BAQEBAQEBAQEBAaV5eXlPKioqKioqKioqKioqT3l5eaUBAQEBAQEBAQGAeXlVTioqKioqKioqKioqKioqTlV5eYABAQEBAQEBgHl5VSoqKioqKioqKioqKioqKioqKlV5eYABAQEBAaV5eVUqKioqKioqKioqKioqKioqKioqKlV5eaUBAQEBeXlVKioqKioqKioqKioqKioqKioqKioqKlV5eQEBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBeXlPKioqKioqKjEyMjIyMjIyMjEqKioqKioqT3l5AXp5eSoqKioqKioxMjIxBwcHBzEyMjEqKioqKioqeXl6eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl5eU8qKioqKioyMgcHBwcHBwcHBwcyMioqKioqKk95eXl5TioqKioqMTIxBwcHBwcHBwcHBzEyMSoqKioqTnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eSoqKioqKjEyBwcHBwcHBwcHBwcHMjEqKioqKip5eXl5KioqKioqMTIHBwcHBwcHBwcHBwcyMSoqKioqKnl5eXkqKioqKioxMgcHBwcHBwcHBwcHBzIxKioqKioqeXl5eU4qKioqKjEyMQcHBwcHBwcHBwcxMjEqKioqKk55eXl5TyoqKioqKjIyBwcHBwcHBwcHBzIyKioqKioqT3l5eXlVKioqKioqMTIxBwcHBwcHBwcxMjEqKioqKipVeXl6eXkqKioqKioqMTIyMQcHBwcxMjIxKioqKioqKnl5egF5eU8qKioqKioqMTIyMjIyMjIyMSoqKioqKipPeXkBAXl5eU4qKioqKioqKjExMTExMSoqKioqKioqTnl5eQEBAXl5VSoqKioqKioqKioqKioqKioqKioqKipVeXkBAQEB+nl5VSoqKioqKioqKioqKioqKioqKioqVXl5+gEBAQEBenl5VSoqKioqKioqKioqKioqKioqKlV5eXoBAQEBAQEBeXl5VU4qKioqKioqKioqKioqKk5VeXl5AQEBAQEBAQEBenl5eU8qKioqKioqKioqKipPeXl5egEBAQEBAQEBAQEB+nl5eXlVT04qKioqTk9VeXl5efoBAQEBAQEBAQEBAQEBAXl5eXl5eXl5eXl5eXl5eXkBAQEBAQEBAQEBAQEBAQEBAQF6eXl5eXl5eXl5eXoBAQEBAQEBAQEB/+AH//+AAf/+AAB//AAAP/gAAB/wAAAP4AAAB8AAAAPAAAADgAAAAYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAYAAAAHAAAADwAAAA+AAAAfwAAAP+AAAH/wAAD/+AAB//4AB///gB/8oAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAACAAAAAwAAAAMAAAADAAAABG1bSA61m3JXuqB4mbuhd8m9o3jqvaF4+b2hePm9o3jqu6F3ybqgeJm1m3JXbVtIDgAAAAQAAAADAAAAAwAAAAMAAAACAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAUAAAAGAAAACI98Wye0nXWavKF4876kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev+8oXjztJ11mo98WycAAAAIAAAABgAAAAUAAAADAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAQAAAAHAAAAChwcHBKulnGJvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+K6WcYkcHBwSAAAACgAAAAcAAAAEAAAAAgAAAAEAAAAAAAAAAAAAAAEAAAADAAAABwAAAAtuYkUst552z76kev++pHr+1LuS//Latf/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/8tq1/9S7kv++pHr+vqR6/7eeds9uYkUsAAAACwAAAAcAAAADAAAAAQAAAAAAAAABAAAAAgAAAAQAAAAIi3hbNbqgd+a+pHr/xayD/+3Vr//85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr//FrIP/vqR6/7qgd+aJdVg0AAAACAAAAAQAAAACAAAAAQAAAAEAAAACAAAABIl8WSW8oXjlvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7yheOWJfFklAAAABAAAAAIAAAABAAAAAAAAAAFfXz8Iu6F4zL6kev/Msor/+uK+//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//rivv/Msor/vqR6/7uheMxfXz8IAAAAAQAAAAAAAAAAAAAAAbqid4K+pHr/xayD//ngvP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//fgvP/FrIP/vqR6/7qid4IAAAABAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAALuheJa+pHr/1LuS//zlwP/85cD//OXA//zlwP/85cD//OXA//riwP/Pq8f/r4HM/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HN/6+BzP/Pq8f/+uLA//zlwP/85cD//OXA//zlwP/85cD//OXA/9S5kv++pHr/u6F4lgAAAACii3MLvKF4876kev/y2rX//OXA//zlwP/85cD//OXA//zlwP/64sD/w5vJ/6+Bzf+vg83/w5vc/9W06v/dwPD/3cDw/9W06v/Dm9z/r4PN/6+Bzf/Dm8n/+uLA//zlwP/85cD//OXA//zlwP/85cD/8tq1/76kev+8oXjzootzC72feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVvaF4mL6kev/fxZ7//OXA//zlwP/85cD//OXA//zlwP/v08L/r4HM/6+Dzf/Wtev/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/r4PN/6+BzP/v08L//OXA//zlwP/85cD//OXA//zlwP/fxZ7/vqR6/72heJi8oXfIvqR6/+zUrv/85cD//OXA//zlwP/85cD//OXA/9Crx/+vgc3/w5vc/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Dm9z/r4HN/9Crx//85cD//OXA//zlwP/85cD//OXA/+zUrv++pHr/vKF3yL2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvaF4+b6kev/64r7//OXA//zlwP/85cD//OXA//zlwP+zhsz/r4HN/93A8P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/3cDw/6+Bzf+zhsz//OXA//zlwP/85cD//OXA//zlwP/64r7/vqR6/72hePm9oXj5vqR6//rivv/85cD//OXA//zlwP/85cD//OXA/7OGzP+vgc3/3cDw/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//dwPD/r4HN/7OGzP/85cD//OXA//zlwP/85cD//OXA//rivv++pHr/vaF4+b2jeOq+pHr/9t25//zlwP/85cD//OXA//zlwP/85cD/u5HK/6+Bzf/VtOr/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9W06v+vgc3/u5HK//zlwP/85cD//OXA//zlwP/85cD/9t25/76kev+9o3jqvKF3yL6kev/s1K7//OXA//zlwP/85cD//OXA//zlwP/Qq8f/r4HN/8Ob3P/hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/w5vc/6+Bzf/Qq8f//OXA//zlwP/85cD//OXA//zlwP/s1K7/vqR6/7yhd8i9oXiYvqR6/9/Fnv/85cD//OXA//zlwP/85cD//OXA/+/Twv+vgcz/r4PN/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//hw/P/4cPz/9a16/+vg83/r4HM/+/Twv/85cD//OXA//zlwP/85cD//OXA/9/Fnv++pHr/vaF4mL2feFW+pHr/y7GJ//zlwP/85cD//OXA//zlwP/85cD//OXA/8+rx/+vgc3/tIfQ/9a16//hw/P/4cPz/+HD8//hw/P/4cPz/+HD8//Wtev/tIfQ/6+Bzf/Pq8f//OXA//zlwP/85cD//OXA//zlwP/85cD/y7GJ/76kev+9n3hVootzC7yhePO+pHr/8tq1//zlwP/85cD//OXA//zlwP/85cD/+uLA/8Obyf+vgc3/r4PN/8Ob3P/VtOr/3cDw/93A8P/VtOr/w5vc/6+Dzf+vgc3/w5vJ//riwP/85cD//OXA//zlwP/85cD//OXA//Latf++pHr/vKF486KLcwsAAAAAu6N3l76kev/Uu5L//OXA//zlwP/85cD//OXA//zlwP/85cD/+uLA/8+rx/+vgcz/r4HN/6+Bzf+vgc3/r4HN/6+Bzf+vgc3/r4HM/8+rx//64sD//OXA//zlwP/85cD//OXA//zlwP/85cD/1LmS/76kev+7oXiWAAAAAAAAAAC3l28gvaN5+L6kev7t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+/Twv/Qq8f/u5HK/7OGzP+zhsz/u5HK/9Crx//v08L//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA/+3Vr/++pHr+vaN5+LeXbyAAAAAAAAAAAAAAAAC6oneCvqR6/8Wsg//54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/34Lz/xayD/76kev+6oneCAAAAAAAAAAAAAAAAAAAAAH9/VQa8oHjLvqR6/8yyiv/64r7//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD/+uK+/8yyiv++pHr/vKB4y39/VQYAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh67o3nkvqR6/8yyiv/54Lz//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//ngvP/Msor/vqR6/7ujeeSyoW4eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqbdim7o3nkvqR6/8Wsg//t1a///OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/t1a//xayD/76kev+7o3nkupt2KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALKhbh68oHjLvqR6/76kev7Uu5L/8tq1//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/85cD//OXA//zlwP/y2rX/1LmS/76kev6+pHr/vKB4y7Khbh4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH9/VQa6oneCvaN5+L6kev++pHr/y7GJ/9/Fnv/s1K7/9t25//rivv/64r7/9t25/+zUrv/fxZ7/y7GJ/76kev++pHr/vaN5+Lqid4J/f1UGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3l28gu6F4lryhePO+pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vqR6/76kev++pHr/vKF487uheJa3l28gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAootzC72feFW9oXiYvKF3yL2jeOq9oXj5vaF4+b2jeOq8oXfIvaF4mL2feFWii3MLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gB///gAH//gAAf/wAAD/4AAAf8AAAD+AAAAfAAAADwAAAA4AAAAGAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAGAAAABwAAAA8AAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/+AAf//4Af/
!Admin Assistant Moodle Training
!!Resources
* Earlham Moodle documentation : http://epress.earlham.edu/tsardocs/
* Moodle HQ docs : http://docs.moodle.org/25/en/Main_page
!!Assignments to execute
# Read [[What's new in Moodle TWO|http://epress.earlham.edu/tsardocs/2013/08/01/whats-new-in-moodle-two-update/]]
# Find your sandbox course on the Moodle site and open it. Write down some different ways to find a course in the Moodle system.
# Change the number of sections in the course. Change the course format to Collapsed Topics. What are other useful things that you may want to change?
# Change the Section heading to something other than the default.
# Enroll a colleague in your training class as a student in your course. Find the specific document that shows you how to do this.
# Upload a pdf resource. Change how it opens up.
# What's the easiest way to show an image on the Course outline? Try it out.
# Make a resource from a Repository and then duplicate it.
/***
|''Name''|BinaryUploadPlugin|
|''Version''|0.3.16|
|''Author''|Ben Gillies and Jon Robson|
|''Type''|plugin|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/BinaryUploadPlugin.js|
|''Description''|Upload a binary file to TiddlyWeb|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig TiddlyWebConfig|
!Usage
{{{
<<binaryUpload bag:<name> edit:tags edit:title tags:<default tags> title:<title> >>
}}}
* {{{bag:<name>}}}: optional; if left out, the file will be saved to the current workspace
* {{{edit:tags}}}: specifies that you want to tag the file being uploaded
* {{{edit:title}}}: specifies that you want to set the title to something other than the filename
* {{{tags:<default tags>}}}: specifies a default set of tags to apply to the file (requires {{{edit:tags}}} to be set)
* {{{title:<title>}}}: predefines the title of the binary tiddler
!Requires
TiddlyWeb
tiddlywebplugins.form
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;

var macro = config.macros.binaryUpload = {
	locale: {
		titleDefaultValue: "Please enter a title...",
		tagsDefaultValue: "Please enter some tags...",
		titlePrefix: "title: ",
		tagsPrefix: "tags: ",
		loadSuccess: 'Tiddler %0 successfully uploaded',
		loadError: "An error occurred when uploading the tiddler %0",
		uploadInProgress: "Please wait while the file is uploaded...",
		membersOnly: "Only members can upload."
	},
	renderInputFields: function(container, options) {
		var locale = macro.locale;
		var editableFields = options.edit;
		var includeFields = {
			tags:  editableFields && editableFields.contains("tags") ? true : false,
			title: editableFields && editableFields.contains("title") ? true : false
		};
		var fields = ["title", "tags"];
		for(var i = 0; i < fields.length; i++) {
			var fieldName = fields[i];
			var userDefault = options[fieldName];
			var defaultValue = userDefault ? userDefault[0] : false;
			if(includeFields[fieldName] || defaultValue) {
				var localeDefault = locale["%0DefaultValue".format(fieldName)];
				var className = defaultValue ? "userInput" : "userInput notEdited";
				var inputEl;
				var val = defaultValue || localeDefault || "";
				var iContainer = $("<div />").addClass("binaryUpload%0".format(fieldName)).
					appendTo(container);
				if(defaultValue && !includeFields[fieldName]) {
					var label = locale["%0Prefix".format(fieldName)];
					$("<span />").text(label).appendTo(iContainer);
					$("<span />").addClass("disabledInput").text(val).appendTo(iContainer);
					inputEl = $("<input />").attr("type", "hidden");
				} else {
					inputEl = $("<input />").attr("type", "text");
				}
				inputEl.attr("name", fieldName).
					addClass("%0Edit".format(fieldName)).
					val(val).addClass(className).appendTo(iContainer);
			}
		}
	},
	getTiddlerName: function(fileName) {
		var fStart = fileName.lastIndexOf("\\");
		var fStart2 = fileName.lastIndexOf("/");
		fStart = fStart < fStart2 ? fStart2 : fStart;
		fileName = fileName.substr(fStart+1);
		return fileName;
	},
	errorHandler: function(fileName) {
		displayMessage("upload of file %0 failed".format(fileName));
	},
	uploadFile: function(place, baseURL, workspace, options) {
		var pleaseWait = $(".uploadProgress", place);
		var iframeName = options.target;
		var form = $("form", place);
		var existingVal = $("input[name=title]", form).val();
		var fileName = existingVal || $('input:file', form).val();
		if(!fileName) {
			return false; // the user hasn't selected a file yet
		}
		fileName = macro.getTiddlerName(fileName);
		$("input[name=title]", place).val(fileName);
		// we need to go somewhere afterwards to ensure the onload event triggers
		var redirectTo = "/%0/tiddlers.txt?select=title:%1".
			format(workspace, fileName);
		var token = tiddlyspace ? tiddlyspace.getCSRFToken() : "";
		var action = "%0?csrf_token=%1&redirect=%2"
			.format(baseURL, token, redirectTo);
		form[0].action = action; // dont use jquery to work with ie
		form[0].target = iframeName;
		// do not refactor following line... won't work in IE6 otherwise
		$(place).append($('<iframe name="' + iframeName + '" id="' + iframeName + '"/>').css('display','none'));
		macro.iFrameLoader(iframeName, function() {
			var content = document.getElementById(iframeName).contentWindow.document.documentElement;
			if($(content).text().indexOf(fileName) > -1) {
				options.callback(place, fileName, workspace, baseURL);
			} else {
				macro.errorHandler(fileName);
			}
			form.show(1000);
			pleaseWait.hide(1000);
		});
		form.hide(1000);
		pleaseWait.show(1000);
		return true;
	},
	createUploadForm: function(place, options) {
		var locale = macro.locale;
		if(readOnly) {
			$('<div class="annotation" />').text(locale.membersOnly).
				appendTo(place);
			return;
		}
		var bag = options.bag;
		options.callback = options.callback ? options.callback :
			function(place, fileName, workspace, baseurl) {
				macro.displayFile(place, fileName, workspace);
				displayMessage(locale.loadSuccess.format(fileName));
				$("input[type=text]", place).val("");
			};
		var defaults = config.defaultCustomFields;
		place = $("<div />").addClass("container").appendTo(place)[0];
		var workspace = bag ? "bags/%0".format(bag) : config.defaultCustomFields["server.workspace"];
		var baseURL = defaults["server.host"];
		baseURL += (baseURL[baseURL.length - 1] !== "/") ? "/" : "";
		baseURL = "%0%1/tiddlers".format(baseURL, workspace);
		//create the upload form, complete with invisible iframe
		var iframeName = "binaryUploadiframe%0".format(Math.random());
		// do not refactor following line of code to work in IE6.
		var form = $('<form action="%0" method="POST" enctype="multipart/form-data" />'.
					format(baseURL)).addClass("binaryUploadForm").
			appendTo(place)[0];
		macro.renderInputFields(form, options);
		$(form).
			append('<div class="binaryUploadFile"><input type="file" name="file" /></div>').
			append('<div class="binaryUploadSubmit"><input type="submit" value="Upload" disabled /></div>').
			submit(function(ev) {
				this.target = iframeName;
				options.target = iframeName;
				macro.uploadFile(place, baseURL, workspace, options);
			})
			.find('[type="file"]').bind('change', function() {
				$(form).find('[type="submit"]').prop('disabled', false);
			}).end();
		$('<div />').addClass("uploadProgress").text(locale.uploadInProgress).hide().appendTo(place);
		$("input[name=file]", place).change(function(ev) {
			var target = $(ev.target);
			var fileName = target.val();
			var title = $("input[type=text][name=title]", place);
			if(!title.val()) {
				title.val(fileName);
			}
		});
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		params = paramString.parseParams(null, null, true);
		macro.createUploadForm(place, params[0]);
	},
	iFrameLoader: function(iframeName, callback) {
		var iframe = document.getElementById(iframeName); //jQuery doesn't seem to want to do this!?
		var locale = macro.locale;
		$(".userInput").addClass("notEdited"); // reset editing
		var finishedLoading = function() {
			callback();
		};
		var iFrameLoadHandler = function() {
			finishedLoading.apply();
			return;
		};

		iframe.onload = iFrameLoadHandler;
		//IE
		completeReadyStateChanges = 0;
		iframe.onreadystatechange = function() {
			if (++(completeReadyStateChanges) == 3) {
				iFrameLoadHandler();
			}
		};
	},
	displayFile: function(place, title, workspace) {
		var adaptor = store.getTiddlers()[0].getAdaptor();
		var context = {
			workspace: workspace,
			host: config.defaultCustomFields['server.host']
		};
		adaptor.getTiddler(title, context, null, function(context) {
			if(context.status) {
				store.addTiddler(context.tiddler);
				story.displayTiddler(place, title);
				var image = config.macros.image;
				if(image && image.refreshImage) {
					image.refreshImage("/%0/tiddlers/%1".format(workspace, title));
					image.refreshImage(title);
					image.refreshImage("/%0".format(title));
					image.refreshImage("%0/%1/tiddlers/%2".format(config.extensions.tiddlyweb.host, workspace, title));
				}
			} else {
				displayMessage(macro.locale.loadError.format(title));
			}
		});
	}
};

if(tiddlyspace) {
	config.macros.binaryUploadPublic = {
		handler: function(place, macroName, params, wikifier, paramString, tiddler) {
			var options = paramString.parseParams(null, null, true)[0];
			var bag = tiddlyspace.getCurrentBag("public");
			options.bag = bag;
			macro.createUploadForm(place, options);
		}
	};
	config.messages.privacySetting = config.options.chkPrivateMode ?
		"private" : "public";
	config.macros.binaryUpload.defaultWorkspace = tiddlyspace.
		getCurrentWorkspace(config.messages.privacySetting);
}

})(jQuery);
//}}}

|linkTable|k
|width:400px; !by modified date |width:400px; !by date created |
|vertical-align:top;padding-left:20px;<<timeline "modified">>|vertical-align:top;padding-left:20px;<<timeline "created">>|
I thinking of a number of compelling features that we could bundle with Moodle2 which would attract faculty to join a pilot:
# [[Streaming Video]] -- Spring 2013?
# [[In Class Polling]] -- CLAMP are looking at this. Will it be ready in time?
# [[Drag 'n' drop]] file uploads
# Audio recording
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8"/>
	<title>TiddlySpace Apps</title>
	<link rel="stylesheet" href="/bags/common/tiddlers/reset.css" />
	<link rel="stylesheet" href="/bags/common/tiddlers/appspage.css" />
	<!--[if lt IE 7 ]>
	<link rel="stylesheet" href="/bags/common/tiddlers/appspageie6.css" />
	<![endif]-->
</head>
<body>
	
	<div id="wrapper">
		<div id="TSbar"></div>
		<div id="main-content">
			<div id="space-details">
				<a href="/_space"><img class="siteicon"></a>
				<div id="title-subtitle">
					<h1 class="spaceaddress">
						<span class="spaceName"></span><span class="hostName"></span>
					</h1>
					<p class="tagline"><span class="subTitle"></span><a class="managespaces" href="/_space">manage space</a></p>
				</div>
			</div>
			<div id="holder">
				<div id="appswitcher-wrapper">
					<div id="appswitcher">
						<h2>Your Apps</h2>
						<ul id="app-list">
							<li class="htmlserialisation">
								<a href="/tiddlers.html?select=tag:!excludeLists;sort=-modified">
									<img src="/bags/common/tiddlers/browse_read_blue.png" alt="Icon for the HTML Serialisation" class="app-img" />
									BROWSE
								</a>
							</li>
							<li class="tiddlywiki">
								<a href="/tiddlers.wiki">
									<img src="/bags/common/tiddlers/tiddlywiki2_blue.png" alt="Icon for TiddlyWiki" class="app-img" />
									TIDDLYWIKI
								</a>
							</li>
						</ul>
						<div id="addapp">
							<button class="inactive">Add More!</button>
						</div>
					</div>
					<div id="app-desc">
						<ul>
							<li class="htmlserialisationdesc"><p>an easy to understand HTML representation of your content.</p></li>
							<li class="tiddlywikidesc"><p>use TiddlyWiki to create, edit and organise your content.</p></li>
						</ul>
					</div>
					<div style="clear: both;"></div>
				</div>
			</div>
		</div>
		<div id="footer"><!-- ie doesn't support footer tag -->
			<div id="footer-content">
				<div class="links">
					<a href="http://blog.tiddlyspace.com">blog</a>
					<a href="http://featured.tiddlyspace.com">featured</a>
					<a href="http://docs.tiddlyspace.com">documentation</a>
					<a href="https://github.com/TiddlySpace/tiddlyspace">source</a>
				</div>
				<p>TiddlySpace 2011, created by <a href="http://osmosoft.com">Osmosoft</a></p>
			</div>
		</div>
	</div>
	
	<script type="text/javascript" src="/bags/common/tiddlers/backstage.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/jquery.js"></script>
	<script type="text/javascript" src="/bags/tiddlyspace/tiddlers/chrjs"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/chrjs-store.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/jquery-json.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/appspage.js"></script>
</body>
</html>
|''Name:''|[[NeUIemTheme03]]|
|''Description:''|Changes the right sidebar|
|''Generator:''|[[TW FreeStyle|http://FreeStyle.tiddlyspot.com]]|
|''Gen.Description:''|Handcrafted by @pmario|
|''PageTemplate:''|NeUIemTheme##PageTemplate|
|''ViewTemplate:''|NeUIemTheme##ViewTemplate|
|''EditTemplate:''|NeUIemTheme##EditTemplate|
|''RevisionTemplate:''|NeUIemTheme##RevisionTemplate|
|''StyleSheet:''|##StyleSheet|

!StyleSheet
/*{{{*/

[[NeUIemTheme##StyleSheet]]

#sidebarTabs .tabset{
	float: right;
	width: 1em;
	padding: 0;
}

#sidebarTabs .tabset:hover{
	width: auto;
}

#sidebarTabs .tabset .tab{
	overflow: hidden;
	display: block;
}
/*}}}*/
<!--{{{-->
<div class='header'>
	<div id='sidebarSearch'>
		<span macro='search'></span>
	</div>
	<div class='headerForeground'>
		<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
		<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
	</div>
	<div class='clearFloat'></div>
</div>

<div id='menuBar'>
	<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
	<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
</div>
<div id='displayArea'>
	<div id='messageArea'></div>
	<div id='tiddlerDisplay'></div>
	<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<!--}}}-->
Playing YouTube videos into Moodle 2 course is an exercise in frustration.
Compared to the default way it seems to work in WordPress, the moodle way is clumsy. What you would normally want to happen is your YouTube video to pop up in a window the size of the video itself and then play from there. I'm not normally fussed about going to the site and faffing about there.
In WordPress you just paste the 'share' URL into the text body and it automatically instantiates a player. Simple.
Moodle 2 does allegedly have a YouTube filter but it's not clear what this actually does -- certainly YT 'share' URLs are not embedded as in WordPress. And the process of Filter activation is another area that Moodle makes more complicated than needed.
There are two options available 
# Resource : URL can be used to link to the 'share' URL. This is also an exercise in annoyance. If you have the YouTube page open with your video on (which is rather likely) tough beans -- using the URL you still need to click the 'Picker' and spend ages faffing about to point and click on the video even though you already know it's URL. The there are the 'Display' options, none of which operate as one might expect.
** Display : Open -- opens a new page with {{{Click http://youtu.be/rK9yd0gMzpE?hd=1 link to open resource.}}} in tiny writing just below the description. @@what?@@ Why doesn't it open the damm URL like you'd expect?
** Display : popup -- one would expect this to open the page in a popup window that you could adjust the dimensions (Moodle 1.9 does this). Nope. Same as above.
** Display : embed -- one would expect this to embed the Youtube page in the Moodle page -- at least that's what the help says it should do. Nope again. Just blank with the title halfway down the page (I switched that option on just in case).
# Resource : Page. Here I found the best way is to paste the 'embed code' into the page. To do this one has to click the [HTML] button and then paste in the code and [Update]. This works well. Example of embed code:
{{{
<iframe width="853" height="480" 
src="http://www.youtube-nocookie.com/embed/rK9yd0gMzpE?rel=0" frameborder="0" allowfullscreen>
</iframe>
}}}
** using 'Moodle media' button. Here again, if you already know the Youtube URL you can't just paste it in. ARGGG! Having searched for the video that you already have the URL to, the URL gets embedded like so {{{<p><a href="http://www.youtube.com/v/rK9yd0gMzpE">Session1: Introduction</a></p>}}} and does actually display as a player (smallest size). This does seem to work, so good, but not half as useful as the embed code where you can select different sizes of player going up the maximum 1280 x 720!!
*** As an aside, the 'Share URL' : {{{http://youtu.be/rK9yd0gMzpE?hd=1}}} is different to the URL that is generated after searching with Moodle media {{{http://www.youtube.com/v/rK9yd0gMzpE}}} and only the latter is displayed as the video frame with controls. Intriguing.
!!SORTED
I finally figured things out -- by serendipity. I was confused because, unlike Moodle 1.9, [Save and display] will ''not'' pop-up a window when pop-up is the chosen option. You have to [Save and return to course] and then click the link. So I found a Resource : URL that popped up a link to the YouTube site. Not useful because all the other crap was there that gets in the way. On a hunch I used the URL formulation that 'Moodle media' uses, ie {{{http://www.youtube.com/v/<share code>}}} and this worked! Not only that but setting the pop-up size to 853x480 will automatically set the quality to ''480'' and setting the size to a massive 1280x720 will choose ''720p'' quality! @@brilliant -- SCUZZED!!@@
So, 
* Resource : URL
* use {{{http://www.youtube.com/v/<share code>}}} formulation
* Display : in pop-up
* size {{{853 x 480}}}


!!List
|sortable|k
|!#|!Faculty|!Aug 8|!Later|!Notes|h
||Jay Roberts| N| 8-16|I am very interested but will be in the woods during that time. Let me know if another date pops up.|
| 1|Cynthia Fadem| Y| ?|I'm in, but can forgo if others need it more :) Geoscience. @@use v2-pilot@@|
| 2|Becky Jestice| Y| |Management|
| 3|Lynne Perkins Socey| Y| |Fine Arts -- Theatre|
| 4|Rajaram Krishnan| Y| |Economics|
| 5|Marya Bower| Y| |Philosophy|
| |Aletha Stahl| ?| 8-16|However, if this fills up and you add another session later (if you're considering that), that would be my preference.|
| |Lori Watson| N| 8-16|Sounds great!  But I'll be backpacking in the Utah mountains with Jay and crew...  Let me know if you have another one!|
| 6|Monteze Snyder| Y| |Management|
| 7|Mark Stocksdale| Y| |Chemistry|
| 8|Kalani Seu| Y| |Chemistry|
| 9|Julia May| Y| |Fine Art -- doing a talk|
| 10|Susan W. Furukawa| Y| |Japanese Studies|
| 11|Meg Streepey Smith| Y| |Geoscience. @@use v2-pilot@@|
| 12|Corinne Deibel| Y| |"this sounds like it would be very useful for gen chem and analytical and those are functions of Moodle that I don't know anything about."|
| 13|Bill Culverhouse| Y| |I'm interested, and my new assistant Danielle may be interested also if there's room.|
;Other comments:
: Jennie Kiffmeyer : "this sounds wonderful! I hope you and Amy have a great turnout -- and a great time."
!!Thoughts
Make 'em @@work@@
# Amy, --Anne-- & Kate (& Wes if available) to join and help out.
# Administer online quiz/questionnaire assessing knowledge and understanding of Moodle before the workshop
# Structure of workshop
# Learning outcomes stated up front. Eg "You should leave the workshop having gained mastery over at least one new major moodle feature of value to you and with confidence that you can implement this into your own course". Also outgoing questionnaire.
Looks interesting : https://github.com/VERSION2-Inc/VideoAssessment
<<showUpdates>>
Handy block from Bob Puffer which allows the user to manipulate sections of the Course Outline without faffing with Ajax.
There is one repeatable bug which occurs with both Bootstrap and Decaf themes on Moodle 2.4.4. Here's how to replicate.
# In the Quicksets block click [Edit sections]
# check a section and click [Add new course section after selected] (how do you add a section //before// the first one with this method?
# Now hit [reorder / submit section changes]. No indication that anything has happened. Click it again just in case.
# Now [Return to course, discard unsaved changes]
# Message "Error writing to database" [[More information about this error|http://docs.moodle.org/24/en/error/moodle/dmlwriteexception]] -- ''error/moodle/dmlwriteexception'' +++[details]>
More information about this error
{{{
Debug info: Duplicate entry '916-20' for key 'mdl_coursect_cousec_uix'
INSERT INTO mdl_course_sections (course,section,summary,summaryformat,sequence) VALUES(?,?,?,?,?)
[array (
0 => '916',
1 => 20,
2 => '',
3 => '1',
4 => '',
)]
Error code: dmlwriteexception
Stack trace:

    line 429 of /lib/dml/moodle_database.php: dml_write_exception thrown
    line 1107 of /lib/dml/mysqli_native_moodle_database.php: call to moodle_database->query_end()
    line 1149 of /lib/dml/mysqli_native_moodle_database.php: call to mysqli_native_moodle_database->insert_record_raw()
    line 2786 of /course/lib.php: call to mysqli_native_moodle_database->insert_record()
    line 42 of /course/format/weeks/format.php: call to course_create_sections_if_missing()
    line 279 of /course/view.php: call to require()
}}}
=== 
To clear the problem go into Course administration > Edit settings and [Save]
----
See [[11 July 2013]]
{{ts{19/07/13 10:51}}} [[New version downloaded|https://github.com/bobpuffer/moodle-block_quickset]]
!!Tests

1. Change a section name. Click [Reorder/Submit section changes]
Screen looses content:
 [img[http://legacy.earlham.edu/~markp/screens/moodle/quicksets-error2.png]]
Then return to course gives error:
{{{
Coding error detected, it must be fixed by a programmer: $course passed to moodle_page::set_course does not look like a proper course object.
}}}
[[More information about this error|http://docs.moodle.org/24/en/error/debug/codingerror]]
{{{
Debug info:
Error code: codingerror
Stack trace:
    line 851 of /lib/pagelib.php: coding_exception thrown
    line 30 of /blocks/quickset/edit.php: call to moodle_page->set_course()
}}}
Go back to course and section name updated.
2. Same behaviour when section deleted
3. Same behaviour when new section inserted
----
Fri July 19:
 +++[More errors]>
1. Insert new section
2. Save
3. Erros:
{{{
Undefined variable: order in /usr/home/markp/public_html/test2014/blocks/quickset/edit.php on line 240
Notice: Undefined variable: order in /usr/home/markp/public_html/test2014/blocks/quickset/edit.php on line 282
Notice: Undefined variable: order in /usr/home/markp/public_html/test2014/blocks/quickset/edit.php on line 287
Warning: Invalid argument supplied for foreach() in /usr/home/markp/public_html/test2014/blocks/quickset/edit.php on line 287
}}}
I'm getting these errors with Leatherbound theme.
=== 
Bob says:
>I'm going to repush to github.  There has to be something wrong with what's up there because nothing like this is happening on my end.
But still errors - so just remove the block ...
/***
|''Name''|TiddlySpaceInitialization|
|''Version''|0.7.3|
|''Description''|Initializes new TiddlySpaces the first time they are created|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/blob/master/src/plugins/TiddlySpaceInit.js|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig RandomColorPalettePlugin chrjs ImageMacroPlugin|
!TODO
* robust error notification and recovery
!MarkupPreHead
<!--{{{-->
<link href="/bags/%0_public/tiddlers.atom" rel="alternate"
	type="application/atom+xml" title="%0's public feed" />
<link rel="canonical" href="%1/" />
<!--}}}-->
!Code
***/
//{{{
(function($) {

var versionField = "tiddlyspaceinit_version";
var markupPreHead = store.getTiddlerText(tiddler.title + "##MarkupPreHead", "");
var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace;
var tweb = config.extensions.tiddlyweb;

var plugin = config.extensions.TiddlySpaceInit = {
	version: "0.6",
	SiteTitle: "%0",
	SiteSubtitle: "a TiddlySpace",
	flagTitle: "%0SetupFlag",
	flagWarning: "Please do not modify this tiddler; it was created " +
		"automatically upon space creation.",

	dispatch: function(ev) {
		var title = plugin.flagTitle.format([currentSpace.name]);
		config.annotations[title] = plugin.flagWarning;
		if(currentSpace.type != "private") {
			return;
		}
		var tiddlers = [];
		var tid = store.getTiddler(title);
		if(tid) {
			curVersion = parseFloat(tid.fields[versionField]);
			reqVersion = parseFloat(plugin.version);
			if(curVersion < reqVersion) {
				plugin.update(curVersion, tid);
				tid.fields[versionField] = plugin.version;
				tid.incChangeCount();
				tid = store.saveTiddler(tid);
				tiddlers.push(tid);
			}
		} else { // first run
			tid = new Tiddler(title);
			tid.tags = ["excludeLists", "excludeSearch", "excludePublisher"];
			tid.fields = $.extend({}, config.defaultCustomFields);
			tid.fields[versionField] = plugin.version;
			tid.text = "@@%0@@".format([plugin.flagWarning]);
			tid = store.saveTiddler(tid);
			tiddlers = tiddlers.concat(plugin.firstRun(), tid);
		}
		autoSaveChanges(null, tiddlers);
	},
	update: function(curVersion, flagTiddler) {
		if(curVersion < 0.2) {
			this.createAvatar();
		}
		if(curVersion < 0.3) {
			flagTiddler.tags.pushUnique("excludePublisher"); // XXX: never persisted
		}
		if(curVersion < 0.5) { // v0.4 was faulty
			this.setupMarkupPreHead();
		}
		if(curVersion < 0.6) {
			this.purgeSystemSettings();
		}
	},
	pubTid: {
		tags: ["excludeLists", "excludeSearch"],
		fields: $.extend({}, config.defaultCustomFields, {
			"server.workspace": tiddlyspace.getCurrentWorkspace("public")
		})
	},
	makeTiddlerIfNot: function(tiddler) {
		if (!store.tiddlerExists(tiddler.title)) {
			$.extend(true, tiddler, plugin.pubTid);
			return [store.saveTiddler(tiddler)];
		} else {
			return [];
		}
	},
	firstRun: function() {
		var tiddlers = [];
		// generate Site*itle
		$.each(["SiteTitle", "SiteSubtitle"], function(i, item) {
			var tid = new Tiddler(item);
			tid.text = plugin[item].format([currentSpace.name]);
			tiddlers.push.apply(tiddlers,
				plugin.makeTiddlerIfNot(tid));
		});
		// generate public ColorPalette
		var tid = new Tiddler("ColorPalette");
		tid.text = config.macros.RandomColorPalette.generatePalette({
			saturation_pale: 0.67, saturation_light: 0.53,
			saturation_mid: 0.43, saturation_dark: 0.06,
			pale: 0.99, light: 0.85, mid: 0.5, dark: 0.31
		},
			false);
		tiddlers.push.apply(tiddlers, plugin.makeTiddlerIfNot(tid));
		this.createAvatar();
		this.setupMarkupPreHead();
		return tiddlers;
	},
	// remove _cookie slices (TiddlyWiki 2.6.2 beta 6 remnants)
	purgeSystemSettings: function() {
		var ss = store.getTiddler("SystemSettings");
		if(ss) {
			var lines = ss.text.split("\n");
			var persistentOptions = $.grep(lines, function(line, i) {
				return line.indexOf("_cookie:") == -1;
			});
			ss.text = persistentOptions.join("\n");
			ss = store.saveTiddler(ss);
			autoSaveChanges(null, [ss]);
		}
	},
	createAvatar: function() {
		var avatar = "SiteIcon";
		var host = tweb.host;
		var notify = function(xhr, error, exc) {
			displayMessage("ERROR: could not create avatar - " + // TODO: i18n
				"%0: %1".format([xhr.statusText, xhr.responseText]));
			// TODO: resolve!?
		};

		var pubBag = tiddlyspace.getCurrentBag("public");
		var tid = new tiddlyweb.Tiddler(avatar);
		tid.bag = new tiddlyweb.Bag(pubBag, host);

		var callback = function(data, status, xhr) {}; // avatar already exists; do nothing
		var errback = function(xhr, error, exc) {
			if(xhr.status != 404) {
				return;
			}
			// copy default avatar
			var _notify = function(tid, status, xhr) {
				displayMessage("created avatar"); // TODO: i18n
				var image = config.macros.image;
				if(image && image.refreshImage) {
					var uri = "/%0/tiddlers/SiteIcon".
						format(tiddlyspace.getCurrentWorkspace("public"));
					image.refreshImage(uri);
					image.refreshImage("SiteIcon");
				}
			};
			var _callback = function(tid, status, xhr) {
				tid.title = avatar;
				tid.bag.name = pubBag;
				delete tid.etag;
				tid.put(_notify, notify); // TODO: add to current session document (via adaptor?)
			};
			tweb.getUserInfo(function(user) {
				var avatarTitle = currentSpace.name == user.name ?
					"defaultUserIcon" : "defaultSiteIcon";
				var tid = new tiddlyweb.Tiddler(avatarTitle);
				tid.bag = new tiddlyweb.Bag("common", host);
				tid.get(_callback, notify);
			});
		};
		tid.get(callback, errback);
	},
	savePublicTiddlerText: function(title, text, pubWorkspace) {
		var tid = new Tiddler(title);
		tid.text = text;
		tid.tags = ["excludeLists"];
		tid.fields = $.extend({}, config.defaultCustomFields);
		tid.fields["server.workspace"] = pubWorkspace;
		tid.fields["server.page.revision"] = "false";
		tid = store.saveTiddler(tid);
		autoSaveChanges(null, [tid]);
	},
	setupMarkupPreHead: function() {
		var pubWorkspace = tiddlyspace.getCurrentWorkspace("public");
		var existing = store.getTiddler("MarkupPreHead");
		if(!existing || existing.fields["server.workspace"] != pubWorkspace) {
			var context = this;
			tweb.getStatus(function(status) {
				var text = markupPreHead.format(currentSpace.name,
					tiddlyspace.getHost(status.server_host, currentSpace.name));
				context.savePublicTiddlerText("MarkupPreHead", text,
					pubWorkspace);
			});
		}
		// also set up DefaultTiddlers
		var title = "DefaultTiddlers";
		existing = store.getTiddler(title) || new Tiddler(title);
		if(existing.fields["server.workspace"] != pubWorkspace) {
			var text = existing.text || store.getShadowTiddlerText(title);
			this.savePublicTiddlerText(title, text, pubWorkspace);
		}
	}
};

$(document).bind("startup", plugin.dispatch);

})(jQuery);
//}}}
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
![[PeerWise|http://peerwise.cs.auckland.ac.nz/]]
* [[Docs|http://peerwise.cs.auckland.ac.nz/docs/]]
* [[Community|http://www.peerwise-community.org/]]
* [[Informative Slideshow|http://www.slideshare.net/EdPER_talks/wcse-slides-batesgallowaydenny]]
* +++[Local slideshow]
<html>
<iframe src="http://www.slideshare.net/slideshow/embed_code/24041117" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="http://www.slideshare.net/EdPER_talks/wcse-slides-batesgallowaydenny" title="Wcse slides bates_galloway_denny" target="_blank">Wcse slides bates_galloway_denny</a> </strong> from <strong><a href="http://www.slideshare.net/EdPER_talks" target="_blank">University of British Columbia</a></strong> </div>
</html>
=== 
* Youtube video : [[PeerWise - Collaborative student learning|http://youtu.be/j1tN006KEWo]] +++[Embedded]
<html>
<iframe width="640" height="360" src="http://www.youtube.com/embed/j1tN006KEWo?rel=0" frameborder="0" allowfullscreen></iframe>
</html>
=== 
* +++[From Uni Edinburgh:]
[[Students writing assessments?|http://www.rsc.org/Education/EiC/issues/2012July/student-develop-assessment-create.asp]]
<<<
We've been using a freely-available online system called PeerWise,2 developed by the Computer Science department at the University of Auckland in New Zealand. Used extensively across the world, in both secondary and tertiary education, PeerWise is straightforward to use, has a clean interface and design, and embodies much of the social functionality that now forms the backbone of online interaction. Students can follow particular question authors, and be informed when they contribute new material. Updates and messages are delivered to a user at each login, telling them how other users have been interacting with their content. There's an in-built scoring system, and a selection of badges to collect to incentivise and motivate contributors, and to encourage participation and engagement.
<<<
Important to scaffold activities ahead of assessment:
<<<
Simply offering students the system to use without any training - the 'build it and they will come' approach - is not enough. In piloting PeerWise, we've found that there are a few key implementation details that are necessary for high quality student engagement. We found it essential to provide a route into the difficult task of creating questions from scratch. Where do you start? How do you know what you don't know? We devised [[scaffolding activities|http://www2.ph.ed.ac.uk/elearning/projects/peerwise/]] to be done in groups in class ahead of the start of the assessment task. This turned out to be crucial in setting a high standard for students to aspire to.
<<<
And
<<<
!!!Key to success 
To ensure good participation from all of the class, there was an incentive, in the form of a small amount of assessed course credit. This was only a few percent of the total course mark, but it ensured a high take up of the task. 
The single biggest surprise to us when implementing this activity was the high quality of nearly all the questions, with the very best ones being outstandingly good. Colleagues asked us if we were not concerned that students would plagiarise end-of-chapter problems from a textbook? On the whole, no: many of the problems students submitted were far better than end of chapter problems. 
<<<
=== 
!!!Publications
*    Simon P. Bates, Ross K. Galloway and Karon L. McBride [[Student-generated content: using PeerWise to enhance engagement and outcomes in introductory physics courses|http://www2.ph.ed.ac.uk/elearning/projects/peerwise/bates_peerwise.pdf]] (PERC 2011 Proceedings) (pdf)
*    Karon L. McBride, Simon P. Bates, Ross K. Galloway [[Overview of Peerwise Use at Edinburgh|http://www2.ph.ed.ac.uk/elearning/projects/peerwise/Peerwise-at-Edinburgh.pdf]] (pdf)
!!!Resources
* [[Scaffolding resources|http://sites.google.com/site/edpersite/project-updates/scottishe-assessmentawardwinner2011formativeassessment/Scaffolding.zip?attredirects=0&d=1]]
* [[Student Generated Content for Learning (SGC4L)|https://www.wiki.ed.ac.uk/display/SGC4L/Home]]
** [[Developing students' ability to construct feedback|https://www.wiki.ed.ac.uk/download/attachments/136521948/G21c-DavidNicol_student_060611.pdf?version=1]] Professor David Nicol, University of Strathclyde
* [[e-Learning in the School of Physics and Astronomy » Project Showcase » Peerwise |http://www2.ph.ed.ac.uk/elearning/projects/peerwise/]]
* [[Students writing assessments?|http://www.rsc.org/Education/EiC/issues/2012July/student-develop-assessment-create.asp]]

+++[Using PeerWise in humanities course]
Published on Jan 31, 2013
[[An interview with Adrian Renzo|http://youtu.be/gdv2_ez3kuE]] on his use of PeerWise in a course on popular music at the University of Auckland
<html>
<iframe width="960" height="720" src="http://www.youtube.com/embed/gdv2_ez3kuE?rel=0" frameborder="0" allowfullscreen></iframe>
</html>
=== 

emastic a CSS framework: http://code.google.com/p/emastic/
In [[File Repository for Teachers: KnowledgeTree?|http://moodle.org/mod/forum/discuss.php?d=134428&parent=861459]] Geoffrey Rowland comments:
<<<
It's been a while since this posting, but I have just rediscovered [[KnowledgeTree Community Edition|http://knowledgetree.org/Main_Page]] as a potential repository for Moodle 2 and have been rather impressed.

Over recent years, I have tinkered with a few different potential repository systems including DOOR, EPrints, SharePoint, Alfresco, Mindtouch and ownCloud but, for various reasons, none have completely fitted the bill.

The latest community KnowledgeTree looks promising as the source code version installs fairly painlessly on the same LAMP stack as Moodle (though I had to perform a [[couple of tweaks|http://tpokorra.blogspot.com/2011/03/knowledge-tree-and-php-533.html]] to cope with PHP 5.3.x).

ActiveDirectory authentication (shared with our Moodle) also worked well for both users and groups.

Setting up KnowledgeTree as a WebDAV repository also worked 'out of the box' for file import into Moodle 2. As our particular KnowledgeTree instance was on a different server to our production Moodle, I did have to tweak moodle/repository/webdav/lib.php to return the correct path for linked-resources. I'll be happy to expand on this if it helps anyone

One @@significant remaining challenge for KnowledgeTree, and other repositories, is linking roles and permissions to those in Moodle@@. For example, KnowledgeTree resources added, by a teacher, as links in a Moodle course are not visible to students unless the appropriate permissions are set in KnowledgeTree. A @@quick fix is to set things for public access@@, though this may not be appropriate for all situations. Alternatively, some way of synchronising Moodle courses (categories?, cohorts?, groups?) with KnowledgeTree groups would be good.

Of course there is less of an issue with imported resource files, as these inherit the Moodle course permissions. However, this does negate some of the advantages of using a repository. Resource files are duplicated and automatic linking to the latest file version.

In summary ,KnowledgeTree looks very promising as a WeDAV repository/Document Management System for Moodle 2 - with AD/LDAP authentication, groups, versioning and workflows. In many ways, a PHP-based 'Alfresco-lite'.
<<<
/*{{{*/
#menuBar {
	position: relative;
	background-color: [[ColorPalette::PrimaryMid]];
	min-height: 1em;
	overflow: hidden;
	font-size: 1.1em;

/* if you have a light bar border would be fine */
/*
	border-top: 1px solid [[ColorPalette::PrimaryDark]];
	border-bottom: 1px solid [[ColorPalette::PrimaryDark]];
*/
	width: 100%; /* for ie 6 */
}

/* horizontal main menu stuff */
.topMenu, .topMenu a{
	padding-top: 0.2em;
	padding-bottom: 0.2em;
}

.topMenu ul,
.topMenu ol {
	list-style:none;
	padding:0;
	margin: 0;
}

.topMenu li {
	float: left;
}

#mainMenu {
	width:auto;		/*-- new in emastic --*/
	position:relative; 	/*-- new in emastic --*/
	text-align:right; 
	font-size:1.1em;
	padding: 0.5em 0.5em 0;  /* same as box */
}

#mainMenu a {
	padding: 0.2em 0.2em; 
}

#mainMenu a:hover {
	background-color: [[ColorPalette::PrimaryMid]];
	color: [[ColorPalette::Background]]
}

#sidebarOptions {
	color: [[ColorPalette::PrimaryDark]];
}

#sidebarOptions {
	min-height: 1em;
}

#sidebarOptions .button, #sidebarOptions .tiddlyLink, #sidebarOptions a, 
.topMenu .button, .topMenu .tiddlyLink, .topMenu a {
	margin-left: 0.5em;
	margin-right: 0.5em;
	padding-left: 3px;
	padding-right: 3px;
	color: [[ColorPalette::PrimaryPale]];
	border: none;
	display: inline;
}

#sidebarOptions .button:hover, #sidebarOptions .tiddlyLink:hover,
.topMenu .button:hover, .topMenu .tiddlyLink:hover {
	color: [[ColorPalette::PrimaryDark]];
	background: [[ColorPalette::PrimaryPale]];
}

/*}}}*/
Some useful conversations about integrating Alfresco with Moodle:
* [[Alfresco linking|http://moodle.org/mod/forum/discuss.php?d=176140]]
* [[Moodle Alfresco - No Files Available|http://moodle.org/mod/forum/discuss.php?d=169345]]
* [[Alfresco Integration|moodle.org/mod/forum/discuss.php?d=164785]] (also WebDAV)
Also, check out [[Owncloud]]
/***
|''Name:''|TiddlySpaceLinkPlugin|
|''Description:''|Formatter to reference other spaces from wikitext |
|''Author:''|PaulDowney (psd (at) osmosoft (dot) com) |
|''Source:''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceLinkPlugin.js|
|''Version:''|1.4.2|
|''License:''|[[BSD License|http://www.opensource.org/licenses/bsd-license.php]] |
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''~CoreVersion:''|2.4|
!!Documentation
This plugin provides wikitext formatters for referencing another [[space|Space]] on the same TiddlySpace server, as in the following examples:
<<<
  {{{@space}}} -- @space 
  {{{~@space}}} -- ~@space 
  {{{Tiddler@space}}} -- Tiddler@space
  {{{[[Tiddler Title]]@space}}} -- [[Tiddler Title]]@space 
  {{{[[Link text|Tiddler Title]]@space}}} -- [[Link text|Tiddler Title]]@space
<<<
Links to tiddlers with a title begining with an "@" remain as tiddlyLinks:
<<<
  {{{[[@tiddler]]}}} -- [[@tiddler]]
<<<
and these may be changed into a space link using {{{@@}}}:
<<<
  {{{[[@@space]]}}} -- [[@@space]]
  {{{[[Link to an another space|@@space]]}}} -- [[Link to another space|@@space]]
  {{{[[@space|@@space]]}}} -- [[@space|@@space]]
<<<
TiddlySpace includes the [[TiddlySpaceLinkPlugin]] which provides WikiText markup for linking to other spaces on the same server. For example @glossary is a link to the {{{glossary}}} space and [[Small Trusted Group]]@glossary a link to an individual tiddler in the @glossary space. Prefixing the link with a tilde escapes the link, for example {{{~@space}}}.
Email addresses, for example joe.bloggs@example.com and mary@had.a.little.lamb.org should be unaffected.
!!Features
The plugin provides external links decorated so that other plugins may be included to add features such as the ability to dynamically pull externally linked tiddlers into the current TiddlyWiki.
Wikitext linking to a space on another server, for example from a tiddler in a space on tiddlyspace.com to a tiddler or a space on example.com, isn't currently supported. 
!!Code
***/
//{{{
/*jslint onevar: false nomen: false plusplus: false */
/*global jQuery config createTiddlyText createExternalLink createTiddlyLink */

function createSpaceLink(place, spaceName, title, alt, isBag) {
	var link, a, currentSpaceName, label;
	try {
		if (spaceName === config.extensions.tiddlyspace.currentSpace.name) {
			title = title || spaceName;
			a = createTiddlyLink(place, title, false);
			jQuery(a).text(alt || title);
			return a;
		}
	} catch (ex1) {
		currentSpaceName = false;
	}

	a = jQuery("<a />").addClass('tiddlySpaceLink externalLink').appendTo(place)[0];
	if(title) {
		jQuery(a).attr('tiddler', title);
	}
	if(isBag) {
		jQuery(a).attr('bag', spaceName);
	} else {
		jQuery(a).attr('tiddlyspace', spaceName);
	}

	config.extensions.tiddlyweb.getStatus(function(status) {
		link = status.server_host.url;
		if (title) {
			label = alt || title;
			link = link + "/" + encodeURIComponent(title);
		} else {
			label = alt || spaceName;
		}
		// assumes a http URI without user:pass@ prefix
		if(!isBag) {
			link = link.replace("http://", "http://" + spaceName.toLowerCase() + ".");
		} else {
			link += "/bags/" + spaceName + "/tiddlers.wiki";
		}
		jQuery(a).attr("href", link).text(label);
	});
	return a;
}

(function ($) {

	config.textPrimitives.spaceName = "[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9]";
	config.textPrimitives.spaceNameStrict = "[a-z][a-z0-9-]*";
	config.textPrimitives.bareTiddlerLetter = config.textPrimitives.anyLetterStrict;

	config.formatters.splice(0, 0, {
		name: "spacenameLink",
		match: config.textPrimitives.unWikiLink + "?" + config.textPrimitives.bareTiddlerLetter + "*@" + config.textPrimitives.spaceName + "\\.?.?",
		lookaheadRegExp: new RegExp(config.textPrimitives.unWikiLink + "?(" + config.textPrimitives.bareTiddlerLetter + "*)@(" + config.textPrimitives.spaceName + ")", "mg"),
		handler: function (w) {
			if (w.matchText.substr(w.matchText.length - 2, 1) === '.' && w.matchText.substr(w.matchText.length - 1, 1).match(/[a-zA-Z]/)) {
				w.outputText(w.output, w.matchStart, w.nextMatch);
				return;
			}
			if (w.matchText.substr(0, 1) === config.textPrimitives.unWikiLink) {
				w.outputText(w.output, w.matchStart + 1, w.nextMatch);
				return;
			}
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
				createSpaceLink(w.output, lookaheadMatch[2], lookaheadMatch[1]);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	},
	{
		name: "tiddlySpaceLink",
		match: "\\[\\[[^\\|\\]]*\\|*@@" + config.textPrimitives.spaceName + "\\]",
		lookaheadRegExp: new RegExp("\\[\\[(.*?)(?:\\|@@(.*?))?\\]\\]", "mg"),
		handler: function (w) {
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
				var alt = lookaheadMatch[2] ? lookaheadMatch[1] : lookaheadMatch[1].replace(/^@@/, "");
				var space = lookaheadMatch[2] || alt;
				createSpaceLink(w.output, space, "", alt);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	},
	{
		name: "tiddlyLinkSpacenameLink",
		match: "\\[\\[[^\\[]*\\]\\]@",
		lookaheadRegExp: new RegExp("\\[\\[(.*?)(?:\\|(.*?))?\\]\\]@(" + config.textPrimitives.spaceName + ")", "mg"),
		handler: function (w) {
			this.lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
			if (lookaheadMatch && lookaheadMatch.index === w.matchStart) {
				var title = lookaheadMatch[2] || lookaheadMatch[1];
				var alt = lookaheadMatch[1] || lookaheadMatch[2];
				createSpaceLink(w.output, lookaheadMatch[3], title, alt);
				w.nextMatch = this.lookaheadRegExp.lastIndex;
			}
		}
	});

	// ensure space links don't appear as missing links
	config.textPrimitives.brackettedLink = "\\[\\[([^\\]][^@\\]][^\\]]*)\\]\\](?=[^@])";
	config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\](?=[^@])";

	// reevaluate derrived expressions ..
	config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
		config.textPrimitives.brackettedLink + ")|(?:" +
		config.textPrimitives.urlPattern + ")","mg");
	config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
		config.textPrimitives.titledBrackettedLink + ")|(?:" +
		config.textPrimitives.brackettedLink + ")|(?:" +
		config.textPrimitives.urlPattern + ")","mg");

	// treat space links in titledBracketedLink as external links
	var missingTiddlySpaceLink = new RegExp("^@@" + config.textPrimitives.spaceName + "$", "");
	var isExternalLink = config.formatterHelpers.isExternalLink;
	config.formatterHelpers.isExternalLink = function(link) {
		return missingTiddlySpaceLink.test(link) || isExternalLink(link);
	};

}(jQuery));
//}}}
Learn more at: http://freestyle.tiddlyspace.com/
/***
|''Name:''|TiddlyLightBox|
|''Date:''|Jan 1, 2006|
|''Version:''|1.0 beta|
|''Author:''|Saq Imtiaz|
|''Location:''|http://tw.lewcid.org/#TiddlyLightBoxPlugin|
|''Documentation:''|http://tw.lewcid.org/#TiddlyLightBoxDocs|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''Based on:''|DC3.LightBox<br>Light Box Gone Wild <br>Ibox|

!!Code
***/
//{{{
config.macros.imagebox ={};
config.macros.imagebox.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
    var e = place.lastChild;
    e.onclick = function(){TiddlyLightBox.initBox('image',this,params[1],params[2],params[0]);return false;};
}

config.macros.divbox ={};
config.macros.divbox.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
    if (params[0]!=".")
        createTiddlyButton(place,params[0],params[0],function(){TiddlyLightBox.initBox('html',params[1],params[3],params[4],params[2]);return false;});
    else
        {
        var e = place.lastChild;
        e.onclick = function(){TiddlyLightBox.initBox('html',params[1],params[3],params[4],params[2]);return false;};
        }
}

config.macros.tiddlerbox ={}
config.macros.tiddlerbox.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{
    config.macros.divbox.handler(place,macroName,[params[0],"tiddler:"+params[1],params[2],params[3],params[4]]);
    return false;
}

store.addNotification("TiddlyLightBoxStyles",refreshStyles);

if (!window.TiddlyLightBox)
    window.TiddlyLightBox = {};
    var loadingImage = "indicator.gif";
    window.TiddlyLightBox =
    {
    _curBox: null, // [sentinel]

    lightBoxHtml : '<div id="lightBoxOverlay" onclick="TiddlyLightBox.hideBox()" style="display:none"></div><div id="lightboxprogress" style="display:none;"><img src=\''+loadingImage+'\' alt=\'loading\' style="width:128px;height:128px;"></div><div class="lightBox" id="lightBox" style="display:none"><div id="lightBoxContent"></div><div id="lightBoxTitle">This is a title</div><div id="lightBoxClose"><a href:"#" onclick="TiddlyLightBox.hideBox();return false;">Click to close</a></div></div>',

    createBoxWrapper : function()
        {
        var wrapper = createTiddlyElement(document.getElementsByTagName("body")[0],"div","tiddlyLightBoxWrapper");
        wrapper.innerHTML = this.lightBoxHtml;
        },

    initBox : function(contentType,url,w,h,text)
        {
        if (this._curBox)
            return;
        this.showProgress();
        this.hideSelects("hidden");
        this.showBg();
        this._curBox = true;
        this.sizeTheBox(contentType,w,h);
        if (contentType == 'image')
            this.showImage(url,text);
        else if (contentType == 'html')
            this.showHtml(url,text);
        return false;
        },
        
    sizeTheBox : function(contentType,w,h)
        {
        var box = document.getElementById("lightBoxContent");
        if (w && isNaN(parseInt(w)))
            {
            addClass(box,w);
            }
        else if (w ||h || contentType == 'html')
            {
            box.style.width = w? w+ "px" : "450px";
            box.style.height = h? h+ "px" : "280px";
            if (contentType=='image')
                setStylesheet("#lightBoxContent img{height:100%;width:100%;}","lightBoxImageSizeHack");
            }
        },

    showProgress : function()
        {
        var progress = document.getElementById("lightboxprogress");
        progress.style.display='';
        this._center(progress);
        },
    
    hideProgress: function()
        {
        var progress = document.getElementById("lightboxprogress");
        progress.style.display='none';
        },

    //this function lifted from Lightbox Gone Wild
    hideSelects: function(visibility)
        {
        var selects = document.getElementsByTagName('select');
        for(i = 0; i < selects.length; i++)
            {
            selects[i].style.visibility = visibility;
            }
        },

    showBg: function()
        {
        var overlay = document.getElementById('lightBoxOverlay');
        if (config.browser.isIE)
            {
            overlay.style.height = Math.max(document.documentElement.scrollHeight,document.documentElement.offsetHeight);
            overlay.style.width = document.documentElement.scrollWidth;
            }
        overlay.style.display = 'block';
        },

    showImage: function (url,text)
        {
        imgPreloader = new Image();
        imgPreloader.onload = function ()
            {
            var lb = document.getElementById("lightBoxContent");
            lb.innerHTML = "<img src="+url+">";
            lb.onclick = function(){TiddlyLightBox.hideBox();return false;};
            TiddlyLightBox.posBox(text);
            };
        imgPreloader.src = url;
        },
        
    showHtml : function(theID,text)
        {
        var lb = document.getElementById("lightBoxContent");
        if (theID.indexOf("tiddler:")==-1)
             lb.innerHTML = document.getElementById(theID).innerHTML;
        else
            { 
             wikify(store.getTiddlerText(theID.replace("tiddler:","")),lb);
             lb.className='tiddler';
            }
        lb.style.overflow = "auto";
        this.posBox(text);
        },

    posBox: function(text)
       {
       this.setTitle(text);
       this.hideProgress();
       var lb = document.getElementById("lightBox");
       lb.style.display = "";
       lb.style.visibilty = "hidden";
       lb.style.position = "absolute";
       this._center(lb);
       if(!TiddlyLightBox._curBox) return;
       lb.style.visibility = "visible";
       lb.style.display = "block";
       },

     setTitle: function(text)
        {
        document.getElementById("lightBoxTitle").innerHTML=  (text==undefined)? '': text;
        },

    _center: function(lb)
       {
       var lbSize = new TiddlyLightBox.getElementSize(lb);
       lb.style.left = (Math.round(findWindowWidth()/2) - (lbSize.width /2) + findScrollX())+'px';
       lb.style.top = (Math.round(findWindowHeight()/2) - (lbSize.height /2) + findScrollY())+'px';
       },

    //this function lifted from Ibox
    getElementSize : function(elem)
       {
       this.width = elem.offsetWidth || elem.style.pixelWidth;
       this.height = elem.offsetHeight || elem.style.pixelHeight;
       },

     hideBox: function()
         {
         if(!this._curBox)
             return;
         document.getElementById("tiddlyLightBoxWrapper").innerHTML= this.lightBoxHtml;
         setStylesheet("","lightBoxImageSizeHack");
         this._curBox = null;
         return false;
         }
}

TiddlyLightBox.createBoxWrapper();

Story.prototype.findContainingTiddler = function(e)
{
    while(e && (!hasClass(e,"tiddler") || !e.getAttribute("tiddler")))
        e = e.parentNode;
    return(e);
}

config.shadowTiddlers.TiddlyLightBoxStyles="/*{{{*/\n#lightBoxOverlay {\n position:absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 90; \n background-color: #000;\n -moz-opacity: 0.75;\n opacity: .75;\n filter: alpha(opacity=75);\n}\n#lightBoxOverlay[id]{ \n position: fixed;\n}\n\n#lightboxprogress { \n margin:0;padding:0;\n position: absolute;\n z-index:95;\n}\n\ndiv.lightBox {\n background: #fff;\n color: #fff;\n border: 4px solid #525252;\npadding:20px 20px 25px 20px; position:absolute; z-index:99;\n}\n\n#lightBoxClose {text-align:right; color:#000; font-size:1.0em; position:absolute; bottom:6px; right:20px;}\n#lightBoxClose a{color:#666; border-bottom:1px solid #666;cursor:pointer;}\n#lightBoxClose a:hover {color:#111; border-bottom:1px solid #666; cursor:pointer; background:transparent;}\n\n#lightBoxContent {border:1px solid #525252;color:#000; background:#fff;}\n#lightBox .tiddler {background:#fff;}\n\n#lightBoxContent img {border:0;margin:0;padding:0;display:block;cursor:pointer;}\n\n#lightBoxTitle {padding:0px; font-weight:bold; position:absolute; left:20px;bottom:6px; font-size:1.1em; color:#000;}\n\n/*}}}*/";
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d">
  <path id="path3288" style="stroke-dasharray:none;" d="m32.71,59.791a1.2868,1.2868,0,1,1,-2.5736,0,1.2868,1.2868,0,1,1,2.5736,0z" fill-rule="evenodd" transform="matrix(0.472928, 0, 0, 0.472928, 12.3536, 34.6064)" stroke-linecap="round" stroke-miterlimit="4" stroke-width="4" fill="#CCC"/>
  <path id="path3637" style="stroke-dasharray:none;" d="m-5.7134,10.839a1.5781,1.5781,0,1,1,0.00225,-0.03585" transform="matrix(4.22706, 0, 0, 2.02533, 58.118, 41.1739)" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.68353766" fill="none"/>
  <path id="path4348" d="m27.559,49.224,4.9188,2.0603-3.569,0,0.15291,6.0339-3.1302,0,0-6.0339-3.514,0,5.1416-2.0603z" stroke-linecap="butt" stroke-width="0.70393437px" fill="#4d4d4d"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
[[Wrensoft Zoom|http://www.wrensoft.com/zoom/features.html]]
Notable features:
* Search results sorted by relevance or by date
* Wildcard searching (eg. "zo?m", "*zoom*")
* Exact phrase searching*
* "Google-like" context search results*
* Highlight words found in search results
* Provide spelling suggestions* and synonyms 
* Search inside DOC, PDF, PPT, XLS, RTF, WPD, ZIP files and more (see plugins#)
The only downside is that indexing is done on a Windows box. Not sure of the process required to index site since this apparently needs a Windows box.
There's a free download which will handle 50 'pages' (URL / file) but the 'Professional' edition handling up to 200,000 is only $99! [[Editions|http://www.wrensoft.com/zoom/editions.html]]
There's also explicit support for Moodle -- [[How to create a search engine for your Moodle site|http://www.wrensoft.com/zoom/support/tutorial_moodle.html]]


[[Eduforge|http://www.eduforge.com/]] has an interesting series of courses under the moniker @@get qualified in the Open Source environment@@. These included:
* Open Source in Business
* Open Source Software development model
* Technical Documentation 
* PHP Programming
* Developing Courses in Moodle
* Moodle Administration
Unfortunately for all these courses the status is {{{(course now closed for enrolment, course started 6 December 2010)}}}
|~ViewToolbar|+editTiddler cloneTiddler saveDraft closeTiddler > fields publishTiddlerRevision pubRev revisions syncing permalink references jump closeOthers closeTiddler <|
|~EditToolbar|+saveTiddler saveDraft savePublicTiddler -cancelTiddler deleteTiddler|
|~RevisionToolbar|fields revert >|
{{ts{9/03/12 11:45}}} Besides [[OU Quiz]] the [[Moodle OU github|https://github.com/moodleou]] reveals some cool other things:
!!Theme
* [[moodle-mod_subpage|https://github.com/moodleou/moodle-mod_subpage]] Subpage module allows you to add Moodle activities onto inner page within course
!!Question types
* [[moodle-qtype_gapselect|https://github.com/moodleou/moodle-qtype_gapselect]] The Gap-select question type for Moodle 2.1+ +++[more]>
This question type allows students to complete a paragraph of text by selecting the
missing words using drop-down menus. You can make questions like this using the
Cloze question type, but this question type is easier for teachers to get up, and
presents the feedback in a more accessible way.
=== 
* [[moodle-qtype_pmatchjme|https://github.com/moodleou/moodle-qtype_pmatchjme]] Moodle pmatch question type with jme molecular editor +++[more]>
Pattern match with JME editor question type

This question type was created by Jamie Pratt, working for the Open University
(http://www.open.ac.uk/).

Students can draw a molecule using the JME editor. This is then graded by matching
it against vaious model answers that are expressed using a sophisticated patten
matching algorithm. See http://docs.moodle.org/dev/The_OU_PMatch_algorithm

This question type is compatible with Moodle 2.1+ (MOODLE_21_STABLE branch) or
2.2+ (master branch).
=== 
* moodle-qtype_varnumeric -- A new question type for Moodle - for numeric questions with variable and expression evaluation
* moodle-qtype_varnumericset -- Question type for Moodle - for numeric questions with variable and expression evaluation. All val...
* moodle-qtype_oumultiresponse -- A multiple-choice, multiple response question type for Moodle, with particular scoring rules. @@good@@
* moodle-qtype_ddmarker -- question type for Moodle - drag and drop markers with text label onto an image background
* moodle-qtype_ddimageortext -- A new question type for Moodle - drag and drop images and / or text drag items onto an image back...

!!Blocks
* moodle-block_rate_course [[Course ratings block for Moodle|http://docs.moodle.org/20/en/Course_rate_block]]. Simple way for students to rate a course.
 
[[More Open University goodies]]
From Jenny Gray's (OU) blog [[Musings of a learning & teaching systems developer|http://ltsdevmusings.wordpress.com/]]:
* [[Collection module alpha review|http://ltsdevmusings.wordpress.com/2012/11/05/collection-module-alpha-review/]]
* refers to [[Survey 2 in Tracker|tracker.moodle.org/browse/MDL/component/12432]]
* [[Survey 2 module|http://docs.moodle.org/dev/Survey_2_module]] to replace Survey, Questionnaire and Feedback !!
** the [[discussion section is interesting!|http://docs.moodle.org/dev/Talk:Survey_2_module]]
[[drag and drop file upload|http://moodle.org/plugins/view.php?plugin=block_dndupload]] for Moodle 2.2!
[[forum discussion|http://moodle.org/mod/forum/discuss.php?d=181988]]
Try making it a 'sticky block' that appears on all pages!
+++[in Oct 2011]>
I've released a new version with an experimental feature - the ability to drag links and blocks of text onto a course. This is only in the Moodle 2.x version (so far).

Links can be dragged from the address bar of another browser window and will create a link in the course.

Blocks of text can be dragged from a browser window, a wordprocessor, a text editor or any other application, and will create a page containing that text.

These seem to both work fine in Chrome, but the text dragging seems a little tempramental in Firefox (latest edition, running under Ubuntu). This is entirely down to the data provided by the browser, so it's not something I can fix.

Please can I have some volunteers to test this and give some feedback? 
=== 
!!Testing with Moodle 2.2
Firefox v9 Mac OS X 10.6.8
URL : http://moodle.flyingnematode.org
Course format : Topics
* single file -- yes
* multiple files -- yes
* folder -- hangs with uploading. Stop with page refresh. No apparent ill effects though.
* URL dragged from Firefox -- yes
** dragging URL from Chrome into Firefox creates a 'Page' resource which contains the (unlinked) URL.
** dragging URL from Safari into Firefox hangs up the FF browser in Ajax (though it does not indicate 'browser not responding')
----
PC running Win XP SP2.
Site open in Firefox v9 -- other browser is old version of Flock
* single file -- yes
* multiple files -- yes. 
** still issues with 'embed' which a) doesn't work the same way it used to -- ie the frame simply does not appear, and b) [Save and Display] does ''not'' display reliably.
* copied text -- highlight text drag and drop creates a 'page' resource. Even html formatting is preserved. @@Very impressive@@
* URL -- drag and drop URL from address bar creates URL resource.
* ZIP file. Interesting because you can unzip to a folder. What to do afterwards?
You can unzip -- good. It creates a folder. But then you can only view the 'main file' in that folder. And //the folder and files are @@invisible@@// elsewhere in the course!


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
<<image tfgNewTiddler.svg>><<image tfgNewJournal.svg>><<image tfgSaveToWeb.svg>><<image tfgPermaview.svg>><<image tfgCloseAll.svg>>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#FF4646" offset="0"/>
   <stop id="stop2" stop-color="#ffcccc" offset="0.66462"/>
   <stop id="stop3" stop-color="#FF4646" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" fill-rule="evenodd" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4">
  <g id="g3238" style="stroke-dasharray:none;" transform="matrix(0.302967, -0.302967, 0.302967, 0.302967, 7.05964, 37.1409)" stroke-width="3.19999981" fill="#e6e6e6">
   <path id="path3240" style="stroke-dasharray:none;" d="m-7.3399,53.9,16.353,0"/>
   <path id="path3242" style="stroke-dasharray:none;" d="m0.8368,62.077,0-16.353"/>
  </g>
  <g id="g3250" style="stroke-dasharray:none;" transform="matrix(0.302967, -0.302967, 0.302967, 0.302967, 7.05964, 45.7405)" stroke-width="3.19999981" fill="#e6e6e6">
   <path id="path3252" style="stroke-dasharray:none;" d="m-7.3399,53.9,16.353,0"/>
   <path id="path3254" style="stroke-dasharray:none;" d="m0.8368,62.077,0-16.353"/>
  </g>
  <g id="g3282" style="stroke-dasharray:none;" transform="matrix(0.302967, -0.302967, 0.302967, 0.302967, 15.4081, 37.1409)" stroke-width="3.19999981" fill="#e6e6e6">
   <path id="path3284" style="stroke-dasharray:none;" d="m-7.3399,53.9,16.353,0"/>
   <path id="path3286" style="stroke-dasharray:none;" d="m0.8368,62.077,0-16.353"/>
  </g>
  <path id="path3288" style="stroke-dasharray:none;" d="m32.71,59.791c0,0.71068-0.57612,1.2868-1.2868,1.2868s-1.2868-0.57612-1.2868-1.2868,0.57612-1.2868,1.2868-1.2868,1.2868,0.57612,1.2868,1.2868z" transform="translate(0.690476, 2.00866)" stroke-width="4" fill="#CCC"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
We are cognizant of a couple of annoying 'security features' of Internet Explorer which, while causing aggravation, don't materially affect the functionality of Moodle.
Internet Exploder version 8 (on Win XP) will display this message on every page after logging in:

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/IE-security-warning.png]]

Clicking [Yes] or [No] seems to make no difference.
Here's how to fix this problem:
# In Interbet Exploder open Tools -> Internet Options -> Security (or click on the Security box at the bottom of the page)
# Select the Security tab
# Click on the Internet zone icon at the top of the tab page
# Click the Custom Level button
# In the Miscellaneous section change Display mixed content to Enable
# Click OK then in response to 'Are you sure you want to change settings for this zone' click [Yes]
# Repeat steps 3 – 5 for the Local Intranet and Trusted sites zones (you need to do this or it won't work)
(Thanks to Jason Robbins for sussing this one out).

Internet Explorer version 9 (on Windows 7 or Vista) displays:
[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/IE-9-screenshot.png]]

This is slightly less aggravating since you don't have to click on it in order to interact with the current page. Ignore it, but it won't go away.
In the meantime, just use Firefox -- you know it makes sense.

/***
|''Name:''|TableSortingPlugin|
|''Description:''|Dynamically sort tables by clicking on column headers|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#TableSortingPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.02|
|''Date:''|25-01-2008|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
* Make sure your table has a header row
** {{{|Name|Phone Number|Address|h}}}<br> Note the /h/ that denote a header row 
* Give the table a class of 'sortable'
** {{{
|sortable|k
|Name|Phone Number|Address|h
}}}<br>Note the /k/ that denotes a class name being assigned to the table.
* To disallow sorting by a column, place {{{<<nosort>>}}} in it's header
* To automatically sort a table by a column, place {{{<<autosort>>}}} in the header for that column
** Or to sort automatically but in reverse order, use {{{<<autosort reverse>>}}}

!!Example:
|sortable|k
|Name |Salary |Extension |Performance |File Size |Start date |h
|ZBloggs, Fred |$12000.00 |1353 |+1.2 |74.2Kb |Aug 19, 2003 21:34:00 |
|ABloggs, Fred |$12000.00 |1353 |1.2 |3350b |09/18/2003 |
|CBloggs, Fred |$12000 |1353 |1.200 |55.2Kb |August 18, 2003 |
|DBloggs, Fred |$12000.00 |1353 |1.2 |2100b |07/18/2003 |
|Bloggs, Fred |$12000.00 |1353 |01.20 |6.156Mb |08/17/2003 05:43 |
|Turvey, Kevin |$191200.00 |2342 |-33 |1b |02/05/1979 |
|Mbogo, Arnold |$32010.12 |2755 |-21.673 |1.2Gb |09/08/1998 |
|Shakespeare, Bill |£122000.00|3211 |6 |33.22Gb |12/11/1961 |
|Shakespeare, Hamlet |£9000 |9005 |-8 |3Gb |01/01/2002 |
|Fitz, Marvin |€3300.30 |5554 |+5 |4Kb |05/22/1995 |

***/
// /%
//!BEGIN-PLUGIN-CODE
config.tableSorting = {
	
	darrow: "\u2193",
	
	uarrow: "\u2191",
	
	getText : function (o) {
		var p = o.cells[SORT_INDEX];
		return p.innerText || p.textContent || '';
	},
	
	sortTable : function (o,rev) {
		SORT_INDEX = o.getAttribute("index");
		var c = config.tableSorting;
		var T = findRelated(o.parentNode,"TABLE");
		if(T.tBodies[0].rows.length<=1) 
			return;
		var itm = "";
		var i = 0;
		while (itm == "" && i < T.tBodies[0].rows.length) {
			itm = c.getText(T.tBodies[0].rows[i]).trim();
			i++;
		}
		if (itm == "") 
			return; 	
		var r = [];
		var S = o.getElementsByTagName("span")[0];		
		c.fn = c.sortAlpha; 
		if(!isNaN(Date.parse(itm)))
			c.fn = c.sortDate; 
		else if(itm.match(/^[$|£|€|\+|\-]{0,1}\d*\.{0,1}\d+$/)) 
			c.fn = c.sortNumber; 
		else if(itm.match(/^\d*\.{0,1}\d+[K|M|G]{0,1}b$/)) 
			c.fn = c.sortFile; 
		for(i=0; i<T.tBodies[0].rows.length; i++) {
			 r[i]=T.tBodies[0].rows[i]; 
		} 
		r.sort(c.reSort);
		if(S.firstChild.nodeValue==c.darrow || rev) {
			r.reverse();
			S.firstChild.nodeValue=c.uarrow;
		} 
		else 
			S.firstChild.nodeValue=c.darrow;
		var thead = T.getElementsByTagName('thead')[0]; 
		var headers = thead.rows[thead.rows.length-1].cells;
		for(var k=0; k<headers.length; k++) {
			if(!hasClass(headers[k],"nosort"))
				addClass(headers[k].getElementsByTagName("span")[0],"hidden");
		}
		removeClass(S,"hidden");
		for(i=0; i<r.length; i++) { 
			T.tBodies[0].appendChild(r[i]);
			c.stripe(r[i],i);
			for(var j=0; j<r[i].cells.length;j++){
				removeClass(r[i].cells[j],"sortedCol");
			}
			addClass(r[i].cells[SORT_INDEX],"sortedCol");
		}
	},
	
	stripe : function (e,i){
		var cl = ["oddRow","evenRow"];
		i&1? cl.reverse() : cl;
		removeClass(e,cl[1]);
		addClass(e,cl[0]);
	},
	
	sortNumber : function(v) {
		var x = parseFloat(this.getText(v).replace(/[^0-9.-]/g,''));
		return isNaN(x)? 0: x;
	},
	
	sortDate : function(v) {
		return Date.parse(this.getText(v));
	},

	sortAlpha : function(v) {
		return this.getText(v).toLowerCase();
	},
	
	sortFile : function(v) { 		
		var j, q = config.messages.sizeTemplates, s = this.getText(v);
		for (var i=0; i<q.length; i++) {
			if ((j = s.toLowerCase().indexOf(q[i].template.replace("%0\u00a0","").toLowerCase())) != -1)
				return q[i].unit * s.substr(0,j);
		}
		return parseFloat(s);
	},
	
	reSort : function(a,b){
		var c = config.tableSorting;
		var aa = c.fn(a);
		var bb = c.fn(b);
		return ((aa==bb)? 0 : ((aa<bb)? -1:1));
	}
};

Story.prototype.tSort_refreshTiddler = Story.prototype.refreshTiddler;
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText){
	var elem = this.tSort_refreshTiddler.apply(this,arguments);
	if(elem){
		var tables = elem.getElementsByTagName("TABLE");
		var c = config.tableSorting;
		for(var i=0; i<tables.length; i++){
			if(hasClass(tables[i],"sortable")){
				var x = null, rev, table = tables[i], thead = table.getElementsByTagName('thead')[0], headers = thead.rows[thead.rows.length-1].cells;
				for (var j=0; j<headers.length; j++){
					var h = headers[j];
					if (hasClass(h,"nosort"))
						continue;
					h.setAttribute("index",j);
					h.onclick = function(){c.sortTable(this); return false;};
					h.ondblclick = stopEvent;
					if(h.getElementsByTagName("span").length == 0)
						createTiddlyElement(h,"span",null,"hidden",c.uarrow); 
					if(!x && hasClass(h,"autosort")) {
						x = j;
						rev = hasClass(h,"reverse");
					}
				}
				if(x)
					c.sortTable(headers[x],rev);		
			}
		}
	}
	return elem; 
};

setStylesheet("table.sortable span.hidden {visibility:hidden;}\n"+
	"table.sortable thead {cursor:pointer;}\n"+
	"table.sortable .nosort {cursor:default;}\n"+
	"table.sortable td.sortedCol {background:#ffc;}","TableSortingPluginStyles");

function stopEvent(e){
	var ev = e? e : window.event;
	ev.cancelBubble = true;
	if (ev.stopPropagation) ev.stopPropagation();
	return false;	
}	

config.macros.nosort={
	handler : function(place){
		addClass(place,"nosort");
	}	
};

config.macros.autosort={
	handler : function(place,m,p,w,pS){
		addClass(place,"autosort"+" "+pS);		
	}	
};
//!END-PLUGIN-CODE
// %/
/***
|''Name''|SvgEvent_Info|
|''Description''|connects .svg mouse events with global TW jQuery custom events.|
|''Author''|Mario Pietsch|
|''Version''|0.2.0|
|''Source''|http://fxplugins.tiddlyspace.com|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6|
|''Keywords''|svg, events, animation, commands|
!Idea
http://softwareas.com/automagic-event-registration
!The plugin structure
# [[SvgEvent_Animations]] .. animation componets
# [[SvgEvent_Menue]] .. menue / toolbar command components
!Needed inside an .svg tiddler
*eg: [[tfgNewTiddler.svg]]
*onclick(): {{{onclick="jQuery(document).trigger('cmd3', {elem:this, comp:{menue:1}})"}}}
**Click the icon, will trigger cmd3 in SvgEvent_Menue
*onmousedown: {{{onmousedown="jQuery(document).trigger('cmd4', {elem:this, comp:{animations:1}})"}}}
*onmouseup: {{{onmouseup="jQuery(document).trigger('cmd3', {elem:this, comp:{animations:1}})"}}}
**onmousedown, onmouseup are activating the corresponding commands in SvgEvent_Animations
!Known issues
!Elements tagged {{{fxPlugins}}}
<<list filter [tag[fxPlugins]]>>
/***
|''Name:''|StoryGlueMacro|
|''Description:''|Makes SelectStoryMacro and NavigationMacro work together|
|''Author:''|Mario Pietsch|
|''Source:''|http://a-pm.tiddlyspot.com|
|''Version:''|0.5.2|
|''Status:''|beta|
|''Date:''|2010.02.06|
|''Requires:''|SelectStoryMacro, NavigationMacro|
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.2|
!!!!!Usage:
<<<
Add the macro to the ViewTemplate, specifying the tag eg:"story" and a cookie: eg:"ACTIVESTORY" to navigate between the possible stories.
Find the line: 
{{{
<div class='viewer' macro='view text wikified'></div>
}}}
''and add the following line below:'' 
{{{
<div class='viewer' macro='storyGlue story ACTIVESTORY</div>
}}}
If you are allready using "navigation" macro. Replace "navigation" macro because it is called by StoryGlueMacro to handle navigation.
Don't delete it comment it !!
<<<
!!!!!Parameter
<<<
General Format: 
{{{
<div class='viewer' macro='storyGlue storyTag COOKIENAME</div>
}}}
storyTag: The macro searches all tiddlers tagged: "storyTag"
>If the tiddler is found in one or more stories. "selectStory" macro is activated instead of "navigation" macro to switch to a new story if you want.
>If it doesn't find a matching story nothing is displayed.

COOKIENAME is last part of an txtSelectStory option cookie, that storyGlue will look at. 
>The cookie is used, to store the name of the actual story, that will be used for navigating.
>The cookie can be manipulated also by SelectStoryMacro if the same name is used. 
>Bee carefull if you use a different name. Look at my examples!
>If you don't use SelectStoryMacro you will need a little program somewhere in your init functions.
>{{{config.options.txtSelectStoryCOOKIENAME  = "yourTiddlerThatContainsAStoryAndIsTaggedWithXXXX";}}}
>Better have a look at [[zzMptwUserConfigPlugin]] 

The option: {{{<<option txtSelectStoryACTIVESTORY>>}}}: ''<<varDisplay {{config.options.txtSelectStoryACTIVESTORY}}>>''
contains the active story, that is used in [[a-pm presentation manager|http://a-pm.tiddlyspot.com]].

If you click a tiddler, which is not part of the active story, but of any tiddler tagged: "story", storyGlue will activate the SelectStoryMarcro. SelectStoryMacro will display all stories found in a different color (default: blue). If you click on of the small sqares, it will activate this story, which can be used for navigatin now. 

The SelectStoryMacro can also work stand alone. See [[SelectStoryMacro]] for more details.
<<<
!!!!!Attention
<<<
There is no limit using different cookie names. ''But be warned: If you get confused. It is not my fault :)''
If your cookie name is eg: MYSTORY the option which contains the active story will be: {{{<<option txtSelectStoryMYSTORY>>}}}
It is always: txtSelectStory + yourCookieName.
In viewTemplate call it with: 
{{{
<div class='viewer' macro='storyGlue story MYSTORY</div>
}}}
<<<
!!!!!Example:
<<<
[[Demo|Story1]]
<<<
!!!!!Revision History
<<<
*Version: 0.5.1 - 2010.01.30
**commented the displayMessage if an empty story is selected from SelectStoryMacro
<<<
***/
/*{{{*/
// 
//!BEGIN-PLUGIN-CODE
if(!version.extensions.StoryGluePlugin) { //# ensure that the plugin is only installed once
version.extensions.StoryGluePlugin = { installed: true };

if(!config.extensions) { config.extensions = {}; } //# obsolete from v2.4.2

config.macros.storyGlue= {
	defineStoryMsg: "~StoryGlue: option name is not defined!\n"+
			"Read the Documentation!\n" +
			"Check your ~ViewTemplate!\n" +
			"Check: config.options.",
	
	handler: function(place, macroName, params, wikifier, paramString, tiddler){

		if (!config.macros.navigation) 
			return false;
		if (!config.macros.selectStory) 
			return false;
		if (config.options.chkDisableStoryGlue== undefined)
			config.options.chkDisableStoryGlue= false;

		var sets = store.getTaggedTiddlers(params[0]); // get tiddlers tagged eg:'story'
		var optId = config.macros.selectStory.optPreTxt + params[1]; // get the last part of the cookie name
		var txtArray = [];
		for (var i = 0; i < sets.length; i++) {
			txtArray.push(sets[i].title);
		}
		var navIndex = txtArray.indexOf(config.options[optId]);
		if (navIndex == -1) {
			// console.log(this.defineStoryMsg+optId);
			return false; // can only be if option is undefined or different pc / cookie
		}
		var tiddlers = store.getTiddlerText(sets[navIndex].title).readBracketedList(); // read tiddlers in active story
		var tidIndex = tiddlers.indexOf(tiddler.title);
		
		// storyline ok .. use navigation macro 
		if (tidIndex != -1) {
			var p = "tiddlers:{{store.getTiddlerText('" + sets[navIndex].title + "').readBracketedList()}}";
			invokeMacro(place, 'navigation', p, wikifier, tiddler);
			return false;
		}
		if (config.options.chkDisableStoryGlue) 
			return false;

		if (this.debug) console.log('not disabled:', tiddlers);

		if (tidIndex == -1) {
			// search other stories for this tiddler.
			var text = params[1]+' '+'tiddlers: [[';
			var found = false;
			for (var i=0; i<txtArray.length; i++) {   //!!!!!!! better search needed !
				tiddlers = store.getTiddlerText(txtArray[i]).readBracketedList(); // read tiddlers in active story
				tidIndex = tiddlers.indexOf(tiddler.title);
				if (tidIndex != -1) {
					found = true;
					text = text + '"' + txtArray[i] + '" '; 
				} // if tidIndex ..	
			} // for i < txtArray.len ..
			text = text+']]';
//	 console.log( 'text: ' + text);
//	 console.log( 'found: ' + found);
//			var text = params[1]+" "+ "tiddlers: {{ var array = store.filterTiddlers('[tag[" + params[0] + 
//				"]]');var text = ''; for (var i=0; i<array.length; i++)"+
//				"{text = text + '[[' + array[i].title + ']]';};}}";		// be carefull evaluated string !!!

			if (found) invokeMacro(place, 'selectStory', text, wikifier, tiddler);
		} // handler
	} // config macro
}
} //# end of "install only once"
/*}}}*/
/***
|''Name''|TiddlySpaceRevisionView|
|''Description''|Show tiddler revisions in a stack of cards view|
|''Author''|BenGillies|
|''Version''|0.2.0|
|''Status''|beta|
|''Source''|http://github.com/TiddlySpace/tiddlyspace|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Requires''|TiddlyWebAdaptor|
!Usage
The viewRevisions macro can be attached to any element, which should be passed
in as a parameter.

For example:

&lt;&lt;viewRevisions page:10 link:"<<view modified date>>"&gt;&gt;

would show the revisions "stack of cards" view, 10 at a time, when the modified
date is clicked.
!Code
***/
//{{{
(function($) {

var me = config.macros.viewRevisions = {
	revisionTemplate: "RevisionTemplate",
	revSuffix: " [rev. #%0]", // text to append to each tiddler title
	defaultPageSize: 5, // default number of revisions to show
	defaultLinkText: "View Revisions", // when there's nothing else to use
	offsetTop: 30, // in px
	offsetLeft: 10, // in px
	shiftDownDelay: 50, // in ms
	visibleSlideAmount: 20, // amount of revisions to show on left hand edge after sliding
	zIndex: 100, // default z-index
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		params = paramString.parseParams(null, null, true)[0];
		var tiddlerElem = story.findContainingTiddler(place);

		var revButton;
		var pageSize = parseInt(params.page[0], 10) || me.defaultPageSize;
		var linkObj = params.link ? params.link[0] || me.defaultLinkText : false;
		if(linkObj) {
			revButton = $('<span class="button openRevisions" />')
				.appendTo(place);
			wikify(linkObj, revButton[0], null, tiddler);
		} else {
			revButton = place;
		}

		$(revButton).click(function() {
			if (!$(tiddlerElem).hasClass("revisions")) {
				me.showRevisions(tiddlerElem, tiddler, pageSize);
			} else {
				me.closeRevisions(tiddlerElem);
			}
		});
	},

	// initialisation for revision view
	showRevisions: function(tiddlerElem, tiddler, pageSize) {
		var context = {
			host: tiddler.fields["server.host"],
			workspace: tiddler.fields["server.workspace"]
		};
		$(tiddlerElem).addClass("revisions").attr("revName", tiddler.title);
		// ensure toolbar commands deactivate RevisionsView
		$("a", ".toolbar", tiddlerElem).each(function(index, btn) {
			var _onclick = btn.onclick;
			btn.onclick = function(e) {
				me.closeRevisions(tiddlerElem);
				_onclick.apply(this, arguments);
			};
		});
		// ensure default action deactivates RevisionsView
		var _ondblclick = tiddlerElem.ondblclick;
		tiddlerElem.ondblclick = function(e) {
			me.closeRevisions(tiddlerElem);
			_ondblclick.apply(this, arguments);
		};
		var type = tiddler.fields["server.type"];
		var adaptor = new config.adaptors[type]();
		var userParams = {
			tiddlerElem: tiddlerElem,
			pageSize: pageSize,
			title: tiddler.title
		};
		me.createCloak(tiddlerElem);
		adaptor.getTiddlerRevisionList(tiddler.title, null, context, userParams,
				function(context, userParams) {
					// strip the current revision
					context.revisions.shift();
					me.expandStack(context, userParams);
				});
	},

	// fetch the actual revision and put it in the tiddler div
	showRevision: function(place, revision, callback) {
		var context = {
			host: revision.fields["server.host"],
			workspace: revision.fields["server.workspace"]
		};
		var userParams = {
			revElem: place
		};
		var type = revision.fields["server.type"];
		var adaptor = new config.adaptors[type]();
		var revNo = revision.fields["server.page.revision"];
		adaptor.getTiddlerRevision(revision.title, revNo, context, userParams,
			function(context, userParams) {
				var tiddler = context.tiddler;
				tiddler.title += me.revSuffix
					.format([$(place).attr("revision")]);
				tiddler.fields.doNotSave = true;
				if (store.getTiddler(tiddler.title)) {
					store.deleteTiddler(tiddler.title);
				}
				store.addTiddler(tiddler);

				//now, populate the existing div
				var revElem = userParams.revElem;
				$(revElem).attr("id", story.tiddlerId(tiddler.title));
				$(revElem).attr("refresh", "tiddler");
				var getTemplate = function() {
					var themeName = config.options.txtTheme;
					if (themeName) {
						return store.getTiddlerSlice(themeName,
							me.revisionTemplate) || me.revisionTemplate ||
							"ViewTemplate";
					} else {
						return (store.getTiddler(me.revisionTemplate)) ?
							me.revisionTemplate : "ViewTemplate";
					}
				};
				var template = getTemplate();
				story.refreshTiddler(tiddler.title, template, true);
				callback(tiddler);
			});
	},

	createCloak: function(promoteElem) {
		var el = $(promoteElem);
		// cache styles for resetting later
		el.data({
			top: el.css("top"),
			left: el.css("left"),
			zIndex: el.css("z-index")
		});

		$('<div class="revisionCloak" />').css("z-index", me.zIndex)
			.click(function() {
				me.closeRevisions(promoteElem);
			})
			.appendTo(document.body);

		el.css("z-index", me.zIndex + 1);
	},

	// clean up, removing all evidence of revision view
	closeRevisions: function(promoteElem) {
		var el = $(promoteElem);
		// revert the original tiddler back to its previous state
		el.removeAttr("revName").removeClass("revisions").css({
			top: el.data("top"),
			left: el.data("left"),
			zIndex: el.data("zIndex")
		});

		// remove any revisions still in the store
		var revisions = $(".revisions");
		revisions.each(function(index, revision) {
			var revAttributes = revision.attributes;
			if ((revAttributes.revname) &&
					(revAttributes.revision)) {
				var revName = revAttributes.revname.value;
				var revNo = revAttributes.revision.value;
				var title = revName + me.revSuffix.format([revNo]);

				if (store.getTiddler(title)) {
					store.deleteTiddler(title);
				}
			}
		});

		// delete the previous revisions
		revisions.remove();

		// remove the cloak
		$(".revisionCloak").remove();
	},

	// calback from getting list of revisions
	expandStack: function(context, userParams) {
		var pageSize = userParams.pageSize;

		var from = userParams.from || 0;
		var tiddlerElem = userParams.tiddlerElem;

		userParams.defaultHeight = $(tiddlerElem).height();
		userParams.defaultWidth = $(tiddlerElem).width();
		if (from < context.revisions.length) {
			me.displayNextRevision(tiddlerElem, userParams, context, from,
				from + pageSize - 1);
		}
	},

	// place the next div above and behind the previous one
	displayNextRevision: function(tiddlerElem, userParams, context, from, to) {
		var revision = context.revisions[from];
		var callback = function() {
			var revText = revBtn.getRevisionText(tiddlerElem, revision);
			tiddlerElem = me.createRevisionObject(tiddlerElem, context,
				userParams, revText);
			$(tiddlerElem)
				.attr("revision", (context.revisions.length - from));
			if ((from < to) && ((from + 1) < context.revisions.length)){
				me.displayNextRevision(tiddlerElem, userParams, context,
					from + 1, to);
			} else if ((context.revisions.length - 1) > to) {
				me.showMoreButton(tiddlerElem, context, userParams, to + 1);
			}
		};
		me.shiftVisibleDown(userParams.title, callback);
	},

	createRevisionObject: function(tiddlerElem, context, userParams, text) {
		var newPosition = me.calculatePosition(tiddlerElem, context);
		return $('<div class="revisions tiddler" />')
			.css({
				position: "absolute",
				top: newPosition.top,
				left: newPosition.left,
				"z-index": me.zIndex + 1,
				height: userParams.defaultHeight,
				width: userParams.defaultWidth
			})
			.attr("revName", userParams.title)
			.append(text)
			.insertBefore(tiddlerElem);
	},

	// move the already present revisions down by 1 to fit the next one in
	shiftVisibleDown: function(title, callback) {
		var revisions = $("[revName='%0'].revisions".format([title]));
		var revisionCount = revisions.length;

		$(revisions).animate({top: "+=" + me.offsetTop},
				me.shiftDownDelay, function() {
					revisionCount -= 1;
					if ((callback) && (!revisionCount)) {
						callback();
					}
				});
	},

	// where we put the new revision
	calculatePosition: function(elem, context) {
		var offset = $(elem).offset();
		var currentPosition = $(elem).position();
		var newPosition = {
			top: currentPosition.top - me.offsetTop
		};
		if ((context.restrictLeft) ||
				((offset.left - me.offsetLeft) <
				$("#contentWrapper").offset().left)) {
			newPosition.left = $(elem).position().left;
			context.restrictLeft = true;
		} else {
			newPosition.left = currentPosition.left - me.offsetLeft;
		}
		return newPosition;
	},

	// equivalent of displayNextRevision, but for the more button
	showMoreButton: function(tiddlerElem, context, userParams, moreIndex) {
		userParams.from = moreIndex + 1;
		me.shiftVisibleDown(userParams.title, function() {
			var btn = me.createRevisionObject(tiddlerElem, context, userParams,
				"");

			var more = createTiddlyButton(btn[0], "more...", "show more revisions",
				function() {
					if ($(".viewRevision").length) {
						return;
					}
					userParams.tiddlerElem = btn[0];
					$(btn).text("")
						.append(revBtn
							.getRevisionText(btn[0], context.revisions[moreIndex]))
						.attr("revision", context.revisions.length - moreIndex);
					me.expandStack(context, userParams);
				});
			$(more).css("float", "right");
		});
	},

	stripRevFromTitle: function(revisionTitle) {
		return revisionTitle.split(/ ?\[rev\. #[0-9]+\]$/)[0];
	},

	onClickRevision: function(revElem, revision, callback) {
		// don't do anything if we are still loading
		if ($(".revisions").hasClass("loading")) {
			return null;
		}

		var origTitle = me.stripRevFromTitle(revision.title);
		if ($(revElem).hasClass("viewRevision")) {
			$(".revisions").addClass("loading");
			me.slideIn(revElem, revision, origTitle, function() {
				store.deleteTiddler(revision.title);
				revision.title = origTitle;
				$(revElem).text("").append(revBtn.getRevisionText(revElem,
						revision))
					.removeAttr("tags").removeAttr("tiddler")
					.removeAttr("refresh").removeAttr("template")
					.removeAttr("id");
				$(".revisions").removeClass("loading");
				if (callback) {
					callback();
				}
			});
			$(revElem).removeAttr("prevPos").removeClass("viewRevision");
		} else {
			var viewRevision = function() {
				var prevPos = $(revElem).position().left;
				$(revElem).addClass("viewRevision").attr("prevPos", prevPos);
				$(".revisions").addClass("loading");
				me.showRevision(revElem, revision, function(rev) {
					me.slideOut(revElem, rev, origTitle, function() {
						$(".revisions").removeClass("loading");
					});
				});
			};
			// make sure another revision isn't already out
			if ($(".viewRevision").length) {
				var newRevElem = $(".viewRevision")[0];
				var newRevision = store.getTiddler($(newRevElem)
					.attr("tiddler"));
				me.onClickRevision(newRevElem, newRevision, viewRevision);
			} else {
				viewRevision();
			}
		}
	},

	slideOut: function(revElem, revision, title, callback) {
		var leftMostPos = $("[revName='%0'].revisions".format([title]))
			.offset().left;
		var width = $(revElem).width();
		var originalLeftPos = $(story.getTiddler(title))
			.position().left;

		var slideAmount = leftMostPos + width - me.visibleSlideAmount;
		$("[revName='%0'].revisions:not(.viewRevision)".format([title]))
			.animate({left: "-=" + slideAmount}, 1000);
		$(revElem)
			.attr("baseHeight", $(revElem).css("height"))
			.css("height", "auto")
			.animate({left: originalLeftPos}, 1000, callback);
	},

	slideIn: function(revElem, revision, title, callback) {
		var slideAmount = $(revElem).offset().left -
			$(story.getTiddler(title)).offset().left;
		var origRevPos = $(revElem).attr("prevPos");

		$("[revName='%0'].revisions:not(.viewRevision)".format([title]))
			.animate({left: "+=" + slideAmount}, 1000);
		$(revElem).animate({left: origRevPos}, 1000, function() {
			$(revElem)
				.css("height", $(revElem).attr("baseHeight"))
				.removeAttr("baseHeight");
			callback();
		});
	}
};

var revBtn;
config.macros.slideRevision = revBtn = {
	btnText: "created by %0 at %1 on %2",
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		var btn = revBtn.getRevisionText(place, tiddler);
		$(place).append(btn);
	},

	getRevisionText: function(place, revision) {
		var text = revBtn.btnText.format([revision.modifier,
			revision.modified.formatString("0hh:0mm"),
			revision.modified.formatString("0DD MMM YYYY")]);
		var btn = $('<a href="javascript:;" class="button revButton" />')
			.text(text)
			.click(function() {
				var revElem = story.findContainingTiddler(this);
				me.onClickRevision(revElem, revision);
			});
		return btn;
	}
};

})(jQuery);
//}}}
<<activity>>
# Modify Collapsed topics CSS to fit with theme:
** +++[topic header size]
{{{
/* -- The table data section of a Toggle's row -- */
tr.cps td {
/*	font-size: 0.8em;*/
	text-align: left;
	padding: 0 0;
	width: auto;
}

/* -- The topic summary text -- */		
tr.cps td span {
/*	font-size: 1.2em;*/
	font-size: 1.0em;
	font-style: bold;
	text-align: left;
}
}}}
Disabling the first //font-size// setting of 0.8em increases the display size of the whole heading from 11px to 14px and then it's reset to 12px! I'm really not sure why that first setting is present. Make these changes in {{{course/format/topcoll/topics_collapsed.css}}}
=== 
** +++[change colors to match]
According to this comment :
{{{/* July-30-2010 Moved css definitions into 'anomaly : blue' theme (theme/anomaly/styles_blue.css) but nowhere else */}}}
So, here they are:
{{{
tr.cps {
        background-color: #CCB28F;
        color: #C60; /* 'Topic x' text colour */
}

/* Toggle text */
tr.cps td a {
        text-decoration: none;
        color: #310;
}

/* -- What happens when a toggle is hovered over -- */
tr.cps td a:hover {
        background-color: #FFE;
        color : #310;
        font-weight : bold;
}
}}}
Paste these into {{{cafelite-wr.css}}} These colours work @@really nicely@@
=== 
# substitute 'Droid Sans' for 'Open Sans' -- it's rather heavier and more legible. +++[link]
{{{ 
<link
    href='http://fonts.googleapis.com/css?family=Ubuntu:500|Droid+Sans:400,700' rel='stylesheet' type='text/css'>
}}}
=== 
# Fix missing icons for +++[plugin blocks: ]
Have also had to create the following folders in {{{cafelite-wr/pix/mod}}}:
{{{
drwxr-xr-x  2 markp  admins   512 Apr 30 21:03 attforblock
drwxr-xr-x  2 markp  admins   512 Apr 30 21:03 enhancedfile
drwxr-xr-x  2 markp  admins   512 Apr 30 21:03 forumng
drwxr-xr-x  2 markp  admins   512 Apr 30 21:03 oublog
drwxr-xr-x  2 markp  admins   512 Apr 30 21:03 assignment
}}}
And added in {{{icon.gif}}} from the module directories. Now all the icons show up in Course menu properly!
=== 
# Make hover style more noticeable. +++[code]
{{{
a:hover {
    color: #310;
    text-decoration: none;
    border-bottom: 1px dashed #310;
}
}}}
Also have to remove //border-bottom// from the collapsed topics style.
{{{
tr.cps td a:hover {
        background-color: #FFE;
        color : #310;
        font-weight : bold;
       border-bottom : 0px;
}
}}}
If you don't want the dashed line anywhere just add {{{a:hover {border-bottom : 0px;} }}} to the appropriate style setting.
=== 
# I wanted to implement [[autohide|Reducing clutter]] but it didn't work as such since it was designed for Moodle 2.x. And I don't have the time (or inclination to faff about with it to make it work.
# Final zipped theme [[cafelite-theme|http://legacy.earlham.edu/~markp/moodledocs/graphics/cafelite-theme.zip]] created {{ts{1/05/12 15:52}}}
----
{{ts{1/05/12 17:18}}}
* fixed the {{{#cafelite-wr-menu}}} styles from underlining with judicious application of {{{border-bottom : 0px;}}} to {{{a:hover;}}} styles

Converting from course wide % to category %
Task : Put all assignments together into a single category and weight appropriately.
|!Assignment|! % course total|>|!% when all assignments worth 50%|!Weight to biggest ass=100|!|!Moodle weighted %|
|Assignment 1| 15%| 15 * 50/70 | 10.7| 10.7/14.3 * 100 |=| 75 |
|Assignment 2| 5%| 5  * 50/70 | 3.6| 3.6/14.3 * 100 |=| 25 |
|Assignment 3| 15%| 15 * 50/70 | 10.7| 10.7/14.3 * 100 |=| 75 |
|Assignment 4| 15%| 15 * 50/70 | 10.7| 10.7/14.3 * 100 |=| 75 |
|Assignment 5| 20%| 20 * 50/70 | 14.3| 14.3/14.3 * 100 |=| 100 |
|''Total''| @@70%@@|| @@50%@@| ||''Category : Assignments (50%)'' |
/*{{{*/
/* user stuff comes here */
/* prefer monospace for editing */
.editor textarea, .editor input {
	font-family: 'Consolas', Monaco, monospace;
        font-size:.8em;
        line-height : 1.4em;
	background-color:[[ColorPalette::TertiaryPale]];
}
body {
      font-family: 'Calibri', 'Gill Sans MT', sans serif;
}
.tabContents, .tab, .dp10, #mainMenu {
      font-family:arial,helvetica;
}
.viewer pre, .viewer code{
	font-family: 'Consolas', Monaco, monospace;
        font-size:1em;
}
/*}}}*/
[[Inside Higher Ed|http://www.insidehighered.com]] : [[A Course Badging Case Study|http://www.insidehighered.com/blogs/technology-and-learning/course-badging-case-study]]
+++!![Question 1: Can you give us a quick sketch of how you introduced badging into your course?]
Michael Evans (professor):
:As a Neukom Fellow, I had the opportunity to design a new course based on my research interests in science and religion in American media. The course is highly interdisciplinary and multimodal (LMS assignments, lectures, student-led classroom discussion, software skills training), so there were some challenges in tracking and evaluating student progress.
:I decided to experiment with badging to track the portion of my course focused on digital scholarship skills. I introduced badging to students as part of the syllabus. For all of their digital scholarship assignments, they could receive both a grade and a badge. Each assignment would earn a "progress badge," and completion of an entire training sequence or practice sequence would earn a "completion badge."
=== 
+++!![Question 2: What objectives were you trying to achieve by using badges?]

Michael Evans (professor):

The main objective was to communicate student competency beyond the grade or transcript.

In addition to the normal complement of lectures and discussion and exams in the course, students also learn how to use media analysis software and produce digital scholarship. But you would never know that from the course title or grades or transcript information.

Badges retain the validity of a grade or endorsement, but are flexible enough for students to communicate to future employers, to grad school admissions committees, or to their friends and colleagues.

Their grade says "I got an A in the course" but the badge says "I can search, collect, edit, collaborate, compose, curate, annotate, and analyze digital video, audio, and text."
=== 
+++!![Question 3: What were the steps necessary to enable Michael E to utilize badging in his class?]

Michael Goudzwaard (instructional designer):

# First, we explored what badges would achieve in the course that other forms of assessment would not. In short, //badges would allow students to communicate their evidence-based skills they had developed in this course with an external audience.// Badges also demonstrate competency required in other courses. For example, as part of their work in Michael's course students attended training on a specific software, [[Mediathread|http://mediathread.columbia.edu/]]. A Mediathread badge could allow a student to work toward a higher level badge in a future course rather than repeat the same training.
#The second step was to define __badge outcomes__, which essentially are __learning outcomes fit into the badge framework__. Badges offer the possibility of linking to evidence of competence. In one meeting I recall we talked about crafting the Mediathread badge outcome from "attend training" to "create a MT project based on training".
#Third, we evaluated badge issuing methods currently available in the badge-o-sphere. We had to educate ourselves about the relationships and realities of platforms such as [[Mozilla's Backpack|http://backpack.openbadges.org/backpack/login]], [[Credly|https://credly.com/]], and other third party issuers. We tested badging plug-ins in Canvas (our LMS) and ultimately Credly offered the simplest and most portable badges for students.

I think it would be ideal in the future to have the badge issuing more tightly integrated with the LMS (Canvas). This would support the pedagogy and lessen the work of both badging and grading for the course.
;Note:
: Badges are tightly integrated in Moodle since 2.5
=== 
+++!![Question 4: How do you plan to use badges in your future teaching?]
Michael Evans (professor):

I have two answers for this.

# First, I plan to continue using badges to track and communicate student accomplishments that might otherwise get lost in traditional grading and recording schemes. I am even considering whether it is possible to go all-badge for my media course, with the ultimate course grade being calculated based on the number of badges completed.
# Second, I plan to use badging as a way to think about how I might improve my course design, whether that is around competencies, scale, technology integration, evaluation, or simply doing a better job of articulating learning objectives.

Through working on this project I've found that many of the conversations about badges aren't actually about badges at all. The very possibility of badges exposes a lot of unresolved tensions around how we teach and learn.

I don't think that badges will magically resolve all of those tensions. But thinking and talking about how they might do so can be productive.
=== 
+++!![Question 5: What issues does your collaboration with Michael E. with badging raise about course design, evaluation and assessment?  What do you see as the path forward?]

Michael Goudzwaard (instructional designer):

At the core of badging platforms is developing evidence-based competency outcomes and at the core of course design is defining learning outcomes so the two are closely linked.  A similar backward-design process can be used with both to start with activities and assignments and design back to outcomes.

While there is a relationship between learning and competency, I am not suggesting that you might be able to equate every part of a course to a badge. In interviewing a few of Michael E's students about badging, one student reflected that badges seem binary and not that applicable to non-science courses.

For badging in to be useful in the broader arts and humanities, feedback to students needs to be robust and the iterative path to mastery well documented.

For the path forward I am interested in Michael's proposal of going "all badge" the next time he teaches this course. In this model a student might choose 22 out of 25 possible badges.

I could also see another course using badges, particularly if the course built on competencies demonstrated by the badges Michael E. issued.

We as a teaching and learning community should continue to have conversations about the value to students of badges in courses, the relationship between badges and overall assessment, and the implications badging has to inform teaching and learning.
=== 
The way I have Moodle setup currently is as follows:
* EC Academic courses by semester and department
* MAT courses by semester
* other non-credit gaining moodle Categories eg Campus, Committees, Departmental, Miscellaneous.
!!Which Academic courses to include in import?
* Center for Integrated Learning. Do we need some or all of these, eg Library Immersion Fellows? If some, which courses? Easier to exclude the whole category.
* ART
** Internship -- eg ART481 ?
** Different levels of Ceramics, Painting, Metals, Photography -- do you want surveys for each of 4 levels?
** Independent Study ? -- probably yes
** Senior project for Art History, Ceramics, Drawing, Fibers, Metals, Painting, Photography?
** Ford Knight ?
** Teaching Assistant ? How does the student (or me?) know which TA 'course' listed as Teaching Assistant is associated with which course they are TA in?
** ART0 courses, eg ART0340-1 SP Topics in Design&Arch
* Athletics. Are there courses within Athletics that should be surveyed? 
* Crosslisted courses -- I don't think that this should be a problem. Just use the moodle crosslisted course name.
* Off Campus programs -- should these have a separate survey? This should be possible. A lot of the Moodle courses don't have any enrollments.
* Music. A lot of 'Applied' classes. Distinguish between MUS, MUSL & MUSG? 
* TESOL ?
* Theatre Arts. Here again a lot of Applied courses. Which ones should be surveyed?
* //Senior Capstone Experience// -- should this have a separate survey across the college?
* MAT -- exclude ?
----
Can filter on import into EK. Suggest :
* include only courses in current semester Category (eg Fall 2013) (this will exclude MAT)
* exclude all courses with no enrollments
* include only courses with Course ID number (= Banner termcode, eg 12586.201410).
** This will exclude all non for credit courses
* exclude a list of certain course categories, eg Athletics, CIL, TESOL
* exclude list of courses with names containing "Applied" , "Teaching Assistant" -- list the system wide course names we want to exclude
2nd attempt to backup and restore Moodle Front page.
1. +++[Backup on 2.1]

Using Settings -> Site Administration : Front page : Front page backup
* Include enrolled users
** Anonymize user information -- not checked
* Include user role assignments
* Include user files
* Include activities
* Include blocks
* Include filters
* Include comments
* Include user completion details
Schema settings -- some data not included
Backup file successfully created. Located in Course Backup Area. But the default filename is somewhat strange:
{{{backup-moodle2-course-omio-20120121-1106.mbz}}}.
Settings : //Front page settings// : ''Restore'' is bolded.
=== 
2. +++[Restore on 2.2]

Use Settings -> Site Administration : Front page : Front page restore (points to
{{{/files/index.php?id=1&wdir=%2Fbackupdata}}}
<<<
{{{
Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, markp@earlham.edu and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.
}}}
<<<
But using Settings : Front page settings : Restore (link {{{/backup/restorefile.php?contextid=2}}}
Goes to Course backup area:
# Choose file. Open Upload {{{backup-moodle2-course-omio-20120121-1106.mbz}}} same one as backed up.
# First page -- Backup Details, Backup settings, Course details all good.
# Destination : Restore as new course (for Front page?), Delete contents of this course, then restore.
# Restore settings good
# Course settings. Changes:
** Keep current roles and enrolments : --yes-- ''no'' (what does 'current' mean? The front page page currently present or the one I'm trying to replace it with? I 'think' it means the page currently present since the default is 'no'). Would be better to phrase this -- 'overwrite current roles with new roles' yes). So, leave this at ''no''.
** ditto groups -- no
** Overwrite course configuration : ''yes''
# perform restore
# {{{Restoring over front page is not allowed.}}}
@@BROKEN@@
=== 
----
{{ts{3/02/12 16:47}}} Repeat with Advanced features -> Development -> Debugging :  Debug messages : ALL
* On Screen 3 of the restore process, choose Restore into this course : Merge the backup course into this course (default)
* Restore settings good
* Schema : Overwrite course configuration : yes. All components checked (Section 0, section 1) and User data checked as well.
* Review -> [Perform restore]
* Message {{{Restoring over front page is not allowed}}}. No debugging messages [[Front page restore error]]

----
* Issues on Tracker : [[Front page backup/restore issues]]


//{{{
config.shadowTiddlers["StyleSheetNeuiEm"]="/*{{{*/\n"+
	".image .showFG {\n"+
	"	opacity: 0;\n"+
	"}\n"+
	"\n"+
	".image:hover .showFG {\n"+
	"	opacity: 1;\n"+
	"}\n"+
	"/*}}}*/";
store.addNotification("StyleSheetNeuiEm",refreshStyles);
//}}}
<html>
<h2 style="text-align: center;">New way to access courses on Moodle</h2>
<p>For the 2012-13 school year Moodle has a new look and slightly different feel. You will have already noticed by now the handy menu bar and you might like to take the time to update your Profile with a personal photo so that new students have an easier time discovering the real you.</p>
<p>Also on the menu bar is a link to MyMoodle. You may be wondering why you need this.</p>
<p><img alt="myCourses display" height="434" src="https://moodletest.earlham.edu/file.php/1/moodle2013-mycourses.png" style="float: left; margin: 5 10 5 0;" title="myCourses display" width="318" /></p>
<p>Well, this year due to popular unrest, sorry, requests, I have 'unhidden' <em>all</em>&nbsp;courses from all previous years. And I'm promoting the myCourses block as the best way of browsing through your old courses to see what is there.</p>
<p>The javascript menu of myCourses displays departmental course categories which are used to group courses together and a nifty feature is that the menus are now 'sticky'. That is, when you come back to Moodle (if using the same browser) the menu opens to the same place that you left it. The magic of browser cookies!</p>
<p>Of course, you can still use MyMoodle and it'll only take an extra click to get there, but now that all your courses are unhidden they will all be listed in the MyMoodle screen.&nbsp;So you'll either want to customize your MyMoodle display (hit 'edit') or use myCourses.</p>
<p>All your new courses are at the top of the list and, as before, you'll use Administration : Import &nbsp;to import a previous year's course.</p>
</html>
<<binaryUpload edit:title>>
Learn more at: BinaryUploadPlugin
/***
|''Name''|tsScanCountPlugin|
|''Description''|Provides ability to count tiddlers at a given tiddlyspace url and display a button that when clicked lists them. Also upgrades tsScan to replace any options containing with $1 with the current space|
|''Version''|0.2.0|
***/
//{{{
(function($) {

var tsScan = config.macros.tsScan;
var tiddlyspace = config.extensions.tiddlyspace;

var macro = config.macros.tsScanCount = {
	cache: true,
	countCache: {},
	handler: function(place, macroName, params, w, paramString, tiddler) {
		var container = $("<a href='#' class='button' />").attr("refresh", "macro").attr("macroName", macroName).appendTo(place)[0];
		$(container).data("params", paramString);
		macro.refresh(container);
	},
	refresh: function(container) {
		var paramString = $(container).data("params");
		var options = tsScan.getOptions(paramString, tiddler);
		var url = options.url;
		options.cache = macro.cache;
		options.callback = function(tiddlers) {
				options.cache = true;
				macro.cache = true;
				var count = tiddlers[0] ? tiddlers[0].fields['server.page.revision'] : 0;
				var lastCount = macro.countCache[url] || 0;
				if(lastCount != count) {
					var interval, step = 0;
					interval = window.setInterval(function() {
						var last = step;
						step += 1;
						$(container).removeClass("step" + last);
						if(step > 10) {
							macro.countCache[url] = count;
							window.clearInterval(interval);
						} else {
							$(container).addClass("step" + step);
						}
					}, 500)
				}
				$(container).empty().addClass("enabled").text(tiddlers.length).click(function(ev) {
				$(ev.target).addClass("active");
				var target = options.popupSelector ? $(options.popupSelector)[0] : ev.target;
				var p = Popup.create(target, "div");
				var container;
				if(options.heading) {
					container = $("<div />").addClass("heading").appendTo(p)[0];
					wikify(store.getTiddlerText(options.heading) || "", container);
				}
				container = $("<div />").addClass("followTiddlersList").appendTo(p)[0];
				tsScan.scan(container, options);
				Popup.show();
				ev.stopPropagation();
				return false;
			});
		};
		tsScan.scan(container, options);
	}
}

var _getOptions = tsScan.getOptions;
config.macros.tsScan.getOptions = function(paramString, tiddler) {
	var options = _getOptions.apply(this, arguments);
	var optionsClone = {};
	for(var i in options) {
		if(typeof(options[i]) == "string") {
			optionsClone[i] = options[i].format(tiddlyspace.currentSpace.name);
		} else {
			optionsClone[i] = options[i];
		}
	}
	return optionsClone;
}

// every 5 minutes make tsScan update.
window.setInterval(function() {
	macro.cache = false;
	$("[macroName=tsScanCount]").each(function(i, el) {
		macro.refresh(el);
	});
}, 1000 * 60 * 5);
})(jQuery);
//}}}
/***
|''Name''|TiddlySpaceCloneTiddlerCommand|
|''Version''|0.6.0|
|''Status''|@@experimental@@|
|''Requires''|TiddlySpaceConfig TiddlySpaceTiddlerIconsPlugin TiddlySpacePublishingCommands|
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var tweb = config.extensions.tiddlyweb;
var cmd = config.commands.publishTiddler;

merge(config.macros.tiddlerOrigin, {
	prompt: function(ev, msg, callback, options) {
		var popup = Popup.create(ev.target);
		$(popup).addClass("confirmationPopup prompt").click(function(ev) {
			if(ev.target.parentNode != document) {
				ev.stopPropagation();
			}
		});
		var form = $("<form />").appendTo(popup);
		$("<div />").addClass("message").text(msg).appendTo(form);
		var input = $('<input type="text"/>').appendTo(form).focus()[0];
		var submitForm = function(ev) {
			callback(ev, $(input).val());
			return false;
		};
		form.submit(submitForm);
		$("<button />").addClass("button").text(options.okLabel || "ok").appendTo(form).
			click(submitForm);

		Popup.show();
		ev.stopPropagation();
	}
});
var originMacro = config.macros.tiddlerOrigin;

var push = config.commands.pushTiddler = {
	text: "push tiddler",
	tooltip: "Inform the originating tiddler that you have made changes to this tiddler",
	isEnabled: function(tiddler) {
		return tiddler.fields._original_tiddler_source &&
			tiddler.fields._original_tiddler_revision && !tiddler.fields._push;
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		tiddler.fields._push = "yes";
		autoSaveChanges(null, [ store.saveTiddler(tiddler) ]);
	}
};

var flick = config.commands.flickTiddler = {
	text: "flick tiddler",
	tooltip: "Flick this tiddler to another public space",
	isEnabled: function(tiddler) {
		return tiddlyspace.getTiddlerStatusType(tiddler) == "public";
	},
	handler: function(ev, src, title) {
		var tiddler = store.getTiddler(title);
		var bag = tiddler.fields["server.bag"];
		var revision = tiddler.fields["server.page.revision"];
		if(tiddler && bag && revision) {
			tweb.getStatus(function(status) {
				originMacro.prompt(ev, flick.tooltip, function(ev, space) {
					var uri = tiddlyspace.getHost(status.server_host, space);
					var fullUri = "%0#clone:[[bags/%1/tiddlers/%2/revisions/%3]]".
						format(uri, bag, title, revision);
					window.open(fullUri);
				}, {});
			});
		}
	}
};

var p = config.paramifiers.clone = {
	onstart: function(url) {
		p.clone(url);
	},
	clone: function(url, morph) {
		ajaxReq({
			dataType: "json",
			url: url,
			success: function(data) {
				var tiddler = config.adaptors.tiddlyweb.toTiddler(data, config.defaultCustomFields['server.host']);
				var space = tiddlyspace.resolveSpaceName(tiddler.fields["server.bag"]);
				if(space != tiddlyspace.currentSpace.name) { // ALLOW SAVING IN SAME SPACE (TODO: what is correct behaviour here)
					delete tiddler.fields["server.bag"];
					delete tiddler.fields["server.permissions"];
					delete tiddler.fields["server.page.revision"];
				}
				tiddler.modified = new Date();
				tiddler.fields["server.workspace"] = config.defaultCustomFields["server.workspace"];
				tiddler.fields["_original_tiddler_title"] = data.title;
				tiddler.fields["_original_tiddler_source"] = data.bag;
				tiddler.fields["_original_tiddler_revision"] = data.revision;
				tiddler = morph ? morph(tiddler) : tiddler;
				store.addTiddler(tiddler);
				story.displayTiddler(null,tiddler, DEFAULT_EDIT_TEMPLATE);
				window.location.hash = "";
			}
		});
	}
};

var toolbar = store.getTiddlerText("ToolbarCommands");
if(toolbar.indexOf("flickTiddler") === -1) {
	var slice = store.getTiddlerText("ToolbarCommands::ViewToolbar");
	var newslice = slice.replace("> ", "> flickTiddler pushTiddler ");
	var tid = store.getTiddler("ToolbarCommands");
	tid.text = toolbar.replace(slice, newslice);
	store.addTiddler(tid);
}

})(jQuery);
//}}}
Having a number of issues with Internet Explorer v8 and v9.
Here's one involving a Moodle quiz. Question 16 looked like this in IE 9:

[img[http://legacy.earlham.edu/~markp/moodledocs/graphics/seely-quiz-Q16.png]]

No question, no form for essay entry and no [Submit] button either. Apparently it looked fine in Firefox.
Upon editing the question and displaying the HTML source, the reason becomes clear:

[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/seely-quiz-Q16-htmlsource.png]]

There's a huge chuck of MS Word crud there and you can see the {{{<!--[endif]-->}}} statement. Removing this crud manually and then [Update] makes the problem go away. The question, tet entry box and [Submit] buttons are now visible and usable.

[img(80%,auto)[http://legacy.earlham.edu/~markp/moodledocs/graphics/seely-quiz-Q16-fixed.png]]

!!How to prevent this happening again
When pasting in text from //Microsoft Word// into an edit box click the {Paste from Word} button [img[http://legacy.earlham.edu/~markp/moodledocs/graphics/paste-from-word2.png]] paste the text into the popup window and then Save. This will remove all the obnoxious styling crud.
Мудл Собор
! Layout
!! The Basics
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[WindowTitle]]: By default, it contains {{{SiteTitle - SiteSubtitle}}}
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlySpace is opened
* Many features of TiddlySpace are accessed via the backstage bar located at the top of the page. You can toggle it on or off using the button in the top right corner of the screen.

!! The ~SiteIcon
* Upload a SiteIcon. A SiteIcon gives your space an identity to make it recognisable to others. A good site icon will be square and at least 48*48 pixels size.
** Hint: This picture should be small in file size, since it may slow down your browser.
<<binaryUploadPublic title:SiteIcon>>

!! The Layout
The layout tiddlers mentioned below, will contain some hidden text covered by {{{/% ... %/}}}. It contains informations, that you may find usefull, tweaking this theme. You may delete the stuff, or you may keep it as some hints. 

|WindowTitle|>|>||
|>|>| SiteTitle| [[sidebarSearch]] |
|>|>| SiteSubtitle||
|>|>|TopMenu edit: "new tiddler  new journal ◄ ►" ... SideBarOptions  »  OptionsPanel||
|MainMenu| DefaultTiddlers| (hidden content) CSidebarTools||
|~| ToolbarCommands| CSideBarTabs||
|~|| SideBarTabs||
|||||
|ColorPalette | FontPalette|||

* The actual theme is set in [[zzConfig]] tiddler
* If you want to know how the MainMenu works have a look at http://apm-plugins.tiddlyspot.com/#StylingPackage.
** If you don't need this mechanism at the moment, overwrite it.
** You will remember it, when automatic TopMenu and MainMenu with drag and drop sorting would be nice ;)

* Have a look at the actual ~ColorPalette with ViewColorPalette

* If you don't like the color scheme click <<RandomColorPaletteButton>> to generate a new random color scheme.
|''Name:''|[[NeUIemTheme]]|
|''Description:''|Your description here!|
|''Generator:''|[[TW FreeStyle|http://FreeStyle.tiddlyspace.com]]|
|''Gen.Description:''|Automatically generated from: tsNeUIemProject|
|''PageTemplate:''|##PageTemplate|
|''ViewTemplate:''|##ViewTemplate|
|''EditTemplate:''|##EditTemplate|
|''RevisionTemplate:''|NeUIemTheme##RevisionTemplate|
|''StyleSheet:''|##StyleSheet|
|''UsedClones:''|StyleSheetHeaderMp StyleSheetMenuBarMp StyleSheetSideBarMp StyleSheetTiddlerMp StyleSheetTiddlySpaceMp StyleSheet_neui-em EmasticSystem NeuiemZzConfig:zzConfig TerminateStyleSheet:StyleSheet CSideBarTabs CSidebarOptions CSidebarTools NeuiemSidebarTools:SidebarTools TopMenu SideBarOptions OptionsPanel [[sidebarSearch]] FontPalette ToolbarCommands GettingStarted NeUIemTheme01 NeUIemTheme02 NeUIemTheme03 NeUIemTheme04 |

!Important
If any of the obove clones is missing, the theme may not work.

!PageTemplate
<!--{{{-->


<!-- tsRowTitle -->
<div class='dp100 header clearfix'>
	<!-- tsColTitle -->
	<div class='dp80'>
		<!-- BoxTsHeader -->		
		<div class='box headerForeground'>
			<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
			<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
		</div>
	</div>

	<!-- tsColSearch -->
	<div class='dp20'>
		<!-- tsBoxGoto -->		
		<div id='sidebarSearch' class='box searchForeground'>
			<div refresh='content' tiddler='sidebarSearch'></div>
		</div>
	</div>
</div>	<!-- row -->


<!-- tsRowMenuBar -->
<div id='menuBar' class='dp100 clearfix'>
	<!-- tsColTopMenue -->
	<div class='dp60'>
		<!-- tsBoxTopMenue -->		
		<!-- horizontal TopMenu -->
		<div class='box topMenu clearfix' refresh='content' tiddler='TopMenu'></div>
	</div>

	<!-- tsColThemeSwitcher -->
	<div class='dp40'>
		<!-- tsBoxThemeSwitcher -->		
		<div id='sidebarOptions' class='dpfr' refresh='content' tiddler='SideBarOptions'></div>
	</div>
</div>	<!-- row -->


<!-- tsRowBody -->
<div class='dp100 clearfix row'>
	<!-- tsColSidebar -->
	<div id='sidebar' class='dp15 dpfr' style='width:15%; position:relative;'>
		<!-- tsBoxSidebarTools -->		
		<div id='sidebarTools' class='box' refresh='content' force='true' tiddler='CSidebarTools'></div>

		<!-- tsBoxSidebarTabs -->		
		<div id='sidebarTabs' class='box' refresh='content' force='true' tiddler='CSideBarTabs'></div>
	</div>

	<!-- tsColMainMenu -->
	<div class='dp15'>
		<!-- tsBoxMainMenu -->		
		<!-- original MainMenu menu -->
		<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
	</div>

	<!-- tsColDisplayArea -->
	<div id='displayArea' class='dp70'>
		<!-- tsBoxMessageArea -->		
		<div id='messageArea' class='box'></div>

		<!-- tsBoxBreadCrumbs -->		
		<div id='breadCrumbs' class='breadCrumbs box'></div>

		<!-- tsBoxTiddlersBar -->		
		<div id='tiddlersBar' refresh='none' ondblclick='config.macros.tiddlersBar.onTiddlersBarAction(event)'></div>

		<!-- tsBoxTiddlerDisplay -->		
		<div id='tiddlerDisplay' class='box'></div>
	</div>
</div>	<!-- row -->

<!--}}}-->
!ViewTemplate
<!--{{{-->


<!-- tsVT_NEUIem -->
<div class='dp100 clearfix'>
	<!-- tsVT_toolbar -->
	<div class='dp100'>
		<!-- tsBoxVT_FollowPlaceHolder -->		
		<div class='followPlaceHolder' macro='linkedTiddlers'>
			<span macro="view title replyLink"></span>
		</div>

		<!-- tsBoxVT_Toolbar -->		
		<div class='box toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]] icons:yes'></div>
	</div>

	<!-- tsVT_leftCol -->
	<div class='dp10'>
		<!-- tsBoxVT_SiteIcon -->		
		<div class='box spaceSiteIcon' macro='tiddlerOrigin label:yes height:48 width:48'></div>

		<!-- BoxVT_Calender -->		
		<div class='box calendar' macro='viewRevisions page:5'>
			<div class='month' macro='view modified date mmm'></div>
			<div class='date' macro='view modified date 0DD'></div>
			<!-- div class='time' macro='view modified date 0hh:0mm'></div  -->
		</div>

		<!-- BoxVTts_tagged -->		
		<div class='box tagged' macro='tags'></div>
		<div class='box' macro='tiddler CTagBox'></div>
	</div>

	<!-- tsViewTemplate -->
	<div class='dp90'>
		<!-- tsBox_ModifierIcon -->		
		<div class='box modifierIcon dpfr'
			macro='view modifier SiteIcon label:yes height:30 width:30 labelPrefix:"modified by "'>
		</div>

		<!-- tsBoxVT_Title -->		
		<div class='titleContainer'>
			<div class='box title' macro='view title'></div>
		</div>

		<!-- tsBox_concertina -->		
		<div class='box concertina clear'></div>

		<!-- tsBoxVT_Body -->		
		<div class='box content'>
			<div class='viewer' macro='view text wikified'></div>
		</div>

		<!-- tsBoxVT_TagglyTaggingFooter -->		
		<div class="box tagglyTagging" macro="tagglyTagging"></div>

		<!-- tsBox_StoryGlue -->		
		<div class='box storyGlue' macro='storyGlue fsStory ACTIVESTORY'></div>
	</div>
</div>	<!-- row -->

<!--}}}-->
!EditTemplate
<!--{{{-->


<!-- tsET_NEUIem -->
<div class='dp100 clearfix'>
	<!-- tsEditTemplate -->
	<div class='dp100'>
		<!-- BoxET_tsEditToolbar -->		
		<div class='box dpfr toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]] icons:yes'></div>

		<!-- BoxET_tsSetPrivate -->		
		<div class="box dpfr privacyEdit" macro='setPrivacy label:no interactive:yes'></div>
		<div class='box dpfr editSpaceSiteIcon'	macro='tiddlerOrigin height:25 width:25 label:no interactive:no'></div>

		<!-- BoxET_tsTitle -->		
		<div class='box title' macro='view title'></div>

		<!-- BoxET_tsEditTitle -->		
		<div class='box editor' macro='edit title'></div>
		<div macro='annotations'></div>

		<!-- BoxET_tsEditBody -->		
		<div class='box editor' macro='edit text'></div>

		<!-- BoxET_tsTagging -->		
		<div class='box save editor' macro='edit tags'></div>

		<!-- BoxET_tsEditFooter -->		
		<div class='box editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
	</div>
</div>	<!-- row -->

<!--}}}-->
!RevisionTemplate
<!--{{{-->


<!-- tsRT_NEUIem -->
<div macro='slideRevision'></div>
<div class='dp100 clearfix'>
	<!-- tsRT_toolbar -->
	<div class='dp100'>
		<!-- tsBoxVT_FollowPlaceHolder -->		
		<div class='followPlaceHolder' macro='followTiddlers'>
			<span macro="view title replyLink"></span>
		</div>

		<!-- tsBoxRT_Toolbar -->		
		<div class='box toolbar' macro='toolbar [[ToolbarCommands::RevisionToolbar]] icons:yes'></div>
	</div>

	<!-- tsVT_leftCol -->
	<div class='dp10'>
		<!-- tsBoxVT_SiteIcon -->		
		<div class='box spaceSiteIcon' macro='tiddlerOrigin label:yes height:48 width:48'></div>

		<!-- BoxVT_Calender -->		
		<div class='box calendar' macro='viewRevisions page:5'>
			<div class='month' macro='view modified date mmm'></div>
			<div class='date' macro='view modified date 0DD'></div>
			<!-- div class='time' macro='view modified date 0hh:0mm'></div  -->
		</div>

		<!-- BoxVTts_tagged -->		
		<div class='box tagged' macro='tags'></div>
		<div class='box' macro='tiddler CTagBox'></div>
	</div>

	<!-- tsViewTemplate -->
	<div class='dp90'>
		<!-- tsBox_ModifierIcon -->		
		<div class='box modifierIcon dpfr'
			macro='view modifier SiteIcon label:yes height:30 width:30 labelPrefix:"modified by "'>
		</div>

		<!-- tsBoxVT_Title -->		
		<div class='titleContainer'>
			<div class='box title' macro='view title'></div>
		</div>

		<!-- tsBox_concertina -->		
		<div class='box concertina clear'></div>

		<!-- tsBoxVT_Body -->		
		<div class='box content'>
			<div class='viewer' macro='view text wikified'></div>
		</div>

		<!-- tsBoxVT_TagglyTaggingFooter -->		
		<div class="box tagglyTagging" macro="tagglyTagging"></div>

		<!-- tsBox_StoryGlue -->		
		<div class='box storyGlue' macro='storyGlue fsStory ACTIVESTORY'></div>
	</div>
</div>	<!-- row -->

<!--}}}-->
!StyleSheet
/*{{{*/
Version: 1.0 - 2010.08.12

/*****************************************************/
/*-- some simple rules to change the global layout --*/
/*-- margin should not be uses for row, col, box   --*/
/*-- margin is used to adjust special elements     --*/
/*-- The layout doesn't allow padding-left/right or margin-left/right ! for rows and cols --*/
.row {
	margin: 0;
	padding: 0;
	margin-top: 0.5em;
}

/*-- The layout doesn't allow padding-left/right or margin-left/right ! for rows and cols --*/
/*-- col is not assigned to layout yet --*/
.col {
	margin: 0;
	padding: 0;
}

/*-- if you want more space between 2 columns use box 2nd and 4th parameter. --*/
/*-- boxes must have padding-bottom: 0; !! --*/
.box {
	margin: 0;
	padding: 0.5em 0.5em 0 0.5em;
}

/* general stuff */
.noBullets ul {
	list-style:none;
}

.noNumbers ol {
	list-style:none;
}

.noBr br {
	display: none;
}

/* prefer monospace for editing */
.editor textarea, .editor input {
	font-size: 90%; 
	font-family: [[FontPalette::twEditor]], 'Courier New', monospace; 
	background-color:[[ColorPalette::TertiaryPale]];
}

/*-- emastic System --*/
[[EmasticSystem]]

/*-- theme specific stuff --*/
[[StyleSheet_neui-em]]

/* 2012.01.04 inserted */
.notLoaded {
	background-image: URL('loading.gif');
	background-repeat:no-repeat;
	background-position:center; 
}

/*-- call the standard StyleSheet --*/
[[StyleSheet]]

/*}}}*/
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#CC9900" offset="0"/>
   <stop id="stop2" stop-color="#E8D18B" offset="0.66462"/>
   <stop id="stop3" stop-color="#CC9900" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" transform="matrix(0.979566, -0.500632, 0.735105, 0.667118, -41.7482, 33.1452)" stroke="#4d4d4d" stroke-linecap="butt" stroke-width="0.80000001px" fill="none">
   <path id="path3696" d="m37.954,54.163-4.5532,5.7819-0.03139-4.2335-7.7522,0,0-2.605,7.7522,0,0-3.4444,4.5846,4.501z"/>
   <path id="path3719" d="m17.41,60.825,4.4254-5.6117,0.03139,4.2335,7.7522,0,0,2.605-7.7522,0,0,3.4444-4.4568-4.6712z"/>
  </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
!!1. Setting up the Gradebook
!!! Adding or editing a grade Category
Gradebook : Categories and Items - [Add Category]
* Simple weighted mean of grades aggregation will weight every item by what you grade it out of
* Category Total > Maximum grade. This is what all the grade items in the Category are averaged out of.
* Make sure that all the Categories add up to 100
!!!!Hidden category:
* Grade type is 'None' -- so no grades will count
* Hidden - check -- so items in this category are hidden from students
!!!Add Grade Item
# Hit [Add grade item]
# give it a name , eg 'Paper 1'
# you can grade all items out of 100 if you like since they will all be weighted.
** to grade alphabetic, choose grade type > Scale and then Scale > Accurate alphabetic
# ''Important''. Allocate grade item to parent category with Parent Category > Grade category -> pull down to choose. You can reorder if you make a mistake by clicking Edit in Categories and Items and choosing the Up/down arrow icon.
!!!Current configuration:
|!Category|!# Grade items|!Aggregation|!Category total (%)|
|Attendance & Participation| 4|Simple weighted mean| 20|
| Papers | 0|Simple weighted mean| 40|
| Project | 0|Simple weighted mean| 40|
| Hidden | 0| - | no grade|
| ''Total'' |>|sum of all non hidden category totals| 100|
!!2. Workflow
# Decide major Categories and their % contribution to the Total (you can change this at any point but once it's published in the syllabus and made public it's concrete). Edit the Gradebook : Categories and Items accordingly.
# You're going to be manually entering grades into the Gradebook. (Make sure you have a 'Grade Item' for each graded thing that the students do.)
## Open View > ''LAE Grader Report''
## click [Turn editing on]
## enter grade into appropriate box
## continue until all grades are entered for that item
## hit [Update]
# Create Assignment activities in the course outline ([Turn editing on] and in the appropriate week [Add Activity > Assignment]). You can display the Course Outline with all the Assignments together in a single Topic (Admin > Settings > course format : topics)
** Take a look at the ''[[Assignment docs|https://epress.earlham.edu/tsardocs/category/moodle-2/assignment/]]'' which have a lot of useful information about configuration and workflow.
** You'll be using the upload file type but not giving a grade within the assignment. So be careful to choose Grade > Grade category -> Hidden so that students don't see a confusing empty grade field.
# Students will upload, revise and re-upload into the appropriate Assignment activity and when the due date has passed you can manually enter the grade into the associated grade item.
# Similarly with Attendance. Having set it up ([[instructions|https://epress.earlham.edu/tsardocs/2013/08/01/attendance/]]) you can easily track class attendance and then manually enter summary grades into the gradebook as before. If you want to track participation in a similar way here's [[Assessing class participation|https://epress.earlham.edu/tsardocs/2014/01/22/assessing-class-participation/]]
/***
|''Name''|TiddlySpaceFollowingSuggestions|
|''Version''|0.2.5dev|
|''Description''|Provides a following macro|
|''Author''|Jon Robson|
|''Requires''|TiddlySpaceFollowingPlugin|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage

!Code
***/
//{{{
(function($) {

var tweb = config.extensions.tiddlyweb;
var tiddlyspace = config.extensions.tiddlyspace;
var followMacro = config.macros.followTiddlers;

var followSuggestions = config.macros.followSuggestions = {
	cache: {},
	handler: function(place, macroName, params) {
		// to do - limit results
		place = $('<div class="suggestions" />').appendTo(place)[0];
		var currentSpace = tiddlyspace.currentSpace.name;
		var user = params[0] || currentSpace;
		var pleaseWait = $("<div class='loading' />").text("please wait..").appendTo(place);
		tweb.getUserInfo(function(activeUser) {
			if(activeUser.name != tiddlyspace.currentSpace.name) {
				pleaseWait.hide();
				return;
			}
			followMacro.getFollowers(function(users) {
				// suggestions are followers of people that you follow that you don't follow
				var bags = followMacro._getFollowerBags(users);
				var _bags = [];
				for(var i = 0; i < bags.length; i++) {
					_bags.push("bag:%0".format([bags[i]]));
				}
				var bagString = _bags.join(" OR ");
				ajaxReq({
					beforeSend: followMacro.beforeSend,
					url: "/search?q=(%0)&select=title:!%1&select=title:!@%1".format([bagString, activeUser.name]),
					dataType: "json",
					success: function(tiddlers) {
						pleaseWait.hide();
						var suggestions = [];
						for(var i = 0; i < tiddlers.length; i++) {
							var tiddler = tiddlers[i];
							if(tiddler.tags.contains("follow")) {
								var title = tiddler.title;
								if(title.indexOf("@") === 0) {
									title = title.substr(1);
								}
								if(!users.contains(title)) {
									suggestions.pushUnique(title);
								}
							}
						}
						$(place).append("<div>suggestions:</div>");
						var suggestionArea = $("<div class='suggestionArea' />").appendTo(place)[0];
						var id = "more_%0".format([Math.random()]);
						var more = $("<div class='moreButton' />").text("more...").appendTo(place).attr("id", id);
						followSuggestions.cache[id] = suggestions;
						var limit = suggestions.length;
						more.click(function(ev) {
							var suggestions = config.macros.followSuggestions.cache[id];
							var newSuggestions = followSuggestions.suggest(place, suggestions, limit);
							config.macros.followSuggestions.cache[id] = newSuggestions;
						});
						followSuggestions.suggest(place, suggestions, limit);
					
					}
				});
			
			}, user);
		});
	},
	randomize: function(a, b) {
		if(Math.random() < Math.random()) {
			return -1;
		} else {
			return 1;
		}
	},
	suggest: function(place, suggestions, limit) {
		var currentSpace = tiddlyspace.currentSpace.name;
		suggestions = suggestions.sort(followSuggestions.randomize);
		var suggestionsArea = $(".suggestionArea", place)[0];
		if(suggestions.length === 0) {
			$("<span />").text("no suggestions..").appendTo(suggestionsArea);
			return;
		}
		limit = limit < suggestions.length ? limit : suggestions.length;
		for(var j = 0; j < limit; j++) {
			var link = $("<span />").appendTo(suggestionsArea)[0];
			var title = suggestions[j];
			var newTiddler = '@%0 <<newTiddler title:"@%0" fields:"server.workspace:bags/%1_public" tag:follow label:"follow">>\n'.format([title, currentSpace]);
			wikify(newTiddler, link);
		}
		var newSuggestions = suggestions.slice(limit, suggestions.length);
		var more = $(".moreButton", place);
		if(newSuggestions.length == 0) {
			more.remove();
		}
		return newSuggestions;
	}
};
})(jQuery);
//}}}
/*{{{*/
/* make it print a little cleaner */
/* FireFox only prints one page. Google Chrome works. */

@media print {
	/* basic setting */
	#displayArea {	
		font:11px/120% Arial, serif;
		background-color: white !important;
		background-image: none !important;
		color:black;

		width: 95%;	
	}

	#sidebarSearch,
	.clear,
	.topMenu,
	.quickopentag a.button, 
	.miniTag,
	.noPrint,
	.tagglyTagging {
		display: none ! important;
	}

	/* not sure if we need all the importants */
	.tiddler {
		-moz-box-shadow: none;
		-web-box-shadow: none;
		boder:none ! important;
		border-style: none ! important;
		margin:0px ! important;
		padding:0px ! important;
		padding-bottom:2em ! important;
		display:inline;
	}

	.headerShadow {
		visibility: hidden ! important;
	}

	.tagglyTagged .quickopentag, .tagged .quickopentag {
	/*	border-style: none ! important; */
	}

	.siteIcon,
	.spaceSiteIcon {
		display: none ! important; 
	}
}
/*}}}*/
/%
!info
|Name|ToggleLeftSidebarEm|
|Source|http://hoster.peermore.com/recipes/TeamWork/tiddlers.wiki#ToggleLeftSidebarEm|
|Version|0.1.0|
|Author|Mario Pietsch|
|Derived from:|http://www.tiddlytools.com/#ToggleLeftSidebar|
|License|http://creativecommons.org/licenses/by-nc-sa/3.0/at/|
|~CoreVersion|2.6|
|Type|transclusion|
|Description|show/hide left sidebar (MainMenu) for FreeStyle Themes. Works only with EmasticSystem|
Usage
<<<
{{{
<<tiddler ToggleLeftSidebarEm>>
<<tiddler ToggleLeftSidebarEm with: label tooltip>>
<<tiddler ToggleLeftSidebarEm with: {{config.options.chkShowLeftSidebar?'◄':'►'}}>>
}}}
Try it: <<tiddler ToggleLeftSidebarEm##show
	with: {{config.options.chkShowLeftSidebar?'◄':'►'}}>>
<<<
Configuration:
<<<
{{{
config.options.chkShowLeftSidebar (true)
config.options.txtToggleLeftSideBarLabelShow (►)
config.options.txtToggleLeftSideBarLabelHide (◄)
}}}
<<<
!end
!show
<<tiddler {{
	var co=config.options;
	if (co.chkShowLeftSidebar===undefined) co.chkShowLeftSidebar=true;

	getDP = function(name) {
		var width = undefined;
		var myregexp = /dp([\d]{1,3})/;
		var elem = jQuery(name);
		var text = elem.attr('class');

		var match = myregexp.exec(text);
		if (match != null) {
			width = match[1];
		} else {
			elem = jQuery(name).parent();
			text = elem.attr('class');
			match = myregexp.exec(text);
			if (match != null) {
				width = match[1]
			}
			else elem = undefined;
		}
		return {'width': width, 'elem': elem};
	}; // end function

	setDP = function(cmd, elem, target) {
		if (!elem || !target) return alert('elem or target undefined!');
		var newWidth = 0;
		if (cmd === 'hide' && (elem.elem.css('display') != 'none')) {
			newWidth = parseInt(target.width) + parseInt(elem.width);
			jQuery(elem.elem).hide();
			jQuery(target.elem).removeClass('dp'+target.width);
			jQuery(target.elem).addClass('dp'+newWidth);
		}
	}; // end function

	var mm = getDP('#mainMenu');
	var da = getDP('#displayArea');
	var sb = getDP('#sidebar');

	var cmd = co.chkShowLeftSidebar?'show':'hide';
	setDP(cmd, mm, da);

'';}}>><html><nowiki><a href='javascript:;' title="$2"
onmouseover="
	this.href='javascript:void(eval(decodeURIComponent(%22(function(){try{('
	+encodeURIComponent(encodeURIComponent(this.onclick))
	+')()}catch(e){alert(e.description?e.description:e.toString())}})()%22)))';"
onclick="
	var co=config.options;
	var opt='chkShowLeftSidebar';
	var show=co[opt]=!co[opt];

	getDP = function(name) {
		var width = undefined;
		var myregexp = /dp([\d]{1,3})/;
		var elem = jQuery(name);
		var text = elem.attr('class');

		var match = myregexp.exec(text);
		if (match != null) {
			width = match[1];
		} else {
			elem = jQuery(name).parent();
			text = elem.attr('class');
			match = myregexp.exec(text);
			if (match != null) {
				width = match[1]
			}
			else elem = undefined;
		}
		return {'width': width, 'elem': elem};
	}; // end function

	setDP = function(cmd, elem, target) {
		if (!elem || !target) return alert('elem or target undefined!');
		var newWidth = 0;
		if (cmd === 'hide') {
			newWidth = parseInt(target.width) + parseInt(elem.width);
			jQuery(elem.elem).hide();
			jQuery(target.elem).removeClass('dp'+target.width);
			jQuery(target.elem).addClass('dp'+newWidth);
		}
		else if (cmd === 'show') {
			newWidth = parseInt(target.width) - parseInt(elem.width);
			jQuery(elem.elem).show();
			jQuery(target.elem).removeClass('dp'+target.width);
			jQuery(target.elem).addClass('dp'+newWidth);			
		}
	}; // end function

	var mm = getDP('#mainMenu');
	var da = getDP('#displayArea');
	var sb = getDP('#sidebar');

	var cmd = co.chkShowLeftSidebar?'show':'hide';
	setDP(cmd, mm, da);

	saveOptionCookie(opt);
	var labelShow=co.txtToggleLeftSideBarLabelShow||'&#x25BA;';
	var labelHide=co.txtToggleLeftSideBarLabelHide||'&#x25C4;';
	if (this.innerHTML==labelShow||this.innerHTML==labelHide) 
		this.innerHTML=show?labelHide:labelShow;
	this.title=(show?'hide':'show')+' left sidebar';
	var sm=document.getElementById('storyMenu');
	if (sm) config.refreshers.content(sm);
	return false;
">$1</a></html>
!end
%/<<tiddler {{
	var src='ToggleLeftSidebarEm';
	src+(tiddler&&tiddler.title==src?'##info':'##show');
}} with: {{
	var co=config.options;
	var labelShow=co.txtToggleLeftSideBarLabelShow||'&#x25BA;';
	var labelHide=co.txtToggleLeftSideBarLabelHide||'&#x25C4;';
	'$1'!='$'+'1'?'$1':(co.chkShowLeftSidebar?labelHide:labelShow);
}} {{
	var tip=(config.options.chkShowLeftSidebar?'hide':'show')+' left sidebar';
	'$2'!='$'+'2'?'$2':tip;
}}>>
chkPrivateMode: true
chkInsertTabs: true
/***
|''Name''|TiddlySpaceToolbar|
|''Description''|augments tiddler toolbar commands with SVG icons|
|''Author''|Osmosoft|
|''Version''|0.6.6|
|''Status''|@@beta@@|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/TiddlySpaceToolbar.js|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.5.0|
|''Requires''|ImageMacroPlugin|
|''Keywords''|toolbar icons SVG|
!Description
replaces tiddler toolbar commands with SVG icons if available
!Notes
requires [[ImageMacroPlugin|http://svn.tiddlywiki.org/Trunk/contributors/JonRobson/plugins/ImageMacroPlugin/plugins/ImageMacroPlugin.tid]]

SVG icons are drawn from tiddlers titled {{{<command>.svg}}}
In readonly mode a tiddler called {{{<command>ReadOnly.svg}}} will be used if it exists.
!TODO
* rename (IconToolbarPlugin?)
* support more than one more popup menu in the toolbar.
!Code
***/
//{{{
(function($) {

if(!config.macros.image) {
	throw "Missing dependency: ImageMacroPlugin";
}

var macro = config.macros.toolbar;

macro.icons = {
	cloneTiddler: "editTiddler"
};

var _handler = macro.handler;
macro.handler = function(place, macroName, params, wikifier,
		paramString, tiddler) {
	var toolbar = $(place);
	toolbar.attr({
		refresh: "macro",
		macroName: macroName
	}).data("args", arguments);
	var status = _handler.apply(this, arguments);
	if(tiddler.isReadOnly()) {
		toolbar.addClass("toolbarReadOnly");
	} else {
		toolbar.removeClass("toolbarReadOnly");
	}
	var parsedParams = paramString.parseParams("name")[0];
	if(parsedParams.icons && parsedParams.icons == "yes") {
		this.augmentCommandButtons(place);
	}
	if(parsedParams.more && parsedParams.more == "popup") {
		// note we must override the onclick event like in createTiddlyButton
		// otherwise the click event is the popup AND the slider
		$(".moreCommand", place).each(function(i, el) {
			el.onclick = macro.onClickMorePopUp;
		});
		// buttons that are after a less command should not be in more menu.
		$(".lessCommand ~ .button", place).appendTo(place);
		$(".lessCommand", place).remove();
	}
	return status;
};

macro.refresh = function(place, params) {
	var args = $(place).empty().data("args");
	this.handler.apply(this, args);
};

var imageMacro = config.macros.image;
macro.augmentCommandButtons = function(toolbar) {
	$(".button", toolbar).each(function(i, el) {
		var cmd = $(el).attr("commandname");
		cmd = cmd ? cmd : "moreCommand"; // XXX: special-casing of moreCommand due to ticket #1234
		var icon = store.tiddlerExists(cmd) ? cmd : macro.icons[cmd];
		var text = $(el).text();
		if(readOnly) {
			var readOnlyAlternative = "%0ReadOnly".format([icon]);
			if(store.tiddlerExists(readOnlyAlternative)) {
				icon = readOnlyAlternative;
			}
		}
		if(store.tiddlerExists(icon)) {
			$(el).css({display: "inline-block"}).empty();
			imageMacro.renderImage(el, icon, { alt: text });
		}
	});
};

// provide onClickMore to provide extra commands in a popup
macro.onClickMorePopUp = function(ev) {
	ev = ev || window.event;
	var sibling = this.nextSibling;
	if(sibling) {
		var commands = sibling.childNodes;
		var popup = Popup.create(this);
		$(popup).addClass("taggedTiddlerList");
		for(var i = 0; i < commands.length; i++) {
			var li = createTiddlyElement(popup, "li", null);
			var oldCommand = commands[i];
			var command = oldCommand.cloneNode(true);
			command.onclick = oldCommand.onclick;
			li.appendChild(command);
		}
		Popup.show();
	}
	ev.cancelBubble = true;
	if(ev.stopPropagation) {
		ev.stopPropagation();
	}
	return false;
};

})(jQuery);
//}}}
From [[M2.2 front page backup #2]] I entered the tracker item : [[Front page restore not operational|http://tracker.moodle.org/browse/MDL-31500]]. Comment:
<<<
Itamar Tzadok added a comment - 10/Jun/12 10:01 PM
I suppose the design challenge for which restore is prevented on front page is that restore restores modules to their designated section which could be > 1, but the front page can handle only one section (on top of the default section that is handled by the main menu block).
I have a module that can restore into itself and in that process ignores the section (because the "restored" activity already exists where it is restored). I managed to let it be restored on the front page by commenting out the condition in backup\util\helper\restore_prechecks_helper.class.php – line 96 (222+)
{{{if ($controller->get_courseid() == SITEID) { //$errors[] = get_string('errorrestorefrontpage', 'backup'); } }}}
I haven't checked but this should probably work for restoring any activity to the front page where the original section of the activity is 0 or 1. This is not a real solution but for the time being may be useful for transferring activities from a dev/sandbox machine to the production frontpage or other similar scenarios.
<<<
+++[code]
{{{less -N backup/util/helper/restore_prechecks_helper.class.php}}}
{{{
     93         // Error if restoring over frontpage
     94         // TODO: Review the whole restore process in order to transform this into one warning (see 1.9)
     95         if ($controller->get_courseid() == SITEID) {
     96             $errors[] = get_string('errorrestorefrontpage', 'backup');
     97         }
}}}
===
Also:
{{{
pwd
/Applications/MAMP/htdocs/CLAMP-M2/backup/util/helper
ec1081:helper markp$ diff restore_prechecks_helper.class.php /Applications/MAMP/htdocs/moodle/backup/util/helper/restore_prechecks_helper.class.php
}}}
returns nothing so the issue has not been tackled for v2.3 either.
/***
|''Name''|TiddlySpaceSearcher|
|''Version''|0.2.5|
|''Requires''|TiddlySpaceConfig TiddlySpaceFollowingPlugin|
***/
//{{{
(function($) {
var tiddlyspace = config.extensions.tiddlyspace;
var tsScan = config.macros.tsScan;

config.shadowTiddlers.SearchTemplate = "<<view server.bag SiteIcon label:no width:24 height:24 preserveAspectRatio:yes>> <<view server.bag spaceLink title external:no>> in space <<view server.bag spaceLink>>";
config.shadowTiddlers.StyleSheetSearch = [".resultsArea .siteIcon { display: inline; }",
	".searchForm {text-align: left;}"].join("\n");
store.addNotification("StyleSheetSearch", refreshStyles);

var search = config.macros.tsSearch = {
	locale: {
		advanced: "Advanced Options",
		header: "Search",
		resultsHeader: "Results (%0)",
		find: "find",
		noResults: "No tiddlers matched your search query",
		query: "QUERY: ",
		error: "please provide a search query or a tag, modifier or title!",
		titleAdvanced: "where the title is",
		modifierAdvanced: "where the last modifier is",
		spaceAdvanced: "only in the space: ",
		notspaceAdvanced: "but not in the spaces: ",
		tagsAdvanced: "with the tags: "
	},
	andConstructor: function(container, label, fieldname, negationMode) {
		var tags = $("<div />").appendTo(container);
		$('<span />').text(label).appendTo(tags);
		var id = "area" + Math.random();
		container = $("<span />").attr("id", id).appendTo(tags)[0];
		function add(container) {
			var el = $('<input type="text" />').attr("field", fieldname).appendTo(container);
			if(negationMode) {
				el.attr("negation", "true");
			}
		}
		add(container);
		var el = $("<button />").text("AND").click(function(ev) {
			add($(ev.target).data("container"));
			ev.preventDefault();
		}).appendTo(tags);
		$(el).data("container", container);
	},
	fieldConstructor: function(container, label, field) {
		container = $("<div />").appendTo(container)[0];
		$("<span />").text(label).appendTo(container);
		$("<input />").attr("text", "input").attr("field", field).appendTo(container);
	},
	advancedOptions: function(form) {
		var locale = search.locale;
		var container = $("<div />").addClass("tsAdvancedOptions").appendTo(form)[0];
		$("<h2/ >").text(search.locale.advanced).appendTo(container);
		$("<div />").addClass("separator").appendTo(container);
		search.fieldConstructor(container, locale.titleAdvanced, "title");
		search.fieldConstructor(container, locale.modifierAdvanced, "modifier");
		search.fieldConstructor(container, locale.spaceAdvanced, "space");
		search.andConstructor(container, locale.notspaceAdvanced, "space", true);
		search.andConstructor(container, locale.tagsAdvanced, "tag");
	},
	constructSearchQuery: function(form) {
		var data = [], select = [];
		var query = $("[name=q]", form).val();
		if(query) {
			data.push("q=%0".format(query));
		}

		// add tags, fields etc..
		$("[field]", form).each(function(i, el) {
			var val = $(el).val();
			var name = $(el).attr("field");
			var negate = $(el).attr("negation") == "true";
			if(val && name) {
				val = encodeURIComponent(val);
				val = negate ? "!" + val : val;
				if(name == "space") {
					val += "_public";
					name = "bag";
				}
				if(negate) {
					select.push("select=%0:%1".format(name,val));
				} else {
					var prefix = data.length === 0 ? "q=" : "";
					data.push('%0%1:"%2"'.format(prefix, name, val));
				}
			}
		});
		var dataString = data.join(" ");
		if(dataString.length === 0 && !query) {
			return false;
		}
		var selectStatement = select.join("&");
		if(dataString.length > 0 && selectStatement.length > 0) {
			dataString += "&";
		}
		dataString += selectStatement;
		return "/search?%0".format(dataString);
	},
	constructForm: function(place) {
		var locale = search.locale;
		$("<h1 />").text(locale.header).appendTo(place);
		var form = $("<form />").appendTo(place)[0];
		$('<input type="text" name="q" />').appendTo(form);
		$('<input type="submit" />').val(locale.find).appendTo(form);
		search.advancedOptions(form);
		var query = $('<h2 class="query"/>').appendTo(place)[0];
		var results = $("<div />").appendTo(place).addClass("resultsArea")[0];
		var lookup = function(url) {
			if(!url) {
				results.empty().addClass("error").text(locale.error);
				return;
			}
			config.extensions.tiddlyweb.getStatus(function(status) {
				$(query).text(locale.query);
				var href = status.server_host.url + url;
				$("<a />").attr("href", href).text(href).appendTo(query);
				tsScan.scan(results, { url: url, emptyMessage: search.locale.noResults, cache: true,
					template: "SearchTemplate", sort: "title", callback: function(tiddlers) {
						$("<h2 />").text(locale.resultsHeader.format(tiddlers.length)).prependTo(results);
					}
				});
			});
		};
		$(form).submit(function(ev) {
			ev.preventDefault();
			var url = search.constructSearchQuery(form);
			config.macros.tsSearch.lastSearch = url;
			lookup(url);
		});
		if(search.lastSearch) {
			lookup(search.lastSearch);
		}
		return form;
	},
	handler: function(place) {
		var container = $("<div />").addClass("searchForm").appendTo(place)[0];
		search.constructForm(container);
	}
};

})(jQuery);
//}}}
!Making Moodle work for you
This morning workshop is designed for new faculty and returning faculty who would like to enhance their expertise with IS Moodle. There will be coffee and goodies available throughout the morning to keep you going. This workshop will not attract a stipend.
;Where:
: Lilly Library Bibliographic Lab
;When:
:Friday Aug 17^^th^^ ''8:30am -- 12:30pm''
!!Topics covered
* Overview of Moodle
** Where to go for help
* Creating your first moodle course
* Making a variety of moodle resources (including how to use media)
* Managing your course as it progresses
* In depth Assignments and grading approaches
!!Signing up
Because of space limitations we have to limit this workshop to 12 participants. Please email me by Monday afternoon Aug 13th if you'd like to attend so that I can order sufficient victuals.
+++!![Participants]
* Mary Bogue
* Jose Ignacio
* Susan Furukawa
* Kate Leuschke Blinn
* Jane Pinzino
* Lajmar Anderson
* Rumya Putcha
* Miyuki Kamiya

=== 
Tar up moodle code without {{{.git}}}
{{{
 ~/public_html]$ tar -cvf ~/moo-archives/243-code.tgz --exclude .git moodle
}}}
To restart the Mysql server:
{{{
sudo /usr/local/etc/rc.d/mysql-server restart
}}}
or {{{stop}}} / {{{start}}}
To restart Apache:
{{{
sudo apachectl restart
}}}
Dump database:
{{{
$ mysqldump -u moodlebackup -p  clam233 >clmp233-db_12-6-postlmb.sql
<pwd : moodlebackup>
}}}
better:
{{{
mysqldump -u moodlebackup -p -c -Q -e clam233 >clmp233-db-01-04-postlmb.sql
}}}
Load database:
{{{
$ mysql -u clam233_user -p -D clam233 <clmp233-db-12-5-prelmb.sql
<pwd : user pwd >
}}}
To discover version of FreeBSD or whatever:
{{{
$ uname -a
FreeBSD naum.lly.earlham.edu 8.3-STABLE FreeBSD 8.3-STABLE #0: Wed Jul  4 10:19:01 EDT 2012     
root@plushstone.earlham.edu:/usr/obj/usr/src/sys/GENERIC  amd64
}}}
Musing over Bob Puffer's replies in this conversation : https://moodle.org/mod/forum/discuss.php?d=225511
!! Regular Categories and Items configuration

[img[http://legacy.earlham.edu/~markp/screens/moodle/gradebook-cats-items-basic.png]]

# Main course : Sum of grades
# Each category : Simple weighted mean 
** ''Category total'' = % of overall grade
!!Major Problem
The 'total' at the bottom is not a 'running' total which excludes non-graded items. Instead  merely sums all the Category totals but then displays out of 100 which is clearly misleading.

[img[http://legacy.earlham.edu/~markp/screens/moodle/gradebook-cats-items-basic-total.png]]

Here the last item, Exam, has yet to be graded so the course total is actually /85 = 88.05%

!Problem solved with LAEGrader
# In Categories and Items change overall aggreagtion to Simple weighted mean
# In Settings : LAE Grader Report set Accurate point totals to 'Show' [img[http://legacy.earlham.edu/~markp/screens/moodle/gradebook-cats-items-fixed-LAEGrader.png]]

Now look at the Total -- becomes a proper running total. Problem solved!

[img[http://legacy.earlham.edu/~markp/screens/moodle/gradebook-cats-items-fixed-LAEGrader-total.png]]
/***
|Name:|SelectThemePluginMP|
|Description:|Lets you easily switch theme and palette|
|Version:|1.0.1 ($Rev: 3646 $) MP 02|
|Date:|$Date: 2008-02-27 02:34:38 +1000 (Wed, 27 Feb 2008) $|
|OriginalSource:|http://mptw.tiddlyspot.com/#SelectThemePlugin|
|OriginalAuthor:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
|Author:|Mario Pietsch|

!Notes
* Borrows largely from ThemeSwitcherPlugin by Martin Budden http://www.martinswiki.com/#ThemeSwitcherPlugin
* Theme is cookie based. But set a default by setting config.options.txtTheme in MptwConfigPlugin (for example)
* Palette is not cookie based. It actually overwrites your ColorPalette tiddler when you select a palette, so beware. 

*MP Added the label to applyTheme macro.
*Made selectPalette tiddlySpace ready. 

!Usage
* {{{<<selectTheme>>}}} makes a dropdown selector
* {{{<<selectPalette>>}}} makes a dropdown selector
* {{{<<applyTheme>>}}} applies the current tiddler as a theme
* {{{<<applyPalette>>}}} applies the current tiddler as a palette
* {{{<<applyTheme TiddlerName>>}}} applies TiddlerName as a theme
* {{{<<applyPalette TiddlerName>>}}} applies TiddlerName as a palette

* {{{<<applyTheme TiddlerName label>>}}} applies TiddlerName as a theme and uses costumized button label
* {{{<<applyTheme {{tiddler.title}} label>>}}} applies actual tiddler as a theme and uses costumized button label
***/
//{{{

config.macros.selectTheme = {
	label: {
      		selectTheme:"select theme",
      		selectPalette:"select palette"
	},
	prompt: {
		selectTheme:"Select the current theme",
		selectPalette:"Select the current palette"
	},
	tags: {
		selectTheme:'systemTheme',
		selectPalette:'systemPalette'
	}
};

config.macros.selectTheme.handler = function(place,macroName)
{
	var btn = createTiddlyButton(place,this.label[macroName],this.prompt[macroName],this.onClick);
	// want to handle palettes and themes with same code. use mode attribute to distinguish
	btn.setAttribute('mode',macroName);
};

config.macros.selectTheme.onClick = function(ev)
{
	var e = ev ? ev : window.event;
	var popup = Popup.create(this);
	var mode = this.getAttribute('mode');
	var tiddlers = store.getTaggedTiddlers(config.macros.selectTheme.tags[mode]);
	// for default
	if (mode == "selectPalette") {
		var btn = createTiddlyButton(createTiddlyElement(popup,'li'),"(default)","default color palette",config.macros.selectTheme.onClickTheme);
		btn.setAttribute('theme',"(default)");
		btn.setAttribute('mode',mode);
	}
	for(var i=0; i<tiddlers.length; i++) {
		var t = tiddlers[i].title;
		var name = store.getTiddlerSlice(t,'Name');
		var desc = store.getTiddlerSlice(t,'Description');
		var btn = createTiddlyButton(createTiddlyElement(popup,'li'), name?name:t, desc?desc:config.macros.selectTheme.label['mode'], config.macros.selectTheme.onClickTheme);
		btn.setAttribute('theme',t);
		btn.setAttribute('mode',mode);
	}
	Popup.show();
	return stopEvent(e);
};

config.macros.selectTheme.onClickTheme = function(ev)
{
	var mode = this.getAttribute('mode');
	var theme = this.getAttribute('theme');
	if (mode == 'selectTheme')
		story.switchTheme(theme);
	else // selectPalette
		config.macros.selectTheme.updatePalette(theme);
	return false;
};

config.macros.selectTheme.updatePalette = function(title)
{
	var tiddlyspace = config.extensions.tiddlyspace;

	if (title != "") {
		if (title != "(default)") {
			var tiddler = store.getTiddler('ColorPalette');

			tiddler.fields["server.workspace"] = "bags/%0_private".format([tiddlyspace.currentSpace.name]);
			tiddler.fields["server.page.revision"] = "false";

		//	tiddler.fields["server.permissions"] = "read, write, create"; // no delete
			delete tiddler.fields["server.title"];
			delete tiddler.fields["server.etag"];
			// special handling for pseudo-shadow tiddlers
			if(tiddlyspace.coreBags.contains(tiddler.fields["server.bag"])) {
				tiddler.tags.remove("excludeLists");
			}
			store.saveTiddler("ColorPalette","ColorPalette", store.getTiddlerText(title),
				config.options.txtUserName,undefined,tiddler.tags, tiddler.fields);
		}
		refreshAll();
		if(config.options.chkAutoSave)
			saveChanges(true);
	}
};

config.macros.applyTheme = {
	label: "apply",
	prompt: "apply this theme or palette: " // i'm lazy
};

config.macros.applyTheme.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	var label = params[1] ? params[1] : this.label;
	var useTiddler = params[0] ? params[0] : tiddler.title;
	var btn = createTiddlyButton(place,label,this.prompt+useTiddler,config.macros.selectTheme.onClickTheme);
	btn.setAttribute('theme',useTiddler);
	btn.setAttribute('mode',macroName=="applyTheme"?"selectTheme":"selectPalette"); // a bit untidy here
}

config.macros.selectPalette = config.macros.selectTheme;
config.macros.applyPalette = config.macros.applyTheme;

config.macros.refreshAll = { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
	createTiddlyButton(place,"refresh","refresh layout and styles",function() { refreshAll(); });
}};

//}}}
I figured out a way to port [[Community Docs]] from 1.9 to the new Moodle2 system. It would be //really nice// to be able to search through pdfs. In the course of researching how this might work (surprisingly difficult) I came across [[Apache Solr|http://lucene.apache.org/solr/]] which seems to be a stand alone system that can be integrated with other systems such as Drupal [[Wikipedia ref|http://en.wikipedia.org/wiki/Apache_Solr]]. However I couldn't find any reference to integrating this with Moodle. On the other hand, there has been progress in looking at Global Search in Moodle (eg [[Global Search rewrite by Tomasz Muras|https://moodle.org/mod/forum/discuss.php?d=189023]] and [[Global Search 2|https://tracker.moodle.org/browse/MDL-31989]] in the tracker, but Tomasz has had to give up development but has written a dev document [[Global Search|http://docs.moodle.org/dev/Global_Search]]. On //25/Feb/13// Martin D seemed keen to have this be a GSOC project, so that's good. (Global Search was removed from Moodle 2.2 as being non functional).
This looks interesting from [[Global Search 2|https://tracker.moodle.org/browse/MDL-31989]]
Luis de Vasconcelos added a comment - 07/Dec/12 7:20 PM :
<<<
wrensoft.com has a search engine that looks interesting. We plan to test it and see if it is a viable solution.
How to create a search engine for your Moodle site
http://www.wrensoft.com/zoom/support/tutorial_moodle.html
How to index sites requiring authentication with Zoom
http://www.wrensoft.com/zoom/support/auth.html
<<<
and  Alistair Spark added a comment - 13/Feb/13 11:17 AM
<<<
We have just finalised the implementation of the wrensoft search tool which works very well for us as a small institution with a limited number of long courses.
The Version 7 alpha release is required - http://www.wrensoft.com/zoom/v7.html
We have created student accounts for each course which index the appropriate Moodle courses which students will have access to.
<<<
+++[Associated comments]>
Luis de Vasconcelos added a comment - 22/Feb/13 8:26 PM
Alistair, why do you say you "wouldn't want to implement this on a site with 1500 courses"? Is that Zoom Search product not a good one for large Moodle installations? If not, can you describe why not? Thanks.
----
Alistair Spark added a comment - 22/Feb/13 9:44 PM
Hi Luis,

The Zoom Search product is a great one and it can cope with 100 000s of files without any issues, their tech support is very good and ultra-responsive (free limited time trial, bug fix within 24 hours of emailing,...) - we were impressed by the cost&service.

However, from an architectural standpoint we have gone through the route of creating student-like read-only accounts so that we have a search page for each student group (class/academic year combinations), those accounts have access to the exact same courses that the student group would have.

Once you have created one working template for your site, creating more is just a question of changing the username&password combinations, scheduling the indexing and creating a new search box in the course (html block).

Each of these search engines are then located in a different folder (eg http://domain.com/course1year1/search.php http://domain.com/course2year1/search.php) - this is automated by the FTP upload settings.

However, we only needed to configure about 30 profiles in total. (ie Course 1 Year 1, Course 1 Year 2, Course 2 Year 1,....). If we had to have 1500 manual accounts in Moodle just for search, that would become a massive job to create accounts, configure all of the profiles, it becomes kind of a security risk, and maintaining this in the long run would be hard to keep track of.

You could simply have a setup which would crawl your whole Moodle site and give you search results BUT if you have that many courses, it is more than likely that some will cover the same subject at various points, causing major user annoyance when they get the error message telling them they don't have permissions to view these results.
=== 
Click the "new tiddler" button towards the top right of the screen to write something in your space. You'll need to give it a title, some content and, optionally, some tags that will help you identify it later.

!Stuck for ideas?
Not sure what to write about? Not sure what to keep in your space? Other people use ~TiddlySpace for almost anything. How about some of the following:

* [[Save interesting sites|http://bookmarks.tiddlyspace.com]], images or articles from around the web so that you can refer back to them.
* [[Record your family tree|http://familytree.tiddlyspace.com]], store notes on long lost relatives or ancestors and map their relationship to you.
* [[Make up a pocketbook|http://pocketbook.tiddlyspace.com]] to store some useful information in, then print it out, [[fold it up|http://www.pocketmod.com/]], and take it with you.
* [[Plan your holiday|http://the-web-is-your-oyster.tiddlyspace.com/]], record where you're planning to go, note down places of interest and refer back to it later.
* [[Create a mindmap|http://mindmaps.tiddlyspace.com/]] to visualise your inner thoughts and see how they relate to each other.
* [[Set up a questionnaire|http://questionnaire.tiddlyspace.com/]] and get all your friends to answer it.

If you don't like any of those ideas, you can still use this space directly to keep notes and link them together, make a todo list and keep track of everything you're doing, or any one of a hundred million other things.

Still stuck? Check out the @featured space for more suggestions.

You can also [[socialise with others|How to socialise]].
/***
|''Name''|SvgEvent_Menue|
|''Description''|contains the global TW jQuery custom events.|
|''Author''|Mario Pietsch|
|''Version''|0.2.1|
|''Status''|''stable''|
|''Source''|http://fxplugins.tiddlyspace.com|
|''CoreVersion''|2.6|
|''Documentation''|[[SvgEvent_Info]]|
|''Keywords''|svg, events, animation, commands|
!Important
!Known issues
!History
*V 0.2.1
**stable
**[[SvgEvent_Info]] has more info now
*Version: 0.2.0
**changed function names. They are not ugly anymore :)
**SvgEventzPlugin is not needed anymore!
*Version: 0.1.0
**initial release
!Code
***/
/*{{{*/
if(!version.extensions.SvgEvent_Menue) { //# ensure that the plugin is only installed once
version.extensions.SvgEvent_Menue= { installed: true };

(function($) {

var eventTypes = ["cCloseAll", "cPermaview", "cNewTiddler", "cNewJournal", "cSaveChanges", "cReadDoc", "cmd99"];

menue= {
	// if you add event types here. Also go to the end and adjust "var eventTypes" accordingly.

	//menueCloseAll
	cCloseAll: function(e, trial) {
		if  (! trial.comp.menue) return false;

		story.closeAllTiddlers();
		return false;
	}, 

	//menuePermaview
	cPermaview: function(e, trial) {
		if  (! trial.comp.menue) return false;
		story.permaView();
		return false;
	}, 

	//menueNewTiddler
	cNewTiddler: function(e, trial) {
		if  (! trial.comp.menue) return false;
		// trigger readOnly
		if (readOnly) {$(document).trigger('cmd99', trial); return false;}

		var title = 'New Tiddler';
		story.displayTiddler(null, title);
		config.commands.editTiddler.handler(null, null, title);
		return false;
	}, 

	//menueNewJournal
	cNewJournal: function(e, trial) {
		if  (! trial.comp.menue) return false;
		// trigger readOnly
		if (readOnly) {$(document).trigger('cmd99', trial); return false;}

		var title = config.macros.timeline.dateFormat;
		title = new Date().formatString(title.trim());
		story.displayTiddler(null, title);
		config.commands.editTiddler.handler(null, null, title);

		return false;
	}, 

	// menueSaveChanges
	cSaveChanges: function(e, trial) {
		if  (! trial.comp.menue) return false;
		// trigger readOnly
		if (readOnly) {$(document).trigger('cmd99', trial); return false;}
		
		saveChanges();
		return false;
	}, 

	cReadDoc: function(e, trial) {
		if  (! trial.comp.menue) return false;

		var rdDocMsg= "Read the documentation!";

		displayMessage(rdDocMsg);
		return false;
	},

	cmd99: function(e, trial) {
		var rdOnlyMsg= "System is readOnly!";

		if  (! trial.comp.menue) return false;

		displayMessage(rdOnlyMsg);

		trial.elem.setAttribute('opacity', 0.3);
		return false;
	}

}; // menue


// if you add components here a 
var components = [menue];

$.each(components, function(i,component) {
	$.each(eventTypes, function(j,eventType) {
		var handler = component[eventType];
		if (handler) $(document).bind(eventType, handler);
	});
});


})(jQuery);
} //# end of "install only once"

/*}}}*/
Mark Drechsler drops this bombshell in his blog posting on [[Moodle course design made simple|http://www.markdrechsler.com/?p=745]]:
<<<
while I prepare a more significant post on the Assignment module redevelopment project, which is rapidly becoming my main focus for the next little while
<<<
Have to get a list of behaviours / features together.
<!--{{{-->
<div class='toolbar'
	macro='toolbar [[ToolbarCommands::EditToolbar]] icons:yes'>
</div>
<div class='heading editorHeading'>
	<div class='editor title' macro='edit title'></div>
	<div class='tagClear'></div>
</div>
<div class='annotationsBox' macro='annotations'>
	<div class='editSpaceSiteIcon'
		macro='tiddlerOrigin height:16 width:16 label:no interactive:no'>
	</div>
	<div class="privacyEdit" macro='setPrivacy label:no interactive:no'></div>
	<div class='tagClear'></div>
</div>
<div class='editor' macro='edit text'></div>
<div class='editorFooter'>
	<div class='tagTitle'>tags</div>
	<div class='editor' macro='edit tags'></div>
	<div class='tagAnnotation'>
		<span macro='message views.editor.tagPrompt'></span>
		<span macro='tagChooser excludeLists'></span>
	</div>
</div>
<!--}}}-->
/***
|''Name''|TiddlySpaceFilters|
|''Description''|provide TiddlySpace-specific filter extensions|
|''Author''|Jon Robson|
|''Version''|0.6.1|
|''Status''|@@beta@@|
|''CoreVersion''|2.6.2|
|''Requires''|TiddlySpaceConfig|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<tsList Private>>
<<tsList Public>>
<<tsList Draft>>
}}}
!Code
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var privateBag = tiddlyspace.getCurrentBag("private");
var publicBag = tiddlyspace.getCurrentBag("public");

config.filterHelpers = {
	is: {
		"private": function(tiddler) {
			var bag = tiddler.fields["server.bag"];
			return bag == privateBag;
		},
		"public": function(tiddler) {
			var bag = tiddler.fields["server.bag"];
			return bag == publicBag;
		},
		draft: function(tiddler) {
			var fields = tiddler.fields;
			var bag = fields["server.bag"];
			return (privateBag == bag && fields["publish.name"]) ? true : false;
		},
		local: function(tiddler) {
			return config.filterHelpers.is["public"](tiddler) ||
				config.filterHelpers.is["private"](tiddler);
		},
		unsynced: function(tiddler) {
			return tiddler ? tiddler.isTouched() : false;
		}
	}
};

config.filters.is = function(results, match) {
	var candidates = store.getTiddlers("title");
	var type = match[3];
	for (var i = 0; i < candidates.length; i++) {
		var tiddler = candidates[i];
		var helper = config.filterHelpers.is[type];
		if(helper && helper(tiddler)) {
			results.pushUnique(tiddler);
		}
	}
	return results;
};

})(jQuery);
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#FF4646" offset="0"/>
   <stop id="stop2" stop-color="#ffcccc" offset="0.66462"/>
   <stop id="stop3" stop-color="#FF4646" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" style="stroke-dasharray:none;" transform="translate(0.0627706, -0.0627706)" stroke="#4d4d4d" stroke-linecap="butt" stroke-miterlimit="4" stroke-width="1.60000002" fill="none">
   <path id="path2874" style="stroke-dasharray:none;" d="m21.748,51.452,1.7934,14.247,7.9706,0,2.4908-15.144-12.255,0.89669z"/>
   <path id="path2880" style="stroke-dasharray:none;" d="m25.435,51.452,0.84687,14.048"/>
   <path id="path2882" style="stroke-dasharray:none;" d="M30.068,51.104,28.573,65.351"/>
  </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
# I have confirmed through experimentation that the Google Docs repository plugin for M2.2 does ''not'' display any type of image file. So {{{.jpg}}}, {{{.png}}} etc cannot be picked from a Google Docs repository source with the File or Folder Resource type. I cannot find any reference to this in either the Forums or Tracker. File a bug?
# None of the repositories //link// to the file used -- they all make a copy. This is totally counter intuitive and makes an external repository much less useful. Users might as well upload files directly from local system since any updates in the course have to be manually performed. While it might be 'safer', it's certainly not user convenient. For example, Dropbox is used by people because they want to distribute the most up to date version. Copying an instance of the file into a course freezes the version at the arbitrary time of copying and renders moot the whole concept and power behind the Dropbox system.
** example links : [[moodle respository file caching?|http://tracker.moodle.org/browse/MDL-31358]] 
** Looks like it might be addressed by [[Extend repository API to better support LCMS (like Equella)|http://tracker.moodle.org/browse/MDL-28666]] though the [[user interface|http://tracker.moodle.org/secure/attachment/25825/File+picker+options.png]]<<imagebox>> could do with improvement -- ie set a default somewhere that is override-able when desired, rather than ask the same question for every file.
[[Google docs and Moodle integration]]
/***
|''Name''|RandomColorPalettePlugin|
|''Description''|Adds a random color palette to TiddlyWiki|
|''Author''|Jon Robson|
|''Version''|1.4.0|
|''Status''|stable|
|''Source''|https://github.com/jdlrobson/TiddlyWikiPlugins/raw/master/plugins/RandomColorPalettePlugin/RandomColorPalettePlugin.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
!Usage
{{{
<<RandomColorPalette>>
}}}
Sets and saves a random color palette on execution

{{{
<<RandomColorPaletteButton>>
}}}
Creates a button, which when clicked will change the color palette
More information at http://macros.tiddlyspace.com/#%5B%5BRandomColorPaletteButton%20macro%5D%5D
!Code
***/
//{{{
RGB.prototype.toRGBString = function() {
	return "rgb(%0,%1,%2)".format(parseInt(this.r * 255, 10),
		parseInt(this.g * 255, 10), parseInt(this.b * 255, 10))
}
function HSL_TO_RGB(h, s, l) { // h (hue) between 0 and 360, s (saturation) & l (lightness) between 0 and 1
	var c = l <= 0.5 ? 2 * l * s : ( 2 - (2 * l)) * s;
	var h1 = h / 60;
	var x = c * (1 - Math.abs((h1 % 2) - 1)); 
	var r, g, b;
	if(typeof(h) == 'undefined') {
		r = 0;
		g = 0;
		b = 0;
	} else if(0 <= h1 && h1 < 1) {
		r = c;
		g = x;
		b = 0;
	} else if(1 <= h1 && h1 < 2) {
		r = x;
		g = c;
		b = 0;
	} else if(2 <= h1 && h1 < 3) {
		r = 0;
		g = c;
		b = x;
	} else if(3 <= h1 && h1 < 4) {
		r = 0;
		g = x;
		b = c;
	} else if(4 <= h1 && h1 < 5) {
		r = x;
		g = 0;
		b = c;
	} else if(5 <= h1 && h1 < 6) {
		r = c;
		g = 0;
		b = x;
	}
	m = l - (0.5 * c);
	return new RGB(r + m, g + m, b + m);
}

(function($){
	var macro = config.macros.RandomColorPalette = {
		messagesOn: false, 
		changedPaletteText: "We have assigned you a random theme by adjusting the [[ColorPalette]] tiddler.\nDon't like it? Click <<RandomColorPalette>> for another one.", 
		handler: function(place, macroName, params, wikifier, paramString, tiddler) {
			paramString = paramString || "";
			var options = macro.getOptions(paramString);
			macro.generatePalette(options, true);
		},
		optionTypes: {
			floats: ["hue", "saturation", "darkest", "lightness", "huevariance", "dark", "pale", "light", "mid",
				"saturation_light", "saturation_pale", "saturation_mid", "saturation_dark"
			]
		},
		getOptions: function(paramString) {
			var args = paramString.parseParams("name", null, true, false, true)[0];
			var options = {};
			var numbers = macro.optionTypes.floats;
			for(var i in args) {
				options[i] = numbers.indexOf(i) > -1 ? parseFloat(args[i][0], 10) : args[i][0];
			}
			return options;
		},
		generateRandomNumber: function(min, max, info) {
			var num = (Math.random() * 1);
			info = !info ? { attempts:0 } : info;
			info.attempts += 1;
			var good = true;
			if(min == max) {
				return max;
			}
			if(min && num < min) {
				good = false;
			} else if(max && num > max) {
				good = false;
			}
			if(!good) {
				if(info.attempts < 5) {
					return macro.generateRandomNumber(min, max, info);
				} else {
					if(max) {
						return max;
					} else if(min) {
						return min;
					} else {
						return 1;
					}
				}
			}
			return num;
		},
		getExistingPalette: function(asJSON) {
			var title = "ColorPalette";
			var tiddlerText;
			if(store.tiddlerExists(title)) {
				tiddlerText = store.getTiddlerText(title);
			} else if(store.isShadowTiddler(title)){
				tiddlerText = config.shadowTiddlers[title];
			}
			if(asJSON) {
				var json = {};
				if(tiddlerText) {
					var lines = tiddlerText.split("\n");
					for(var i = 0; i < lines.length; i++) {
						var definition = lines[i].split(":");
						if(definition.length == 2) {
							var name = definition[0].trim();
							var value = definition[1].trim();
							json[name] = value;
						}
					}
				}
				return json;
			} else {
				return tiddlerText;
			}
		},
		generatePalette: function(options, save) {
			var outputRGB = options.rgb;
			var palette = macro.getExistingPalette(true);
			var hue = options.hue || Math.floor(Math.random() * 359);
			var saturation = options.saturation || macro.generateRandomNumber(0.3, 0.7);
			var dark = options.dark || options.darkest || macro.generateRandomNumber(0, 0.10);
			var pale = options.pale || options.lightness || macro.generateRandomNumber(0.90, 1);
			var delta = ( ( pale - dark ) / 3 );
			var mid = options.mid || dark + delta;
			var light = options.light || dark + (delta * 2);
			var lightness_values = {Dark: dark, Mid: mid, Light: light, Pale: pale};
			var saturation_values = {};
			for(i in lightness_values) {
				if(true) {
					saturation_values[i] = options["saturation_" + i.toLowerCase()] || saturation;
				}
			}

			var opposite_hue = (hue + 180) % 360;
			var seed = options.huevariance || Math.floor((85 * Math.random()) + 5); // we want it to be at least 5 degrees
			var huetwo = (opposite_hue + seed) % 360;
			var huethree = (opposite_hue - seed) % 360;
			if(huetwo < 0) {
				huetwo = 360 + huetwo;
			}
			if(huethree < 0) {
				huethree = 360 + huethree;
			}
			for(var j in lightness_values) {
				if(true) {
					var saturation = saturation_values[j];
					palette["Primary" + j] = HSL_TO_RGB(hue, saturation, lightness_values[j]);
					palette["Secondary" + j] = HSL_TO_RGB(huetwo, saturation, lightness_values[j]);
					palette["Tertiary" + j] = HSL_TO_RGB(huethree, saturation, lightness_values[j]);
				}
			}
			palette.Background = HSL_TO_RGB(hue, saturation, 0.92);
			palette.Foreground = HSL_TO_RGB(hue, saturation, 0.08);
			palette.ColorPaletteParameters = ["HSL([", hue, "|", seed, "], [", saturation_values.Pale, "|",
				saturation_values.Light, "|", saturation_values.Mid, "|", saturation_values.Dark, "],",
				"[", dark, "|", mid, "|", light, "|", pale, "])"].join("");
			// construct new ColorPalette
			var text = ["/*{{{*/\n"];
			var colorcode;
			for(var id in palette) {
				if(true) {
					var color = palette[id];
					colorcode = outputRGB ? color.toRGBString() : color.toString();
					text.push("%0: %1\n".format(id, colorcode));
				}
			}
			text.push("/*}}}*/");
			text = text.join("");
			if(save) {
				macro.saveColorPalette(text);
			}
			return text;
		},
		saveColorPalette: function(text) {
			var tid = store.getTiddler("ColorPalette");
			if(!tid) {
				tid = new Tiddler("ColorPalette");
				tid.fields = merge({}, config.defaultCustomFields);
			} // TODO: detect that the ColorPalette in the space comes from outside recipe
			tid.fields["server.page.revision"] = "false"; // edit conflicts dont matter

			// save the color palette in tid
			tid = store.saveTiddler(tid.title, tid.title, text, tid.modifier, tid.modified,
				tid.tags, tid.fields, false, tid.created, tid.creator);
			// an interval is used to cope with users clicking on the palette button quickly.
			if(macro._nextSave) {
				window.clearTimeout(macro._nextSave);
			}
			macro._nextSave = window.setTimeout(function() {
					autoSaveChanges(null, [tid]);
				}, 2000);
			// temporary workaround for IE.
			$.twStylesheet.remove({ id: "StyleSheetColors" });
			$.twStylesheet.remove({ id: "StyleSheet" });
			refreshAll();
			macro.reportChange();
			return tid;
		},
		reportChange: function() {
			if(macro.messagesOn) { // only display message once..
				var msgPlace = getMessageDiv();
				if(!$(".changedPalette", msgPlace)[0]) {
					var tempPlace = document.createElement("div");
					wikify("{{changedPalette{" + macro.changedPaletteText + "}}}", tempPlace);
					msgPlace.appendChild(tempPlace);
				}
			}
		}
	};
	var btnMacro = config.macros.RandomColorPaletteButton = {
			text: "New ColorPalette",
			tooltip: "Generate a random colour scheme for your TiddlyWiki",
			makeButton: function(place, options) {
				var btnHandler = function(ev) {
					var t = $(ev.target);
					var options = t.data("options");
					macro.generatePalette(options, true);
					ev.preventDefault();
					return false;
				};
				var btn = createTiddlyButton(place, this.text, this.tooltip, btnHandler);
				$(btn).data("options", options);
				return btn;
			},
			handler: function(place, macroName, params, wikifier, paramString, tiddler) {
				var options = macro.getOptions(paramString);
				btnMacro.makeButton(place, options);
			}
	};
})(jQuery);
//}}}
From the Aug workshop I need to give the class a dummy course with dummy users and //graded assignments// and also //attendances//. Problem is that I cannot use real student names. So, take Dan Graves' Jazz History course and attempt to substitute hogwart students for real students.

* Enrol hogwart students into class
* backup course users and //grade hsitories//
* download and unzip. Examine the {{{moodle.xml}}}

What we find is that mdl_user.id has a unique counterpart in //moodle.xml// as : 
{{{
      <USER>
        <ID>1246</ID>
        <AUTH>ldap</AUTH>
        <CONFIRMED>1</CONFIRMED>
        <POLICYAGREED>0</POLICYAGREED>
        <DELETED>0</DELETED>
        <USERNAME>mrwarner09</USERNAME>
        <IDNUMBER>56196</IDNUMBER>
        <FIRSTNAME>Michael</FIRSTNAME>
        <LASTNAME>Warner</LASTNAME>
        <EMAIL>mrwarner09@earlham.edu</EMAIL>
}}}
And this is replicated elsewhere in the file as {{{<USERID>}}}
{{{
            <ASSIGNMENT>
              <USERID>1246</USERID>
              <HIDDEN>0</HIDDEN>
              <TIMESTART>0</TIMESTART>
              <TIMEEND>0</TIMEEND>
              <TIMEMODIFIED>1327578643</TIMEMODIFIED>
              <MODIFIERID>0</MODIFIERID>
              <ENROL>lmb</ENROL>
              <SORTORDER>0</SORTORDER>
            </ASSIGNMENT> 
}}}
So, all I need to do is to swap <ID> numbers of genuine class members with Hogwarts students. (But, the problem with this way is that the <id> will be wrong for the rest of moodle -- best to swap <userid> for each instance which should be straightforward with global find/replace.
But which students to swap? Best to get a spread of grades throughout the class. There are 30 students and only 13 hogwarts students.
# Go to the online gradebook in Moodle course and download all the grades as excel spreadsheet. This is good but only the LMB 'idnumber' is retained and not mdl_user.id. So, with a copied list of 'idnumber' generate a sql series like:
{{{
SELECT firstname,lastname, username, idnumber, id FROM mdl_user WHERE idnumber = 90461;
}}}
for each class member and run as command line like:
{{{mysql -u clamp13_user -p -D clamp13 <class_ids.sql >class_ids.txt}}}
which outputs:
{{{
firstname       lastname        username        idnumber        id
Rachel  	Winsberg        rawinsb10       90461   	518
firstname       lastname        username        idnumber        id
Nathan  	Young   	nlyoung07       9798    	586
}}}
Then tidy this up in Excel.
Similarly for hogwarts students:
{{{
SELECT firstname,lastname, username, idnumber, id FROM mdl_user WHERE email='c@wondershock.net';
SELECT firstname,lastname, username, idnumber, id FROM mdl_user WHERE email='d@wondershock.net';
}}}
which gives :
{{{
firstname       lastname        username        idnumber        id
Cho     	Chang   	choc            		418
firstname       lastname        username        idnumber        id
Fleur   	Delacour        fleurd          		420
}}}
Now, get both of these files back into Excel and do some jiggery pokery (in //MUS369-0_201220_student_substitutions.xlsx//)
{{{
Michael	Warner	mrwarner09	56196	1246	96.19		Cho	Chang	choc		418
Rachel	Winsberg	rawinsb10	90461	518	95.26						
Nathan	Young	nlyoung07	9798	586	94.69		Fleur	Delacour	fleurd		420
Emily	McGrew	ermcgrew11	76179	2538	94.61						
Martin	Ventura	mkventu09	19041	1091	94.41		Seamus	Finnigan	seamusf		429
}}}
So, now all I need to do is change all instances of {{{<USERID>1246</USERID>}}} (Michael Warner) to {{{<USERID>418</USERID>}}} (Cho Chang) and delete the <ID>1246</ID>. Repeat for all users.
[[Dummy course construction -- part 2]]
!Course restore problem with LMB enrollments
;Problem
: Users enrolled via LMB process are not restored into a new course even when it seems that everything has been backed up.
!!Description
I need to duplicate a course with all enrolled teachers and students together with graded Workshop assignments in order to do some testing.
# On production moodle 2.3.4+ system create a course backup in the normal way (as 'Moodle Tsar' system admin) which includes student grades (but not logs). Backup completes without error.
** expanding the mbz file reveals that all the enrollments are correctly recorded in {{{course/enrolments.xml}}}
# On the sandbox moodle site (which has exactly the same code -- the production site is simply a copy of this) do the full course restore.
# Open the course and check Course administration > Users > Enrolled users. Only manually enrolled user accounts have been restored.
+++!!![Restore process]
# As system admin open Front page settings > Restore
# Drag & drop the course backup file with user grades
# Begin the restore, [[stage 1|http://www.earlham.edu/~markp/screens/moodle/M2-restore-course-grades1a.png]]<<imagebox>>
# The Destination is a new course
# [[Stage 3|http://www.earlham.edu/~markp/screens/moodle/M2-restore-course-grades2.png]]<<imagebox>> includes all enrolled users and grade histories
# [[Stage 4 Schema|http://www.earlham.edu/~markp/screens/moodle/M2-restore-course-grades3.png]] Chnage some settings for the new course
# Continue to process the restore and execute
# Open the newly created course and go to Settings > Course administration > Users > Enrolled users. Here's what you find:
: [img(80%,auto)[http://www.earlham.edu/~markp/screens/moodle/M2-restore-course-grades4.png]]
=== 
LMB version :
{{{
$plugin->version  = 2012091203;
$plugin->release = "2.1.9";
}}}
!!Implications
The implications are rather dire. On my new production Moodle system I'm planning to run system wide course backups at regular intervals. In order to be useful (ie recover from a disastrous mistake in grading perhaps) they need to include all users and associated grades. If such courses cannot be restored fully then they are useless for this purpose.
----
On tracker as [[Course restore problem with LMB enrollments|https://tracker.moodle.org/browse/CONTRIB-4194]]
{{ts{12/03/13 10:14}}}
Response from Eric Merrill:
<<<
This is a limitation of Moodle version below 2.4. Starting in that release they added support for enrolment restores for methods other than manual.
<<<
/***
|Name:|InstantTimestampPlugin|
|Description:|A handy way to insert timestamps in your tiddler content|
|Version:|1.0.10 ($Rev: 3646 $)|
|Date:|$Date: 2008-02-27 02:34:38 +1000 (Wed, 27 Feb 2008) $|
|Source:|http://mptw.tiddlyspot.com/#InstantTimestampPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!Usage
If you enter {ts} in your tiddler content (without the spaces) it will be replaced with a timestamp when you save the tiddler. Full list of formats:
* {ts} or {t} -> timestamp
* {ds} or {d} -> datestamp
* !ts or !t at start of line -> !!timestamp
* !ds or !d at start of line -> !!datestamp
(I added the extra ! since that's how I like it. Remove it from translations below if required)
!!Notes
* Change the timeFormat and dateFormat below to suit your preference.
* See also http://mptw2.tiddlyspot.com/#AutoCorrectPlugin
* You could invent other translations and add them to the translations array below.
***/
//{{{

config.InstantTimestamp = {

	// adjust to suit
	timeFormat: 'DD/0MM/YY 0hh:0mm',
	dateFormat: 'DD/0MM/YY',

	translations: [
		[/^!ts?$/img,  "'!!{{ts{'+now.formatString(config.InstantTimestamp.timeFormat)+'}}}'"],
		[/^!ds?$/img,  "'!!{{ds{'+now.formatString(config.InstantTimestamp.dateFormat)+'}}}'"],

		// thanks Adapted Cat
		[/\{ts?\}(?!\}\})/ig,"'{{ts{'+now.formatString(config.InstantTimestamp.timeFormat)+'}}}'"],
		[/\{ds?\}(?!\}\})/ig,"'{{ds{'+now.formatString(config.InstantTimestamp.dateFormat)+'}}}'"]
		
	],

	excludeTags: [
		"noAutoCorrect",
		"noTimestamp",
		"html",
		"CSS",
		"css",
		"systemConfig",
		"systemConfigDisabled",
		"zsystemConfig",
		"Plugins",
		"Plugin",
		"plugins",
		"plugin",
		"javascript",
		"code",
		"systemTheme",
		"systemPalette"
	],

	excludeTiddlers: [
		"StyleSheet",
		"StyleSheetLayout",
		"StyleSheetColors",
		"StyleSheetPrint"
		// more?
	]

}; 

TiddlyWiki.prototype.saveTiddler_mptw_instanttimestamp = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {

	tags = tags ? tags : []; // just in case tags is null
	tags = (typeof(tags) == "string") ? tags.readBracketedList() : tags;
	var conf = config.InstantTimestamp;

	if ( !tags.containsAny(conf.excludeTags) && !conf.excludeTiddlers.contains(newTitle) ) {

		var now = new Date();
		var trans = conf.translations;
		for (var i=0;i<trans.length;i++) {
			newBody = newBody.replace(trans[i][0], eval(trans[i][1]));
		}
	}

	// TODO: use apply() instead of naming all args?
	return this.saveTiddler_mptw_instanttimestamp(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created);
}

// you can override these in StyleSheet 
setStylesheet(".ts,.ds { font-style:italic; }","instantTimestampStyles");

//}}}

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#FF4646" offset="0"/>
   <stop id="stop2" stop-color="#ffcccc" offset="0.66462"/>
   <stop id="stop3" stop-color="#FF4646" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" style="stroke-dasharray:none;" transform="matrix(0.579556, -0.579556, 0.579556, 0.579556, -4.21894, 26.7647)" stroke="#4d4d4d" stroke-width="3.19999981" fill="#4d4d4d">
<path id="path3219" style="stroke-dasharray:none;" d="M-7.3399,53.9h16.353"/>
<path id="path3221" style="stroke-dasharray:none;" d="M0.8368,62.077v-16.354"/>
</g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
/***
|''Name''|TiddlyWebConfig|
|''Description''|configuration settings for TiddlyWebWiki|
|''Author''|FND|
|''Version''|1.3.2|
|''Status''|stable|
|''Source''|http://svn.tiddlywiki.org/Trunk/association/plugins/TiddlyWebConfig.js|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''Requires''|TiddlyWebAdaptor ServerSideSavingPlugin|
|''Keywords''|serverSide TiddlyWeb|
!Code
***/
//{{{
(function($) {

if(!config.extensions.ServerSideSavingPlugin) {
	throw "Missing dependency: ServerSideSavingPlugin";
}
if(!config.adaptors.tiddlyweb) {
	throw "Missing dependency: TiddlyWebAdaptor";
}

if(window.location.protocol != "file:") {
	config.options.chkAutoSave = true;
}

var adaptor = tiddler.getAdaptor();
var recipe = tiddler.fields["server.recipe"];
var workspace = recipe ? "recipes/" + recipe : "bags/common";

var plugin = config.extensions.tiddlyweb = {
	host: tiddler.fields["server.host"].replace(/\/$/, ""),
	username: null,
	status: {},

	getStatus: null, // assigned later
	getUserInfo: function(callback) {
		this.getStatus(function(status) {
			callback({
				name: plugin.username,
				anon: plugin.username ? plugin.username == "GUEST" : true
			});
		});
	},
	hasPermission: function(type, tiddler) {
		var perms = tiddler.fields["server.permissions"];
		if(perms) {
			return perms.split(", ").contains(type);
		} else {
			return true;
		}
	}
};

config.defaultCustomFields = {
	"server.type": tiddler.getServerType(),
	"server.host": plugin.host,
	"server.workspace": workspace
};

// modify toolbar commands

config.shadowTiddlers.ToolbarCommands = config.shadowTiddlers.ToolbarCommands.
	replace("syncing ", "revisions syncing ");

config.commands.saveTiddler.isEnabled = function(tiddler) {
	return plugin.hasPermission("write", tiddler) && !tiddler.isReadOnly();
};

config.commands.deleteTiddler.isEnabled = function(tiddler) {
	return !readOnly && plugin.hasPermission("delete", tiddler);
};

// hijack option macro to disable username editing
var _optionMacro = config.macros.option.handler;
config.macros.option.handler = function(place, macroName, params, wikifier,
		paramString) {
	if(params[0] == "txtUserName") {
		params[0] = "options." + params[0];
		var self = this;
		var args = arguments;
		args[0] = $("<span />").appendTo(place)[0];
		plugin.getUserInfo(function(user) {
			config.macros.message.handler.apply(self, args);
		});
	} else {
		_optionMacro.apply(this, arguments);
	}
};

// hijack isReadOnly to take into account permissions and content type
var _isReadOnly = Tiddler.prototype.isReadOnly;
Tiddler.prototype.isReadOnly = function() {
	return _isReadOnly.apply(this, arguments) ||
		!plugin.hasPermission("write", this);
};

var getStatus = function(callback) {
	if(plugin.status.version) {
		callback(plugin.status);
	} else {
		var self = getStatus;
		if(self.pending) {
			if(callback) {
				self.queue.push(callback);
			}
		} else {
			self.pending = true;
			self.queue = callback ? [callback] : [];
			var _callback = function(context, userParams) {
				var status = context.serverStatus || {};
				for(var key in status) {
					if(key == "username") {
						plugin.username = status[key];
						config.macros.option.propagateOption("txtUserName",
							"value", plugin.username, "input");
					} else {
						plugin.status[key] = status[key];
					}
				}
				for(var i = 0; i < self.queue.length; i++) {
					self.queue[i](plugin.status);
				}
				delete self.queue;
				delete self.pending;
			};
			adaptor.getStatus({ host: plugin.host }, null, _callback);
		}
	}
};
(plugin.getStatus = getStatus)(); // XXX: hacky (arcane combo of assignment plus execution)

})(jQuery);
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d">
  <path id="path3288" style="stroke-dasharray:none;" d="m32.71,59.791a1.2868,1.2868,0,1,1,-2.5736,0,1.2868,1.2868,0,1,1,2.5736,0z" fill-rule="evenodd" transform="matrix(0.472928, 0, 0, 0.472928, 12.3536, 34.6064)" stroke-linecap="round" stroke-miterlimit="4" stroke-width="4" fill="#CCC"/>
  <path id="path3637" style="stroke-dasharray:none;" d="m-5.7134,10.839a1.5781,1.5781,0,1,1,0.00225,-0.03585" transform="matrix(4.22706, 0, 0, 2.02533, 58.118, 41.1739)" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.68353766" fill="none"/>
  <path id="path4348" d="m27.559,49.224,4.9188,2.0603-3.569,0,0.15291,6.0339-3.1302,0,0-6.0339-3.514,0,5.1416-2.0603z" stroke-linecap="butt" stroke-width="0.70393437px" fill="#4d4d4d"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
/***
|''Name''|ToggleTiddlerPrivacyPlugin|
|''Version''|0.7.1|
|''Status''|@@beta@@|
|''Description''|Allows you to set the privacy of new tiddlers and external tiddlers within an EditTemplate, and allows you to set a default privacy setting|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
|''Source''|http://github.com/TiddlySpace/tiddlyspace/raw/master/src/plugins/ToggleTiddlerPrivacyPlugin.js|
!Notes
When used in conjunction with TiddlySpaceTiddlerIconsPlugin changing the privacy setting will also interact with any privacy icons.

Currently use of
{{{<<setPrivacy defaultValue:public>>}}} is in conflict with {{{<<newTiddler fields:"server.workspace:x_private">>}}}

There is an option, found in the tweak tab of the backstage, called txtPrivacyMode. Set this to either ''public'' or ''private'' depending on your security preference. If you choose not to set it then it will default to ''public''.
!Params
defaultValue:[private|public]
Allows you to set the default privacy value (Default is private)

!Code
***/
//{{{
(function($) {

	var tiddlyspace = config.extensions.tiddlyspace,
		macro;
	macro = config.macros.setPrivacy = {
		handler: function(place, macroName, params, wikifier, paramString, tiddler) {
			if(readOnly) {
				return;
			}
			var el = $(story.findContainingTiddler(place)),
				args = paramString.parseParams("name",
					null, true, false, true)[0],
				container = $("<div />").
					addClass("privacySettings").
					appendTo(place)[0],
				currentSpace = tiddlyspace.currentSpace.name,
				currentBag = tiddler ? tiddler.fields["server.bag"] : false,
				// XXX: is the following reliable?
				isNewTiddler = el.hasClass("missing") || !currentBag,
				tiddlerStatus = tiddlyspace.getTiddlerStatusType(tiddler),
				customFields = el.attr("tiddlyfields"),
				defaultValue = "public",
				options = config.macros.tiddlerOrigin ?
						config.macros.tiddlerOrigin.getOptions(paramString) :
						{};
			customFields = customFields ? customFields.decodeHashMap() : {};
			if(isNewTiddler || !["public", "private", "unsyncedPrivate",
					"unsyncedPublic"].contains(tiddlerStatus)) {
				if(args.defaultValue) {
					defaultValue = args.defaultValue[0].toLowerCase();
				} else {
					defaultValue = config.options.chkPrivateMode ?
							"private" : "public";
				}
				defaultValue = defaultValue ?
						"%0_%1".format(currentSpace, defaultValue) :
						customFields["server.bag"];
				this.createRoundel(container, tiddler, currentSpace,
						defaultValue, options);
			}
		},
		updateEditFields: function(tiddlerEl, bag) {
			var saveBagField = $('[edit="server.bag"]', tiddlerEl),
				saveWorkspaceField = $('[edit="server.workspace"]', tiddlerEl),
				input = $("<input />").attr("type", "hidden"),
				workspace = "bags/" + bag;
			if(saveBagField.length === 0) {
				input.clone().attr("edit", "server.bag").val(bag).
					appendTo(tiddlerEl);
			} else {
				saveBagField.val(bag);
			}
			// reset to prevent side effects
			$(tiddlerEl).attr("tiddlyFields", "");
			if(saveWorkspaceField.length === 0) {
				input.clone().attr("edit", "server.workspace").
					val(workspace).appendTo(tiddlerEl);
			} else {
				saveWorkspaceField.val(workspace);
			}
		},
		setBag: function(tiddlerEl, newBag, options) {
			var bagStatus,
				title = $(tiddlerEl).attr("tiddler"),
				tiddler = store.getTiddler(title),
				originButton = $(".originButton", tiddlerEl)[0],
				refreshIcon,
				newWorkspace = "bags/" + newBag,
				rPrivate = $("input[type=radio].isPrivate", tiddlerEl),
				rPublic = $("input[type=radio].isPublic", tiddlerEl);
			refreshIcon = function(type) {
				var originMacro = config.macros.tiddlerOrigin;
				if(originButton && originMacro) {
					options.noclick = true;
					originMacro.showPrivacyRoundel(tiddler, type,
							originButton, options);
				}
			};
			macro.updateEditFields(tiddlerEl, newBag);
			if(tiddler) {
				tiddler.fields["server.bag"] = newBag;
				// for external tiddlers
				tiddler.fields["server.workspace"] = newWorkspace;
			}
			if(newBag.indexOf("_public") > -1) {
				rPrivate.attr("checked", false);
				rPublic.attr("checked", true);
				bagStatus = "public";
			} else {
				rPublic.attr("checked", false); // explicitly do this for ie
				rPrivate.attr("checked", true);
				bagStatus = "private";
			}
			refreshIcon(bagStatus);
		},
		createRoundel: function(container, tiddler, currentSpace,
							   defaultValue, options) {
			var privateBag = "%0_private".format(currentSpace),
				publicBag = "%0_public".format(currentSpace),
				rbtn = $("<input />").attr("type", "radio").
					attr("name", tiddler.title),
				el = story.findContainingTiddler(container);
			rbtn.clone().val("private").addClass("isPrivate").
				appendTo(container);
			$("<label />").text("private").appendTo(container); // TODO: i18n
			rbtn.clone().val("public").addClass("isPublic")
				.appendTo(container);
			$("<label />").text("public").appendTo(container); // TODO: i18n
			$("[type=radio]", container).click(function(ev) {
				var btn = $(ev.target);
				tiddler.fields["server.page.revision"] = "false";
				if(btn.hasClass("isPrivate")) { // private button clicked.
					$(el).addClass("isPrivate").removeClass("isPublic");
					macro.setBag(el, privateBag, options);
				} else {
					$(el).addClass("isPublic").removeClass("isPrivate");
					macro.setBag(el, publicBag, options);
				}
			});
			window.setTimeout(function() {
				macro.setBag(el, defaultValue, options);
			}, 100);
			// annoyingly this is needed as customFields are added to end of EditTemplate so are not present yet
			// and don't seem to respect any existing customFields.
		}
	};

}(jQuery));
//}}}
!Topics
*    Using Questionnaire to poll a class
*    How Progress Bar can help students keep up with their reading
*    Grading Attendance and Class Participation the easy way with Attendance.
*    Gradebook redux — simple ways to keep track of class grades
*    Gradebook — when to use Assignment activity and when not.
*    Managing courses — using Import / Backup / Restore to manage all your courses yourself.
*    Content heavy course — simple ways to present courses with lots of material without clutter.
*    Using Scheduler to create online 'sign up sheet'
From 2009:
|!#|!Workshop|>|>|!Level of interest|
| | |Definitely|Maybe|Nope|
| 1.|Tracking student attendance and class activity with Attendance | 4| 1| |
| 2.|Ways of doing your quiz online to minimize grading overhead. | 3| 1| |
| 3.|Doing effective group work online with Forums/ Wikis and Groups/Groupings | 7| 1| |
| 4.|Setting up assignments for online processing – submission, mark-up, grading | 4| 1| |
| 5.|Using the Moodle gradebook | 3| | 1|
Workshops in 2010
* Making the new editor (TinyMCE) work for you (fixing MS Word damage)
* Streamlining attendance and participation with Attendance
* Keeping students on track with reading : Progress Bar
* Using Questionnaire to elicit student feedback
* Using Choice, Groups and Forums for collaborative working online
* Using Advanced Assignment/ZIP download to return marked up papers
* Ease the process of quizzing large classes with Quiz
* Make the Gradebook work for you
* Map syllabus onto course activities, resources and gradebook
* Class blogging with OUBlog
* Collaboration with OUWiki

[[Faculty List]]
!SpaceUnplugged
{{unpluggedSpaceTab{
{{wizard{
<<image unsyncedIcon width:48>> Sync is currently unavailable in ~TiddlyWiki due to security constraints in modern browsers. Research is being done to build a suitable alternative. In the meantime if you have changed content in an offline ~TiddlyWiki, you can get your content back into ~TiddlySpace by using the ''import'' functionality from the backstage of the online wiki.
}}}
}}}

!Menu
<<message messages.memberStatus>> <<homeLink>>
{{unsyncedList{<<message messages.syncListHeading>> <<list filter [is[unsynced]]>>}}}

running TiddlySpace@glossary version <<message extensions.tiddlyweb.status.tiddlyspace_version>>
{{autotable{
<<tiddler Backstage##Resources>>
}}}

!Resources
[[blog|@@blog]] [[documentation|@@docs]] [[featured spaces|@@featured]] 

!ImportExport
<<fileImport>>
You can download this TiddlySpace as an offline TiddlyWiki:

{{chunkyButton{<<exportSpace>>}}}

!BackstageTiddlers
|upload a <<message messages.privacySetting>> file: <<binaryUpload>>|<<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>>|
|>|<<search>>|
|>|<<tiddler Backstage##Tiddlers>>|

!Tiddlers
<<tabs
	txtMainTab
	"Recent" "Recently edited tiddlers" TabTimeline
	"All" "All tiddlers" TabAll
	"Public" "All public tiddlers" [[TiddlySpaceTabs##Public]]
	"Private" "All private tiddlers" [[TiddlySpaceTabs##Private]]
	"Tags" "All tags" TabTags
	"Spaces" "Tiddlers grouped by space" [[TiddlySpaceTabs##Spaces]]
	"Missing" "Missing tiddlers" TabMoreMissing
	"Orphans" "Orphaned tiddlers" TabMoreOrphans
	"Shadows" "Shadowed tiddlers" TabMoreShadowed
>>

!BatchOps
<<tabs
	txtPublisherTab
	"Private" "Move tiddlers from private to public" Backstage##BatchPrivate
	"Public" "Move tiddlers from public to private" Backstage##BatchPublic
>>

!BatchPrivate
<<TiddlySpacePublisher type:private>>

!BatchPublic
<<TiddlySpacePublisher type:public>>

!Plugins
''Note:'' Many of these plugins are core TiddlySpace plugins and cannot be changed unless first cloned.

<<tiddler PluginManager>>

!Tweaks
These options change behavior in TiddlyWiki //only// and may be ineffective in TiddlySpace.

<<tiddler AdvancedOptions>>
/***
|''Name''|TiddlySpaceRevertRevision|
|''Description''|Revert to a previous revision|
|''Author''|BenGillies|
|''Version''|0.1|
|''Status''|unstable|
|''Source''|http://github.com/TiddlySpace/tiddlyspace|
|''CodeRepository''|http://github.com/TiddlySpace/tiddlyspace|
|''License''|[[BSD|http://www.opensource.org/licenses/bsd-license.php]]|
|''CoreVersion''|2.6.0|
|''Requires''|TiddlyWebAdaptor TiddlySpaceRevisionView|
!Usage
Add a control button to revert to a particular revision.

The button must be called from within a revision, as generated by TiddlySpaceRevisionView
!Code
***/
//{{{
(function($) {

config.commands.revert = {
	text: "revert",
	tooltip: "make this revision the current one",
	handler: function(ev, src, title) {
		var revElem = story.getTiddler(title);
		var tidToRevert = store.getTiddler($(revElem).attr("revName"));

		var revision = store.getTiddler(title);
		if ((revision) && (tidToRevert)) {
			tidToRevert.text = revision.text;
			var newFields = merge({}, revision.fields);
			for (var fieldName in newFields) {
				if (fieldName.substr(0, 7) === "server.") {
					delete newFields[fieldName];
				}
			}
			merge(tidToRevert.fields, newFields);
			tidToRevert.tags = merge([], revision.tags);
			tidToRevert.fields.changecount = 1;
			delete tidToRevert.fields.doNotSave;

			store.saveTiddler(tidToRevert.title, tidToRevert.title,
				tidToRevert.text, null, null, tidToRevert.tags,
				tidToRevert.fields, false, tidToRevert.created, tidToRevert.creator);

			autoSaveChanges(true);
		}
	}
};

})(jQuery);
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <path id="iconSymbol" stroke-linejoin="miter" style="stroke-dasharray:none;" d="m21.411,59.069,3.5152,4.3939,9.7922-11.675" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" stroke-width="2.4000001" fill="none"/>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>
/***
|''Name''|ImportExternalLinksPlugin|
|''Author''|Jon Robson|
|''Version''|0.3.0|
|''Requires''|TiddlySpaceConfig TiddlySpaceLinkPlugin TiddlySpaceCloneCommand|
|''Description''|Turns space links into ajax links so you don't have to leave the comfort of your own TiddlyWiki|
!Notes
This maybe should hides the editTiddler, cloneTiddler commands. Ideally the toolbar commands should hide themselves but we need a strong concept of "this is a sucked in tiddler" to do that.
***/
//{{{
(function($){
var tiddlyspace = config.extensions.tiddlyspace;
_createSpaceLink = createSpaceLink;
if(_createSpaceLink) {
	createSpaceLink = function(place, spaceName, title, alt, isBag) {
		var tooltip = "Click to open in current document. Right click to open in original space.";
		_createSpaceLink(place, spaceName, title, alt, isBag);
		var workspace;
		if(isBag) {
			workspace = "bags/%0".format(spaceName);
		} else {
			workspace = "bags/%0_public".format(spaceName);
		}
		if(title && spaceName != tiddlyspace.currentSpace.name) {
			var link = $("a:last", place);
			var newlink = $("<a />").text("[link]").after(link[0]);
			// very hacky
			var updateInterval = setInterval(function() {
				var href = link.attr("href");
				if(href) {
					$(newlink).attr("href", href);
					clearInterval(updateInterval);
				}
			}, 200);
			
			if(link.parent(".replyLink").length == 0) { // don't suck in a reply link.
				link.attr("title", tooltip).addClass("importLink").click(function(ev) {
					if(config.floorboards) {
						config.floorboards.pushUnique("%0_public".format(spaceName));
					}
					tiddlyspace.displayServerTiddler(ev.target, title, workspace, function(el) {
						// TODO: the commands should disable themselves based on the meta information.
						//$("[commandname=editTiddler], [commandname=cloneTiddler]", el).hide(); 
					});
					ev.preventDefault();
				});
			}
		}
	};
}

var _cloneHandler = config.commands.cloneTiddler.handler;
config.commands.cloneTiddler.handler = function(event, src, title) {
	var _tiddler = store.getTiddler(title);
	var source = _tiddler ? _tiddler.fields["server.bag"] : false;
	var imported = _tiddler ? _tiddler.fields["tiddler.source"] : false;
	var realTitle = _tiddler ? _tiddler.fields["server.title"] : title;
	_cloneHandler.apply(this, [event, src, title]);
	var tidEl = story.getTiddler(title);
	$(story.getTiddlerField(title, "title")).val(realTitle);
	if(source) {
		$("<input />").attr("type", "hidden").attr("edit", "tiddler.source").val(source).appendTo(tidEl);
		$("<input />").attr("type", "hidden").attr("edit", "server.activity").appendTo(tidEl);
	}
}
})(jQuery);
//}}}
The tiddler 'New Tiddler' doesn't yet exist. Double-click to create it/%
!info
|Name|ToggleRightSidebarEm|
|Source|http://hoster.peermore.com/recipes/TeamWork/tiddlers.wiki#ToggleRightSidebarEm|
|Version|0.1.0|
|Author|Mario Pietsch|
|Derived from:|http://www.tiddlytools.com/#ToggleRightSidebar|
|License|http://creativecommons.org/licenses/by-nc-sa/3.0/at/|
|~CoreVersion|2.6|
|Type|transclusion|
|Description|show/hide right sidebar (MainMenu) for FreeStyle Themes. Works only with EmasticSystem|
Usage
<<<
{{{
<<tiddler ToggleRightSidebarEm>>
<<tiddler ToggleRightSidebarEm with: label tooltip>>
<<tiddler ToggleRightSidebarEm with: {{config.options.chkShowRightSidebar?'►':'◄'}}{{config.options.chkShowRightSidebar?'hide':'show'}}>>
}}}
Try it: <<tiddler ToggleRightSidebarEm##show
	with: {{config.options.chkShowRightSidebar?'►':'◄'}}>>
<<<
Configuration:
<<<
{{{
config.options.chkShowRightSidebar (true)
config.options.txtToggleRightSideBarLabelShow (◄)
config.options.txtToggleRightSideBarLabelHide (►)
}}}
<<<
!end
!show
<<tiddler {{
	var co=config.options;
	if (co.chkShowRightSidebar===undefined) co.chkShowRightSidebar=true;

	getDP = function(name) {
		var width = undefined;
		var myregexp = /dp([\d]{1,3})/;
		var elem = jQuery(name);
		var text = elem.attr('class');

		var match = myregexp.exec(text);
		if (match != null) {
			width = match[1];
		} else {
			elem = jQuery(name).parent();
			text = elem.attr('class');
			match = myregexp.exec(text);
			if (match != null) {
				width = match[1]
			}
			else elem = undefined;
		}
		return {'width': width, 'elem': elem};
	}; // end function

	setDP = function(cmd, elem, target) {
		if (!elem || !target) return alert('elem or target undefined!');
		var newWidth = 0;
		if (cmd === 'hide' && (elem.elem.css('display') != 'none')) {
			newWidth = parseInt(target.width) + parseInt(elem.width);
			jQuery(elem.elem).hide();
			jQuery(target.elem).removeClass('dp'+target.width);
			jQuery(target.elem).addClass('dp'+newWidth);
		}
	}; // end function

	var mm = getDP('#mainMenu');
	var da = getDP('#displayArea');
	var sb = getDP('#sidebar');

	var cmd = co.chkShowRightSidebar?'show':'hide';
	setDP(cmd, sb, da);

'';}}>><html><nowiki><a href='javascript:;' title="$2"
onmouseover="
	this.href='javascript:void(eval(decodeURIComponent(%22(function(){try{('
	+encodeURIComponent(encodeURIComponent(this.onclick))
	+')()}catch(e){alert(e.description?e.description:e.toString())}})()%22)))';"
onclick="
	var co=config.options;
	var opt='chkShowRightSidebar';
	var show=co[opt]=!co[opt];

	getDP = function(name) {
		var width = undefined;
		var myregexp = /dp([\d]{1,3})/;
		var elem = jQuery(name);
		var text = elem.attr('class');

		var match = myregexp.exec(text);
		if (match != null) {
			width = match[1];
		} else {
			elem = jQuery(name).parent();
			text = elem.attr('class');
			match = myregexp.exec(text);
			if (match != null) {
				width = match[1]
			}
			else elem = undefined;
		}
		return {'width': width, 'elem': elem};
	}; // end function

	setDP = function(cmd, elem, target) {
		if (!elem || !target) return alert('elem or target undefined!');
		var newWidth = 0;
		if (cmd === 'hide') {
			newWidth = parseInt(target.width) + parseInt(elem.width);
			jQuery(elem.elem).hide();
			jQuery(target.elem).removeClass('dp'+target.width);
			jQuery(target.elem).addClass('dp'+newWidth);
		}
		else if (cmd === 'show') {
			newWidth = parseInt(target.width) - parseInt(elem.width);
			jQuery(elem.elem).show();
			jQuery(target.elem).removeClass('dp'+target.width);
			jQuery(target.elem).addClass('dp'+newWidth);			
		}
	}; // end function

	var mm = getDP('#mainMenu');
	var da = getDP('#displayArea');
	var sb = getDP('#sidebar');

	var cmd = co.chkShowRightSidebar?'show':'hide';
	setDP(cmd, sb, da);

	saveOptionCookie(opt);
	var labelShow=co.txtToggleRightSideBarLabelShow||'&#x25C4;';
	var labelHide=co.txtToggleRightSideBarLabelHide||'&#x25BA;';
	if (this.innerHTML==labelShow||this.innerHTML==labelHide) 
		this.innerHTML=show?labelHide:labelShow;
	this.title=(show?'hide':'show')+' Right sidebar';
	var sm=document.getElementById('storyMenu');
	if (sm) config.refreshers.content(sm);
	return false;
">$1</a></html>
!end
%/<<tiddler {{
	var src='ToggleRightSidebarEm';
	src+(tiddler&&tiddler.title==src?'##info':'##show');
}} with: {{
	var co=config.options;
	var labelShow=co.txtToggleRightSideBarLabelShow||'&#x25C4;';
	var labelHide=co.txtToggleRightSideBarLabelHide||'&#x25BA;';
	'$1'!='$'+'1'?'$1':(co.chkShowRightSidebar?labelHide:labelShow);
}} {{
	var tip=(config.options.chkShowRightSidebar?'hide':'show')+' Right sidebar';
	'$2'!='$'+'2'?'$2':tip;
}}>>
!Modifications
!!Menu bar
now [[looks like|http://legacy.earlham.edu/~markp/moodledocs/graphics/ingeneous-theme-menubar.png]]<<imagebox>>
* +++[styles.css]
{{{
     69 /* Menu */
     70
     71 #menubox{
     72    font-size : 0.95em;
     73 }
     74
     75 #menu {
     76     list-style:none;
     77   margin:0;
     78   padding:0;
     79 }
     80 #menu ul {
     81   float:left;
     82 }
     83
     84 #menu li {
     85   float:left;
     86 }
     87
     88 #menu a {
     89   display:block;
     90   padding:5px 10px;
     91 }
     92 #menu a:link,
     93 #menu a:visited {
     94 }
     95
     96 #menu a:hover,
     97 #menu a:active {
     98 }
     99
    100 #menu-date {
    101     list-style:none;
    102    margin: 0;
    103   padding : 5px 0;
    104   float: right;
    105 }
    106 #menu-date ul {
    107   text-align: right;
    108 }
    109
    110 #menu-date ul li a{
    111     display: block;
    112     color : #fff;
    113 }
}}}
=== 
* +++[menu.php]
{{{
      1         <?php
      2 echo '<ul  id="menu">';
      3 echo '<li class="home"><a href="'.$CFG->wwwroot.'/"><img width="18" height="17" src="'.$CFG->httpswwwroot.
         '/theme/'.current_theme().'/images/home_icon.png" alt="Home" title="Home" /></a>
      4         </li>';
      5 if (!isloggedin() or isguestuser()) {
      6 echo '<li><a href="'.$CFG->wwwroot.'/login/index.php">'.get_string('login').'</a></li></ul>';
      7 } else {
      8 echo '<li><a href="'.$CFG->wwwroot.'/login/logout.php">'.get_string('logout').'</a></li>';
      9 echo '<li><a href="'.$CFG->wwwroot.'/user/edit.php?id='.$USER->id.'&amp;course='.$COURSE->id.'">'.get_string
        ('updatemyprofile').'</a></li>';
     10 echo '<li><a href="'.$CFG->wwwroot.'/my">'.get_string('mycourses').'</a><li></ul>';
     11 }?>
     12 <?php
     13         echo '<ul id="menu-date">';
     14         echo '<li><a href="'.$CFG->httpswwwroot.'/calendar/view.php" title="Calendar">';
     15         echo userdate(date('U'));
     16         echo '</a></li></ul>';
     17 ?>
}}}
=== 
* +++[styles_select.css]
{{{
     18 #menu a:link,
     19 #menu a:visited,
     20 #menu-date a:link,
     21 #menu-date a:visited  {
     22   color:#fff;
     23 }
     24
     25 #menu a:hover,
     26 #menu a:active,
     27 #menu-date a:hover,
     28 #menu-date a:active {
     29   background:#922803;
     30 }
}}}
=== 
* +++[rename 'my courses']
in {{{lang/en_utf8/moodle.php}}} :
{{{
$string['mycourses'] = 'MyMoodle';
}}}
Change in lang/en_us_utf8 as well
=== 
!!Still to do
* change fonts +++[in header.html]
{{{
<html<?php echo $direction ?>>
<head>
    <?php echo $meta ?>
    <meta name="keywords" content="moodle, <?php echo $title ?> " />
    <title><?php echo $title ?></title>
    <link rel="shortcut icon" href="<?php echo $CFG->themewww .'/'. current_theme() ?>/favicon.ico" />
    <link
    href='http://fonts.googleapis.com/css?family=Ubuntu:500|Droid+Sans:400,700' rel='stylesheet' type='text/css'>
}}}
=== 
* adjust sizes +++[example]
{{{
    font-family: 'Open Sans', sans-serif;
    font-style: normal;
    font-weight: 400;
    font-size: 12px; 
}}}
=== 
* tweak +++[Treemenu]
{{{
.treeMenuDefault {
                font-size: 100%;
                font-style: normal;
            }

            .treeMenuBold {
                font-size: 100%;
                font-weight: bold;
            }
}}}
=== 
* +++[Collapsed topics course format styling]
''Change colours to suit''
{{{
/*********************
 * collapsed topics  *	
 *********************/
tr.cps {
        background-color: #CCB28F;
        color: #C60; /* 'Topic x' text colour */
}

/* Toggle text */
tr.cps td a {
        text-decoration: none;
        color: #310;
}

/* -- What happens when a toggle is hovered over -- */
tr.cps td a:hover {
        background-color: #FFE;
        color : #310;
        font-weight : bold;
        border-bottom : 0px;
}
}}}
=== 
/***
|Name:|TagglyTaggingPlugin|
|Description:|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
|Version:|3.3.1 ($Rev: 9828 $)|
|Date:|$Date: 2009-06-03 21:38:41 +1000 (Wed, 03 Jun 2009) $|
|Source:|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{

merge(String.prototype,{

	parseTagExpr: function(debug) {

		if (this.trim() == "")
			return "(true)";

		var anyLogicOp = /(!|&&|\|\||\(|\))/g;
		var singleLogicOp = /^(!|&&|\|\||\(|\))$/;

		var spaced = this.
			// because square brackets in templates are no good
			// this means you can use [(With Spaces)] instead of [[With Spaces]]
			replace(/\[\(/g," [[").
			replace(/\)\]/g,"]] "). 
			// space things out so we can use readBracketedList. tricky eh?
			replace(anyLogicOp," $1 ");

		var expr = "";

		var tokens = spaced.readBracketedList(false); // false means don't uniq the list. nice one JR!

		for (var i=0;i<tokens.length;i++)
			if (tokens[i].match(singleLogicOp))
				expr += tokens[i];
			else
				expr += "tiddler.tags.contains('%0')".format([tokens[i].replace(/'/,"\\'")]); // fix single quote bug. still have round bracket bug i think

		if (debug)
			alert(expr);

		return '('+expr+')';
	}

});

merge(TiddlyWiki.prototype,{
	getTiddlersByTagExpr: function(tagExpr,sortField) {

		var result = [];

		var expr = tagExpr.parseTagExpr();

		store.forEachTiddler(function(title,tiddler) {
			if (eval(expr))
				result.push(tiddler);
		});

		if(!sortField)
			sortField = "title";

		result.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
		
		return result;
	}
});

config.taggly = {

	// for translations
	lingo: {
		labels: {
			asc:        "\u2191", // down arrow
			desc:       "\u2193", // up arrow
			title:      "title",
			modified:   "modified",
			created:    "created",
			show:       "+",
			hide:       "-",
			normal:     "normal",
			group:      "group",
			commas:     "commas",
			sitemap:    "sitemap",
			numCols:    "cols\u00b1", // plus minus sign
			label:      "Tagged as '%0':",
			exprLabel:  "Matching tag expression '%0':",
			excerpts:   "excerpts",
			descr:      "descr",
			slices:     "slices",
			contents:   "contents",
			sliders:    "sliders",
			noexcerpts: "title only",
			noneFound:  "(none)"
		},

		tooltips: {
			title:      "Click to sort by title",
			modified:   "Click to sort by modified date",
			created:    "Click to sort by created date",
			show:       "Click to show tagging list",
			hide:       "Click to hide tagging list",
			normal:     "Click to show a normal ungrouped list",
			group:      "Click to show list grouped by tag",
			sitemap:    "Click to show a sitemap style list",
			commas:     "Click to show a comma separated list",
			numCols:    "Click to change number of columns",
			excerpts:   "Click to show excerpts",
			descr:      "Click to show the description slice",
			slices:     "Click to show all slices",
			contents:   "Click to show entire tiddler contents",
			sliders:    "Click to show tiddler contents in sliders",
			noexcerpts: "Click to show entire title only"
		},

		tooDeepMessage: "* //sitemap too deep...//"
	},

	config: {
		showTaggingCounts: true,
		listOpts: {
			// the first one will be the default
			sortBy:     ["title","modified","created"],
			sortOrder:  ["asc","desc"],
			hideState:  ["show","hide"],
			listMode:   ["normal","group","sitemap","commas"],
			numCols:    ["1","2","3","4","5","6"],
			excerpts:   ["noexcerpts","excerpts","descr","slices","contents","sliders"]
		},
		valuePrefix: "taggly.",
		excludeTags: ["excludeLists","excludeTagging"],
		excerptSize: 50,
		excerptMarker: "/%"+"%/",
		siteMapDepthLimit: 25
	},

	getTagglyOpt: function(title,opt) {
		var val = store.getValue(title,this.config.valuePrefix+opt);
		return val ? val : this.config.listOpts[opt][0];
	},

	setTagglyOpt: function(title,opt,value) {
		// create it silently if it doesn't exist
		if (!store.tiddlerExists(title)) {
			store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),"");

			// <<tagglyTagging expr:"...">> creates a tiddler to store its display settings
			// Make those tiddlers less noticeable by tagging as excludeSearch and excludeLists
			// Because we don't want to hide real tags, check that they aren't actually tags before doing so
			// Also tag them as tagglyExpression for manageability
			// (contributed by RA)
			if (!store.getTaggedTiddlers(title).length) {
				store.setTiddlerTag(title,true,"excludeSearch");
				store.setTiddlerTag(title,true,"excludeLists");
				store.setTiddlerTag(title,true,"tagglyExpression");
			}
		}

		// if value is default then remove it to save space
		return store.setValue(title, this.config.valuePrefix+opt, value == this.config.listOpts[opt][0] ? null : value);
	},

	getNextValue: function(title,opt) {
		var current = this.getTagglyOpt(title,opt);
		var pos = this.config.listOpts[opt].indexOf(current);
		// supposed to automagically don't let cols cycle up past the number of items
		// currently broken in some situations, eg when using an expression
		// lets fix it later when we rewrite for jquery
		// the columns thing should be jquery table manipulation probably
		var limit = (opt == "numCols" ? store.getTaggedTiddlers(title).length : this.config.listOpts[opt].length);
		var newPos = (pos + 1) % limit;
		return this.config.listOpts[opt][newPos];
	},

	toggleTagglyOpt: function(title,opt) {
		var newVal = this.getNextValue(title,opt);
		this.setTagglyOpt(title,opt,newVal);
	}, 

	createListControl: function(place,title,type) {
		var lingo = config.taggly.lingo;
		var label;
		var tooltip;
		var onclick;

		if ((type == "title" || type == "modified" || type == "created")) {
			// "special" controls. a little tricky. derived from sortOrder and sortBy
			label = lingo.labels[type];
			tooltip = lingo.tooltips[type];

			if (this.getTagglyOpt(title,"sortBy") == type) {
				label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
				onclick = function() {
					config.taggly.toggleTagglyOpt(title,"sortOrder");
					return false;
				}
			}
			else {
				onclick = function() {
					config.taggly.setTagglyOpt(title,"sortBy",type);
					config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
					return false;
				}
			}
		}
		else {
			// "regular" controls, nice and simple
			label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
			tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
			onclick = function() {
				config.taggly.toggleTagglyOpt(title,type);
				return false;
			}
		}

		// hide button because commas don't have columns
		if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
			createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
	},

	makeColumns: function(orig,numCols) {
		var listSize = orig.length;
		var colSize = listSize/numCols;
		var remainder = listSize % numCols;

		var upperColsize = colSize;
		var lowerColsize = colSize;

		if (colSize != Math.floor(colSize)) {
			// it's not an exact fit so..
			upperColsize = Math.floor(colSize) + 1;
			lowerColsize = Math.floor(colSize);
		}

		var output = [];
		var c = 0;
		for (var j=0;j<numCols;j++) {
			var singleCol = [];
			var thisSize = j < remainder ? upperColsize : lowerColsize;
			for (var i=0;i<thisSize;i++) 
				singleCol.push(orig[c++]);
			output.push(singleCol);
		}

		return output;
	},

	drawTable: function(place,columns,theClass) {
		var newTable = createTiddlyElement(place,"table",null,theClass);
		var newTbody = createTiddlyElement(newTable,"tbody");
		var newTr = createTiddlyElement(newTbody,"tr");
		for (var j=0;j<columns.length;j++) {
			var colOutput = "";
			for (var i=0;i<columns[j].length;i++) 
				colOutput += columns[j][i];
			var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
			wikify(colOutput,newTd);
		}
		return newTable;
	},

	createTagglyList: function(place,title,isTagExpr) {
		switch(this.getTagglyOpt(title,"listMode")) {
			case "group":  return this.createTagglyListGrouped(place,title,isTagExpr); break;
			case "normal": return this.createTagglyListNormal(place,title,false,isTagExpr); break;
			case "commas": return this.createTagglyListNormal(place,title,true,isTagExpr); break;
			case "sitemap":return this.createTagglyListSiteMap(place,title,isTagExpr); break;
		}
	},

	getTaggingCount: function(title,isTagExpr) {
		// thanks to Doug Edmunds
		if (this.config.showTaggingCounts) {
			var tagCount = config.taggly.getTiddlers(title,'title',isTagExpr).length;
			if (tagCount > 0)
				return " ("+tagCount+")";
		}
		return "";
	},

	getTiddlers: function(titleOrExpr,sortBy,isTagExpr) {
		return isTagExpr ? store.getTiddlersByTagExpr(titleOrExpr,sortBy) : store.getTaggedTiddlers(titleOrExpr,sortBy);
	},

	getExcerpt: function(inTiddlerTitle,title,indent) {
		if (!indent)
			indent = 1;

		var displayMode = this.getTagglyOpt(inTiddlerTitle,"excerpts");
		var t = store.getTiddler(title);

		if (t && displayMode == "excerpts") {
			var text = t.text.replace(/\n/," ");
			var marker = text.indexOf(this.config.excerptMarker);
			if (marker != -1) {
				return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";
			}
			else if (text.length < this.config.excerptSize) {
				return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";
			}
			else {
				return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";
			}
		}
		else if (t && displayMode == "contents") {
			return "\n{{contents indent"+indent+"{\n" + t.text + "\n}}}";
		}
		else if (t && displayMode == "sliders") {
			return "<slider slide>\n{{contents{\n" + t.text + "\n}}}\n</slider>";
		}
		else if (t && displayMode == "descr") {
			var descr = store.getTiddlerSlice(title,'Description');
			return descr ? " {{excerpt{" + descr  + "}}}" : "";
		}
		else if (t && displayMode == "slices") {
			var result = "";
			var slices = store.calcAllSlices(title);
			for (var s in slices)
				result += "|%0|<nowiki>%1</nowiki>|\n".format([s,slices[s]]);
			return result ? "\n{{excerpt excerptIndent{\n" + result  + "}}}" : "";
		}
		return "";
	},

	notHidden: function(t,inTiddler) {
		if (typeof t == "string") 
			t = store.getTiddler(t);
		return (!t || !t.tags.containsAny(this.config.excludeTags) ||
				(inTiddler && this.config.excludeTags.contains(inTiddler)));
	},

	// this is for normal and commas mode
	createTagglyListNormal: function(place,title,useCommas,isTagExpr) {

		var list = config.taggly.getTiddlers(title,this.getTagglyOpt(title,"sortBy"),isTagExpr);

		if (this.getTagglyOpt(title,"sortOrder") == "desc")
			list = list.reverse();

		var output = [];
		var first = true;
		for (var i=0;i<list.length;i++) {
			if (this.notHidden(list[i],title)) {
				var countString = this.getTaggingCount(list[i].title);
				var excerpt = this.getExcerpt(title,list[i].title);
				if (useCommas)
					output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);
				else
					output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\n");

				first = false;
			}
		}

		return this.drawTable(place,
			this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
			useCommas ? "commas" : "normal");
	},

	// this is for the "grouped" mode
	createTagglyListGrouped: function(place,title,isTagExpr) {
		var sortBy = this.getTagglyOpt(title,"sortBy");
		var sortOrder = this.getTagglyOpt(title,"sortOrder");

		var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);

		if (sortOrder == "desc")
			list = list.reverse();

		var leftOvers = []
		for (var i=0;i<list.length;i++)
			leftOvers.push(list[i].title);

		var allTagsHolder = {};
		for (var i=0;i<list.length;i++) {
			for (var j=0;j<list[i].tags.length;j++) {

				if (list[i].tags[j] != title) { // not this tiddler

					if (this.notHidden(list[i].tags[j],title)) {

						if (!allTagsHolder[list[i].tags[j]])
							allTagsHolder[list[i].tags[j]] = "";

						if (this.notHidden(list[i],title)) {
							allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
										+ this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\n";

							leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers

						}
					}
				}
			}
		}

		var allTags = [];
		for (var t in allTagsHolder)
			allTags.push(t);

		var sortHelper = function(a,b) {
			if (a == b) return 0;
			if (a < b) return -1;
			return 1;
		};

		allTags.sort(function(a,b) {
			var tidA = store.getTiddler(a);
			var tidB = store.getTiddler(b);
			if (sortBy == "title") return sortHelper(a,b);
			else if (!tidA && !tidB) return 0;
			else if (!tidA) return -1;
			else if (!tidB) return +1;
			else return sortHelper(tidA[sortBy],tidB[sortBy]);
		});

		var leftOverOutput = "";
		for (var i=0;i<leftOvers.length;i++)
			if (this.notHidden(leftOvers[i],title))
				leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\n";

		var output = [];

		if (sortOrder == "desc")
			allTags.reverse();
		else if (leftOverOutput != "")
			// leftovers first...
			output.push(leftOverOutput);

		for (var i=0;i<allTags.length;i++)
			if (allTagsHolder[allTags[i]] != "")
				output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\n" + allTagsHolder[allTags[i]]);

		if (sortOrder == "desc" && leftOverOutput != "")
			// leftovers last...
			output.push(leftOverOutput);

		return this.drawTable(place,
				this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
				"grouped");

	},

	// used to build site map
	treeTraverse: function(title,depth,sortBy,sortOrder,isTagExpr) {

		var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);

		if (sortOrder == "desc")
			list.reverse();

		var indent = "";
		for (var j=0;j<depth;j++)
			indent += "*"

		var childOutput = "";

		if (depth > this.config.siteMapDepthLimit)
			childOutput += indent + this.lingo.tooDeepMessage;
		else
			for (var i=0;i<list.length;i++)
				if (list[i].title != title)
					if (this.notHidden(list[i].title,this.config.inTiddler))
						childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder,false);

		if (depth == 0)
			return childOutput;
		else
			return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title,depth) + "\n" + childOutput;
	},

	// this if for the site map mode
	createTagglyListSiteMap: function(place,title,isTagExpr) {
		this.config.inTiddler = title; // nasty. should pass it in to traverse probably
		var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"),isTagExpr);
		return this.drawTable(place,
				this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
				"sitemap"
				);
	},

	macros: {
		tagglyTagging: {
			handler: function (place,macroName,params,wikifier,paramString,tiddler) {
				var parsedParams = paramString.parseParams("tag",null,true);
				var refreshContainer = createTiddlyElement(place,"div");

				// do some refresh magic to make it keep the list fresh - thanks Saq
				refreshContainer.setAttribute("refresh","macro");
				refreshContainer.setAttribute("macroName",macroName);

				var tag = getParam(parsedParams,"tag");
				var expr = getParam(parsedParams,"expr");

				if (expr) {
					refreshContainer.setAttribute("isTagExpr","true");
					refreshContainer.setAttribute("title",expr);
					refreshContainer.setAttribute("showEmpty","true");
				}
				else {
					refreshContainer.setAttribute("isTagExpr","false");
					if (tag) {
        				refreshContainer.setAttribute("title",tag);
						refreshContainer.setAttribute("showEmpty","true");
					}
					else {
        				refreshContainer.setAttribute("title",tiddler.title);
						refreshContainer.setAttribute("showEmpty","false");
					}
				}
				this.refresh(refreshContainer);
			},

			refresh: function(place) {
				var title = place.getAttribute("title");
				var isTagExpr = place.getAttribute("isTagExpr") == "true";
				var showEmpty = place.getAttribute("showEmpty") == "true";
				jQuery(place).empty()
				jQuery(place).addClass("tagglyTagging");
				var countFound = config.taggly.getTiddlers(title,'title',isTagExpr).length
				if (countFound > 0 || showEmpty) {
					var lingo = config.taggly.lingo;
					config.taggly.createListControl(place,title,"hideState");
					if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
						createTiddlyElement(place,"span",null,"tagglyLabel",
								isTagExpr ? lingo.labels.exprLabel.format([title]) : lingo.labels.label.format([title]));
						config.taggly.createListControl(place,title,"title");
						config.taggly.createListControl(place,title,"modified");
						config.taggly.createListControl(place,title,"created");
						config.taggly.createListControl(place,title,"listMode");
						config.taggly.createListControl(place,title,"excerpts");
						config.taggly.createListControl(place,title,"numCols");
						config.taggly.createTagglyList(place,title,isTagExpr);
						if (countFound == 0 && showEmpty)
							createTiddlyElement(place,"div",null,"tagglyNoneFound",lingo.labels.noneFound);
					}
				}
			}
		}
	},

	// todo fix these up a bit
	styles: [
"/*{{{*/",
"/* created by TagglyTaggingPlugin */",
".tagglyTagging { padding-top:0.5em; }",
".tagglyTagging li.listTitle { display:none; }",
".tagglyTagging ul {",
"	margin-top:0px; padding-top:0.5em; padding-left:2em;",
"	margin-bottom:0px; padding-bottom:0px;",
"}",
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",
".tagglyTagging table { margin:0px; padding:0px; }",
".tagglyTagging .button { visibility:hidden; margin-left:3px; margin-right:3px; }",
".tagglyTagging .button, .tagglyTagging .hidebutton {",
"	color:[[ColorPalette::TertiaryLight]]; font-size:90%;",
"	border:0px; padding-left:0.3em;padding-right:0.3em;",
"}",
".tagglyTagging .button:hover, .hidebutton:hover, ",
".tagglyTagging .button:active, .hidebutton:active  {",
"	border:0px; background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",
"}",
".selected .tagglyTagging .button { visibility:visible; }",
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",
".tagglyTagging ul ul li {margin-left:0.5em; }",
".editLabel { font-size:90%; padding-top:0.5em; }",
".tagglyTagging .commas { padding-left:1.8em; }",
"/* not technically tagglytagging but will put them here anyway */",
".tagglyTagged li.listTitle { display:none; }",
".tagglyTagged li { display: inline; font-size:90%; }",
".tagglyTagged ul { margin:0px; padding:0px; }",
".excerpt { color:[[ColorPalette::TertiaryDark]]; }",
".excerptIndent { margin-left:4em; }",
"div.tagglyTagging table,",
"div.tagglyTagging table tr,",
"td.tagglyTagging",
" {border-style:none!important; }",
".tagglyTagging .contents { border-bottom:2px solid [[ColorPalette::TertiaryPale]]; padding:0 1em 1em 0.5em;",
"  margin-bottom:0.5em; }",
".tagglyTagging .indent1  { margin-left:3em;  }",
".tagglyTagging .indent2  { margin-left:4em;  }",
".tagglyTagging .indent3  { margin-left:5em;  }",
".tagglyTagging .indent4  { margin-left:6em;  }",
".tagglyTagging .indent5  { margin-left:7em;  }",
".tagglyTagging .indent6  { margin-left:8em;  }",
".tagglyTagging .indent7  { margin-left:9em;  }",
".tagglyTagging .indent8  { margin-left:10em; }",
".tagglyTagging .indent9  { margin-left:11em; }",
".tagglyTagging .indent10 { margin-left:12em; }",
".tagglyNoneFound { margin-left:2em; color:[[ColorPalette::TertiaryMid]]; font-size:90%; font-style:italic; }",
"/*}}}*/",
		""].join("\n"),

	init: function() {
		merge(config.macros,this.macros);
		config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
		store.addNotification("TagglyTaggingStyles",refreshStyles);
	}
};

config.taggly.init();

//}}}

/***
InlineSlidersPlugin
By Saq Imtiaz
http://tw.lewcid.org/sandbox/#InlineSlidersPlugin

// syntax adjusted to not clash with NestedSlidersPlugin
// added + syntax to start open instead of closed

***/
//{{{
config.formatters.unshift( {
	name: "inlinesliders",
	// match: "\\+\\+\\+\\+|\\<slider",
	match: "\\<slider",
	// lookaheadRegExp: /(?:\+\+\+\+|<slider) (.*?)(?:>?)\n((?:.|\n)*?)\n(?:====|<\/slider>)/mg,
	lookaheadRegExp: /(?:<slider)(\+?) (.*?)(?:>)\n((?:.|\n)*?)\n(?:<\/slider>)/mg,
	handler: function(w) {
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart ) {
			var btn = createTiddlyButton(w.output,lookaheadMatch[2] + " "+"\u00BB",lookaheadMatch[2],this.onClickSlider,"button sliderButton");
			var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
			panel.style.display = (lookaheadMatch[1] == '+' ? "block" : "none");
			wikify(lookaheadMatch[3],panel);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
   },
   onClickSlider : function(e) {
		if(!e) var e = window.event;
		var n = this.nextSibling;
		n.style.display = (n.style.display=="none") ? "block" : "none";
		return false;
	}
});

//}}}
!Workshop #1
;Where : 
:Landrum Bolling Center room 124
;When :
: Wednesday August 8th
!!Schedule
| ''Time'' | ''Topic'' | ''Details'' |
| 8:30| Getting started |bring own laptop, get setup with power, boot up & logon to Moodle, navigate to Testing category|
|~| Introductions |<<tiddlerbox "Format of workshop" "Workshop format" "Ideal sequence of workshop activities">>  Coffee |
| 9:00| Managing large classes : [[Attendance & Participation]] |Creation, configuration, taking attendance, auto grading|
| 10:30|>| @@Coffee break@@ |
| 11:00| Getting the most from the gradebook : have Moodle do the Math |Setting it up, adding grades, display to students|
| 12:30|>| @@lunch@@ |
| 1:30| Making meaningful collaboration the easy way |cover the setting up & use of groups, Forums, ~OUWiki|
| 3:00|>| @@Tea time@@ |
| 3:30| Putting it all together -- managing a large lecture class with moodle |Julie May will show us some of the moodle features she has used to effectively manage her large lecture classes. Quiz, essay questions, gradebook|
+++!![Participants]
<<tiddler [[Aug 8 Workshop Participants]]>>
=== 
[[Additional workshop|Workshop : alternate date]] on Friday Aug 17th ?
I want to take Dan Graves' Jazz History (MUS369:201220) course backup and use it to illustrate the gradebook. But I have to anonymize the user details so that real student names are not shown.
Here's what to try:
# Make a course backup with just user account details and grade hisotries.
# Transfer to PC for processing.
# unzip backup and open up index.xml in text editor
# Find "USERNAME" field.
# +++[Substitute fields]
{{{
        <USERNAME>kkasik10</USERNAME>
        <IDNUMBER>774775</IDNUMBER>
        <FIRSTNAME>Kubra</FIRSTNAME>
        <LASTNAME>Kasikci</LASTNAME>
        <EMAIL>kkasik10@earlham.edu</EMAIL>

username : harryp
idnumber : same ?
firstname: Harry
Lastname : Potter
Email : harryp@wondershock.net
}}}
=== with Hogwarts user details
# delete users not needed (eg refneal, refamy)
# Save and rezip

Actual process here : [[Dummy course construction]]
! About
This tiddler, is designed, to be overwritten in your space. It should contain a more detailed information about your space. The basic overview is SiteInfo, which you may want to overwrite too, if it still contains the @nuei-em info.

Some tiddlers eg: SiteInfo, may contain hidden information covered by{{{/% %/}}}. This info is only seen in edit mode, and contains stuff, about tweaking the theme.

!!!! Theme History
* V 0.6.7 - 2012.01.04
* ...
* V 0.5.1 - 2010.08.11
* V 0.5.0 - initial release

The full theme history can be seen at: 
http://neui-em.tiddlyspace.com/_/9ddb6837-854b-4fdd-b2aa-a1a4bd5d523a
/***
|Name|NestedSlidersPlugin|
|Source|http://www.TiddlyTools.com/#NestedSlidersPlugin|
|Documentation|http://www.TiddlyTools.com/#NestedSlidersPluginInfo|
|Version|2.4.9|
|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||
|Options|##Configuration|
|Description|show content in nest-able sliding/floating panels, without creating separate tiddlers for each panel's content|
!!!!!Documentation
>see [[NestedSlidersPluginInfo]]
!!!!!Configuration
<<<
<<option chkFloatingSlidersAnimate>> allow floating sliders to animate when opening/closing
>Note: This setting can cause 'clipping' problems in some versions of InternetExplorer.
>In addition, for floating slider animation to occur you must also allow animation in general (see [[AdvancedOptions]]).
<<<
!!!!!Revisions
<<<
2008.11.15 - 2.4.9 in adjustNestedSlider(), don't make adjustments if panel is marked as 'undocked' (CSS class).  In onClickNestedSlider(), SHIFT-CLICK docks panel (see [[MoveablePanelPlugin]])
|please see [[NestedSlidersPluginInfo]] for additional revision details|
2005.11.03 - 1.0.0 initial public release.  Thanks to RodneyGomes, GeoffSlocock, and PaulPetterson for suggestions and experiments.
<<<
!!!!!Code
***/
//{{{
version.extensions.NestedSlidersPlugin= {major: 2, minor: 4, revision: 9, date: new Date(2008,11,15)};

// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkFloatingSlidersAnimate===undefined)
	config.options.chkFloatingSlidersAnimate=false; // avoid clipping problems in IE

// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
	background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");

// if removeCookie() function is not defined by TW core, define it here.
if (window.removeCookie===undefined) {
	window.removeCookie=function(name) {
		document.cookie = name+'=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;'; 
	}
}

config.formatters.push( {
	name: "nestedSliders",
	match: "\\n?\\+{3}",
	terminator: "\\s*\\={3}\\n?",
	lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\@\\[\\>]*\\^)?)?(\\*)?(\\@)?(?:\\{\\{([\\w]+[\\s\\w]*)\\{)?(\\[[^\\]]*\\])?(\\[[^\\]]*\\])?(?:\\}{3})?(\\#[^:]*\\:)?(\\>)?(\\.\\.\\.)?\\s*",
	handler: function(w)
		{
			lookaheadRegExp = new RegExp(this.lookahead,"mg");
			lookaheadRegExp.lastIndex = w.matchStart;
			var lookaheadMatch = lookaheadRegExp.exec(w.source)
			if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
				var defopen=lookaheadMatch[1];
				var cookiename=lookaheadMatch[2];
				var header=lookaheadMatch[3];
				var panelwidth=lookaheadMatch[4];
				var transient=lookaheadMatch[5];
				var hover=lookaheadMatch[6];
				var buttonClass=lookaheadMatch[7];
				var label=lookaheadMatch[8];
				var openlabel=lookaheadMatch[9];
				var panelID=lookaheadMatch[10];
				var blockquote=lookaheadMatch[11];
				var deferred=lookaheadMatch[12];

				// location for rendering button and panel
				var place=w.output;

				// default to closed, no cookie, no accesskey, no alternate text/tip
				var show="none"; var cookie=""; var key="";
				var closedtext=">"; var closedtip="";
				var openedtext="<"; var openedtip="";

				// extra "+", default to open
				if (defopen) show="block";

				// cookie, use saved open/closed state
				if (cookiename) {
					cookie=cookiename.trim().slice(1,-1);
					cookie="chkSlider"+cookie;
					if (config.options[cookie]==undefined)
						{ config.options[cookie] = (show=="block") }
					show=config.options[cookie]?"block":"none";
				}

				// parse label/tooltip/accesskey: [label=X|tooltip]
				if (label) {
					var parts=label.trim().slice(1,-1).split("|");
					closedtext=parts.shift();
					if (closedtext.substr(closedtext.length-2,1)=="=")	
						{ key=closedtext.substr(closedtext.length-1,1); closedtext=closedtext.slice(0,-2); }
					openedtext=closedtext;
					if (parts.length) closedtip=openedtip=parts.join("|");
					else { closedtip="show "+closedtext; openedtip="hide "+closedtext; }
				}

				// parse alternate label/tooltip: [label|tooltip]
				if (openlabel) {
					var parts=openlabel.trim().slice(1,-1).split("|");
					openedtext=parts.shift();
					if (parts.length) openedtip=parts.join("|");
					else openedtip="hide "+openedtext;
				}

				var title=show=='block'?openedtext:closedtext;
				var tooltip=show=='block'?openedtip:closedtip;

				// create the button
				if (header) { // use "Hn" header format instead of button/link
					var lvl=(header.length>5)?5:header.length;
					var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,buttonClass,title);
					btn.onclick=onClickNestedSlider;
					btn.setAttribute("href","javascript:;");
					btn.setAttribute("title",tooltip);
				}
				else
					var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider,buttonClass);
				btn.innerHTML=title; // enables use of HTML entities in label

				// set extra button attributes
				btn.setAttribute("closedtext",closedtext);
				btn.setAttribute("closedtip",closedtip);
				btn.setAttribute("openedtext",openedtext);
				btn.setAttribute("openedtip",openedtip);
				btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
				btn.defOpen=defopen!=null; // save default open/closed state (boolean)
				btn.keyparam=key; // save the access key letter ("" if none)
				if (key.length) {
					btn.setAttribute("accessKey",key); // init access key
					btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
				}
				btn.setAttribute("hover",hover?"true":"false");
				btn.onmouseover=function(ev) {
					// optional 'open on hover' handling
					if (this.getAttribute("hover")=="true" && this.sliderPanel.style.display=='none') {
						document.onclick.call(document,ev); // close transients
						onClickNestedSlider(ev); // open this slider
					}
					// mouseover on button aligns floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this,this.sliderPanel);
				}

				// create slider panel
				var panelClass=panelwidth?"floatingPanel":"sliderPanel";
				if (panelID) panelID=panelID.slice(1,-1); // trim off delimiters
				var panel=createTiddlyElement(place,"div",panelID,panelClass,null);
				panel.button = btn; // so the slider panel know which button it belongs to
				btn.sliderPanel=panel; // so the button knows which slider panel it belongs to
				panel.defaultPanelWidth=(panelwidth && panelwidth.length>2)?panelwidth.slice(1,-1):"";
				panel.setAttribute("transient",transient=="*"?"true":"false");
				panel.style.display = show;
				panel.style.width=panel.defaultPanelWidth;
				panel.onmouseover=function(event) // mouseover on panel aligns floater position with button
					{ if (window.adjustSliderPos) window.adjustSliderPos(this.parentNode,this.button,this); }

				// render slider (or defer until shown) 
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				if ((show=="block")||!deferred) {
					// render now if panel is supposed to be shown or NOT deferred rendering
					w.subWikify(blockquote?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
					// align floater position with button
					if (window.adjustSliderPos) window.adjustSliderPos(place,btn,panel);
				}
				else {
					var src = w.source.substr(w.nextMatch);
					var endpos=findMatchingDelimiter(src,"+++","===");
					panel.setAttribute("raw",src.substr(0,endpos));
					panel.setAttribute("blockquote",blockquote?"true":"false");
					panel.setAttribute("rendered","false");
					w.nextMatch += endpos+3;
					if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
				}
			}
		}
	}
)

function findMatchingDelimiter(src,starttext,endtext) {
	var startpos = 0;
	var endpos = src.indexOf(endtext);
	// check for nested delimiters
	while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
		// count number of nested 'starts'
		var startcount=0;
		var temp = src.substring(startpos,endpos-1);
		var pos=temp.indexOf(starttext);
		while (pos!=-1)  { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
		// set up to check for additional 'starts' after adjusting endpos
		startpos=endpos+endtext.length;
		// find endpos for corresponding number of matching 'ends'
		while (startcount && endpos!=-1) {
			endpos = src.indexOf(endtext,endpos+endtext.length);
			startcount--;
		}
	}
	return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	while (theTarget && theTarget.sliderPanel==undefined) theTarget=theTarget.parentNode;
	if (!theTarget) return false;
	var theSlider = theTarget.sliderPanel;
	var isOpen = theSlider.style.display!="none";

	// if SHIFT-CLICK, dock panel first (see [[MoveablePanelPlugin]])
	if (e.shiftKey && config.macros.moveablePanel) config.macros.moveablePanel.dock(theSlider,e);

	// toggle label
	theTarget.innerHTML=isOpen?theTarget.getAttribute("closedText"):theTarget.getAttribute("openedText");
	// toggle tooltip
	theTarget.setAttribute("title",isOpen?theTarget.getAttribute("closedTip"):theTarget.getAttribute("openedTip"));

	// deferred rendering (if needed)
	if (theSlider.getAttribute("rendered")=="false") {
		var place=theSlider;
		if (theSlider.getAttribute("blockquote")=="true")
			place=createTiddlyElement(place,"blockquote");
		wikify(theSlider.getAttribute("raw"),place);
		theSlider.setAttribute("rendered","true");
	}

	// show/hide the slider
	if(config.options.chkAnimate && (!hasClass(theSlider,'floatingPanel') || config.options.chkFloatingSlidersAnimate))
		anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		theSlider.style.display = isOpen ? "none" : "block";

	// reset to default width (might have been changed via plugin code)
	theSlider.style.width=theSlider.defaultPanelWidth;

	// align floater panel position with target button
	if (!isOpen && window.adjustSliderPos) window.adjustSliderPos(theSlider.parentNode,theTarget,theSlider);

	// if showing panel, set focus to first 'focus-able' element in panel
	if (theSlider.style.display!="none") {
		var ctrls=theSlider.getElementsByTagName("*");
		for (var c=0; c<ctrls.length; c++) {
			var t=ctrls[c].tagName.toLowerCase();
			if ((t=="input" && ctrls[c].type!="hidden") || t=="textarea" || t=="select")
				{ try{ ctrls[c].focus(); } catch(err){;} break; }
		}
	}
	var cookie=theTarget.sliderCookie;
	if (cookie && cookie.length) {
		config.options[cookie]=!isOpen;
		if (config.options[cookie]!=theTarget.defOpen) window.saveOptionCookie(cookie);
		else window.removeCookie(cookie); // remove cookie if slider is in default display state
	}

	// prevent SHIFT-CLICK from being processed by browser (opens blank window... yuck!)
	// prevent clicks *within* a slider button from being processed by browser
	// but allow plain click to bubble up to page background (to close transients, if any)
	if (e.shiftKey || theTarget!=resolveTarget(e))
		{ e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); }
	Popup.remove(); // close open popup (if any)
	return false;
}
//}}}
//{{{
// click in document background closes transient panels 
document.nestedSliders_savedOnClick=document.onclick;
document.onclick=function(ev) { if (!ev) var ev=window.event; var target=resolveTarget(ev);

	if (document.nestedSliders_savedOnClick)
		var retval=document.nestedSliders_savedOnClick.apply(this,arguments);
	// if click was inside a popup... leave transient panels alone
	var p=target; while (p) if (hasClass(p,"popup")) break; else p=p.parentNode;
	if (p) return retval;
	// if click was inside transient panel (or something contained by a transient panel), leave it alone
	var p=target; while (p) {
		if ((hasClass(p,"floatingPanel")||hasClass(p,"sliderPanel"))&&p.getAttribute("transient")=="true") break;
		p=p.parentNode;
	}
	if (p) return retval;
	// otherwise, find and close all transient panels...
	var all=document.all?document.all:document.getElementsByTagName("DIV");
	for (var i=0; i<all.length; i++) {
		 // if it is not a transient panel, or the click was on the button that opened this panel, don't close it.
		if (all[i].getAttribute("transient")!="true" || all[i].button==target) continue;
		// otherwise, if the panel is currently visible, close it by clicking it's button
		if (all[i].style.display!="none") window.onClickNestedSlider({target:all[i].button})
		if (!hasClass(all[i],"floatingPanel")&&!hasClass(all[i],"sliderPanel")) all[i].style.display="none";
	}
	return retval;
};
//}}}
//{{{
// adjust floating panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel) {
	if (hasClass(panel,"floatingPanel") && !hasClass(panel,"undocked")) {
		// see [[MoveablePanelPlugin]] for use of 'undocked'
		var rightEdge=document.body.offsetWidth-1;
		var panelWidth=panel.offsetWidth;
		var left=0;
		var top=btn.offsetHeight; 
		if (place.style.position=="relative" && findPosX(btn)+panelWidth>rightEdge) {
			left-=findPosX(btn)+panelWidth-rightEdge; // shift panel relative to button
			if (findPosX(btn)+left<0) left=-findPosX(btn); // stay within left edge
		}
		if (place.style.position!="relative") {
			var left=findPosX(btn);
			var top=findPosY(btn)+btn.offsetHeight;
			var p=place; while (p && !hasClass(p,'floatingPanel')) p=p.parentNode;
			if (p) { left-=findPosX(p); top-=findPosY(p); }
			if (left+panelWidth>rightEdge) left=rightEdge-panelWidth;
			if (left<0) left=0;
		}
		panel.style.left=left+"px"; panel.style.top=top+"px";
	}
}
//}}}
//{{{
// TW2.1 and earlier:
// hijack Slider stop handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function()
	{ this.coreStop.apply(this,arguments); this.element.style.overflow = "visible"; }

// TW2.2+
// hijack Morpher stop handler so sliderPanel/floatingPanel overflow is visible after animation has completed
if (version.major+.1*version.minor+.01*version.revision>=2.2) {
	Morpher.prototype.coreStop = Morpher.prototype.stop;
	Morpher.prototype.stop = function() {
		this.coreStop.apply(this,arguments);
		var e=this.element;
		if (hasClass(e,"sliderPanel")||hasClass(e,"floatingPanel")) {
			// adjust panel overflow and position after animation
			e.style.overflow = "visible";
			if (window.adjustSliderPos) window.adjustSliderPos(e.parentNode,e.button,e);
		}
	};
}
//}}}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onclick="if(jQuery) jQuery(document).trigger('cNewTiddler', {elem:this, comp:{menue:1}})" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})" title="Create a new tiddler">
 <metadata id="metadata14">
  <rdf:RDF>
   <cc:Work rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
    <dc:title/>
    <dc:rights>
     <cc:Agent>
      <dc:title>http://creativecommons.org/licenses/by-nc-sa/3.0/at/</dc:title>
     </cc:Agent>
    </dc:rights>
    <dc:source>http://iconbuilder.tiddlyspace.com</dc:source>
    <dc:creator>
     <cc:Agent>
      <dc:title>Mario Pietsch</dc:title>
     </cc:Agent>
    </dc:creator>
   </cc:Work>
  </rdf:RDF>
 </metadata>
 <defs id="defs_bBgTrans">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#6BB546" offset="0"/>
   <stop id="stop2" stop-color="#B5DAA2" offset="0.66462"/>
   <stop id="stop3" stop-color="#6BB546" offset="1"/>
  </linearGradient></defs>
<g id="icon">
 <rect id="iconBG" stroke="#696969" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" fill="none" class="showBG"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0,-1,1,0,0,0)" width="22" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showFG"/>
<g id="iconSymbol" stroke-linejoin="miter" transform="translate(0.17754196,0)" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" stroke-dasharray="none" fill="none" class="showSY">
  <path d="m21.585,50.448,7.3934-0.000001,0,4.5527,4.3752,0,0,10.101-11.769,0z" stroke-width="1.6"/>
  <path d="m29.712,50.447,3.644,3.8077" stroke-width="1.60000002"/>
 </g>
 <rect id="overlay" stroke="#696969" opacity="0" ry="4.1663" transform="matrix(0,-1,1,0,0,0)" height="25" width="25" y="15.167" x="-70.116" stroke-width="1.2" class="showOV"/>
</g>
</svg>
!You like the Neui-em stuff?
#Create a tiddler named "~@neui-em"
#Tag this tiddler "like"
!!Who likes Neui-em theme
<<tsScan @neui-em tag:like fat:y template:"Like##like">> 

!Important
This tiddler should contain the activity macro which is part of the @following space.
If you want to use it, you need to go to backstage and include it.

/%
!like
<<image http://$1.tiddlyspace.com/bags/$1_public/tiddlers/SiteIcon 24 24>> @$1 likes FreeStyle suff :)
<<<
<<view text text>>
<<<
!end
%/
[[posting to backup forum at moodle.org|http://moodle.org/mod/forum/discuss.php?d=194089#p845487]]
<<<
OK, so I had a moodle v2.1 test install and I wanted to copy the front page stuff (which I'd spent a long time setting up) into a fresh 2.2 install (Moodle 2.2.1+ (Build: 20120112)). So I do a front page backup (at least that's what I thought I did, the filename is backup-moodle2-course-omio-20120117-1058.mbz) and having successfully created the new 2.2 site I do a front page restore. Then I get the unwelcome error message :

Error 500: restoring over front page is not allowed

I used the menu path Settings : Front page settings : Backup and then the same path with Restore which seemed logical at the time Spock.

Now I see that there's an additional separate menu path, namely:

Site Administration : Front page : Front page Backup and Front page restore.

However, when I use Front page restore it gives an 'Internal server misconfiguration' error on URL /files/index.php?id=1&wdir=%2Fbackupdata . I suspect this is because the backup was not done to this location but I don't know for certain.

Questions:

    Why are there two separate places to perform a front page backup & restore (seemingly a single functionality)?
    How can I restore the front page content from my other site since neither 'front page restore' menu option works for me?

Thanks for any help, messages of commiseration, acknowledgment of my stupidity.

Mark
<<<
Once you have some content then you may choose to determine a tiddler, or set of tiddlers to display each time you load ~TiddlySpace. This is determined by the [[DefaultTiddlers]].
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
	<title>This Space</title>
	<link href="/bags/common/tiddlers/profile.css" type='text/css' rel='stylesheet' >
	<link href="/bags/common/tiddlers/admin.css" type='text/css' rel='stylesheet' >
	<!--[if lte IE 8]>
	<script type="text/javascript" src="/bags/common/tiddlers/json2.js"></script>
	<script type="text/javascript" src="/bags/common/tiddlers/es5-shim.min.js"></script>
	<![endif]-->
</head>
<body>
<div id="container">
	<div id="text-html" class="main section">
		<a class="app" href="/">home</a>
		<div class="left">
		<h2>About this space <button class='toggleNext'></button></h2>
		<div id="siteinfo"></div>
		<h2>Site Icon</h2>
		<div>
			<img id="siteicon" class="siteicon">
			<form id="upload" method="POST" enctype="multipart/form-data">
				<input type="hidden" name="title" value="SiteIcon" />
				<input type="hidden" name="tags" value="excludeLists">
				<input type="hidden" name="csrf_token" class="csrf" />
				<input type="file" name="file" accept="image/*" />
				<input class="btn" type="submit" value="upload" />
			</form>
			<div id="dropzone">Drop file here
				<img class="notloading" src="/bags/common/tiddlers/ajax-loader.gif" alt="submitting SiteIcon" />
			</div>
		</div>
		<h2>Vital Statistics</h2>
		<div id="info">please wait while information is loaded about this space...</div>
		<button class="spacereset">Reset Space</button>
		<div class="reset-confirm-wrap messageArea">
			<button class="close-btn" title="cancel reset">×</button>
			<p>Are you sure you want to reset the space? You can't go back! This will remove all the content from the space!</p>
			<form class="cf">
				<label for="reset-confirm">Enter the space name to confirm.</label>
				<input type="text" name="reset-confirm" class="reset-confirm-input inputBox" />
				<button type="submit">Reset Now</button>
			</form>
			<div class="reset-message-area">
				<p class="performing">Resetting...</p>
				<p class="finished">Reset Done!</p>
				<p class="recipe-error-msg">Error removing includes. Please remove manually.</p>
			</div>
		</div>
		</div>
		<div class="right">
		<div class="ts-membership">
			<h2>
				Add Member
				<a href="http://docs.tiddlyspace.com/What%20is%20a%20member%3F" title="What is a Member?" class="help">What is a Member?</a>
			</h2>
			<div>
				<p>Add a new member to your space by entering their name below. Enter a space name instead and prefix with @ to add everyone who is already a member of that space.</p>
				<form class="ts-members">
					<input class="inputBox" type="text" name="username">
					<input type="submit" value="Add Member" class="btn" />
				</form>
			</div>
			<h2>
				Existing Members <button class='toggleNext'></button>
			</h2>
			<div>
				Your space currently has the following members: 
				<ul class="ts-members"></ul>
			</div>
			<h2>
				Include Space
				<a class="help" href="http://docs.tiddlyspace.com/What%20is%20space%20inclusion%3F" title="What is inclusion?">What is Inclusion?</a>
			</h2>
			<form class="ts-includes">
				<input class="inputBox" type="text" name="spacename">
				<input type="submit" value="Include Space" class="btn" />
			</form>
		</div>
		<div>
			<h2>Included Spaces <button class='toggleNext'></button></h2>
			<div>
			This space includes the following spaces:
			<ul class="ts-includes"></ul>
			</div>
		</div>
		</div>
		<div class="clear"></div>
	</div>
</div>
<script src='/bags/common/tiddlers/backstage.js'></script>
<script src='/bags/common/tiddlers/jquery.js'></script>
<script src='/bags/tiddlyspace/tiddlers/chrjs'></script>
<script src='/bags/common/tiddlers/chrjs.space'></script>
<script src='/bags/common/tiddlers/chrjs.users'></script>
<script src='/bags/common/tiddlers/chrjs.identities'></script>
<script src='/bags/tiddlyspace/tiddlers/TiddlySpaceCSRF'></script>
<script src='/bags/common/tiddlers/jquery-form.js'></script>
<script src="/bags/common/tiddlers/siteiconupload.js"></script>
<script src="/bags/common/tiddlers/ts.js"></script>
<script src="/status.js"></script>
<script src="/bags/common/tiddlers/space.js"></script>
</body>
</html>
Firefox v11 (WIndows or Mac) breaks the TinyMCE version embedded into CLAMP LAE 1.9.11 and Moodle 2.1 (not sure about 2.2). The 2^^nd^^ or third instance in a single window are unusable.
* From [[Firefox 11 has incompability with Moodle's TinyMCE version|http://tracker.moodle.org/browse/MDL-32123]] there's a workaround :
>If users resize the editor box with the bottom right corner drag handle the editor will become usable.
* Also [[outdated TinyMCE in 2.1.x does not work in Firefox 11|http://tracker.moodle.org/browse/MDL-32141]]
* Also on [[CLAMP Moodle Exchange|http://cme.clamp-it.org/mod/forum/discuss.php?d=759]]
CLAMP developers are working on updating to TinyMCE 3.5b2.
* Also [[Latest FF update locks down multiple TinyMCE instances|http://www.tinymce.com/develop/bugtracker_view.php?id=5089]] +++[Comment -- fixed]
elygre 12012-03-23
The Mozilla guys have fixed this in their latest nightly build. The following little comments are from the thread:
>"I really wish more people would test the Aurora/Beta builds. The problem has been present since early December 2011, and this is the first we heard of it. :("
and
>"This should be fixed in the next nightly, someone should test [...]"
----
{{ts{26/03/12 12:42}}} I was unable to find this comment using a google search -- I suspect that it's from the Mozilla nightly build email mailing list.
=== Test this with latest version of v11 Firefox. 
I found it! 
As mentioned [[Firefox/Channels/Meetings/2012-03-22|https://wiki.mozilla.org/Firefox/Channels/Meetings/2012-03-22]] :
<<<
Roundtable
*    Mambo/TinyMCE (and more?) are affected by [[bug 737784 – WYWSIWYG editor in mambo ceases to visualise following update to Firefox11|https://bugzilla.mozilla.org/show_bug.cgi?id=737784]]. /2012-03-22
<<<
User-agent: *
Disallow: /bags
Disallow: /recipes
/***
|''Name''|ErrorHandlerPlugin|
|''Version''|0.4.3|
|''Author''|Jon Robson|
|''Description''|Localised tiddler save errors including edit conflict resolution.|
|''CoreVersion''|2.6.1|
|''Requires''|TiddlySpaceConfig|
***/
//{{{
(function($) {

var tiddlyspace = config.extensions.tiddlyspace;
var currentSpace = tiddlyspace.currentSpace.name;
tiddlyspace.getLocalTitle = function(title, workspace, suffix) {
	var endsWith = config.extensions.BinaryTiddlersPlugin.endsWith;
	if(!suffix) {
		var isPublic = endsWith(workspace, "_public");
		suffix = tiddlyspace.resolveSpaceName(workspace);
		if(currentSpace == suffix) {
			suffix = isPublic ? "public" : "private";
		} else {
			suffix = "@%0".format(suffix);
		}
	}
	return "%0 *(%1)*".format(title, suffix);
};

var sssp = config.extensions.ServerSideSavingPlugin;

var msgs = config.messages.editConflict = {
	loading: "Loading..",
	resolve: "[[Edit Conflict]]@glossary: this tiddler may have been changed by someone else.",
	reviewDiff: "review (recommended)",
	reviewDiffTooltip: "review changes made to this tiddler",
	reviewDiffError: "error retrieving revision.",
	save: "overwrite",
	saveTooltip: "make this revision the top revision of this tiddler",
	discard: "cancel",
	discardTooltip: "undo changes to this tiddler and get most recent version",
	diffTitle: "%0",
	diffFieldTitle: "%0 - fields",
	diffTextTitle: "%0 - text",
	updating: "updating your version...",
	diffHeader: ["Review the changes that have been made whilst you were editing this tiddler. ",
		"Fold relevant changes back into your version.\n",
		"{{removed{Red}}} highlight shows content removed. ",
		"{{added{Green}}} highlight shows content added.\n"].join(""),
	diffTextHeader: "View changes in text",
	diffFieldsHeader: "View changes in fields"
};

var plugin = config.extensions.errorHandler = {
	diffTags: ["excludeLists", "excludeMissing", "excludeSearch"],
	displayMessage: function(message, tiddler, context) {
		var desc = context && context.httpStatus ? context.statusText :
			sssp.locale.connectionError;
		var reportArea = plugin.reportError(tiddler.title);
		var msg = $("<div />").appendTo(reportArea);
		if(message == "saveConflict") {
			wikify(msgs.resolve, msg[0]);
			var choiceArea = $("<div />").appendTo(reportArea)[0];
			plugin.editConflictHandler(choiceArea, tiddler);
		} else {
			msg.text(sssp.locale[message].format(tiddler.title, desc));
		}
	},
	editConflictHandler: function(container, tiddler) {
		var title = tiddler.title;
		var myrev = tiddler.fields["server.page.revision"];
		// note user now needs to edit, fix problem and save. 
		// TODO: make sure this gets reset in save callback
		store.getTiddler(title).fields["server.page.revision"] = "false";

		var diffBtn = createTiddlyButton(container, msgs.reviewDiff, msgs.reviewDiffTooltip, function(ev) {
			var title = $(ev.target).data("title");
			plugin.displayDiff(ev.target, store.getTiddler(title), myrev);
		});
		var saveBtn = createTiddlyButton(container, msgs.save, msgs.saveTooltip, function(ev) {
				var title = $(ev.target).data("title");
				var tid = store.saveTiddler(store.getTiddler(title));
				autoSaveChanges(null, [tid]);
			});
		var ignoreBtn = createTiddlyButton(container, msgs.discard, msgs.discardTooltip, function(ev) {
			var title = $(ev.target).text(msgs.updating).data("title");
			plugin.resetToServerVersion(store.getTiddler(title));
		});
		$([diffBtn, ignoreBtn, saveBtn]).data("title", title);
	},
	getDiffTiddlerTexts: function(diffText) {
		var chunks = diffText.split("\n  \n");
		if(chunks.length < 2) {
			return [chunks[0], ""];
		} else {
			var diffFieldsText = "{{diff{\n%0\n}}}".format(chunks[0]);
			diffText = '{{diff{\n%0\n}}}'.format(chunks.splice(1, chunks.length).join("\n"));
			return [diffText, diffFieldsText];
		}
	},
	makeDiffTiddler: function(title, diff) {
		var newTiddler = new Tiddler(title);
		var tags = plugin.diffTags;
		newTiddler.text = msgs.loading;
		newTiddler.fields.doNotSave = true;
		newTiddler.tags = diff ? tags.concat(["diff"]) : tags;
		newTiddler = store.saveTiddler(newTiddler);
		$.extend(store.getTiddler(title).fields,
			config.defaultCustomFields); // allow option to save it
		return newTiddler;
	},
	displayDiff: function(src, tiddler, latestRevision) {
		var adaptor = tiddler.getAdaptor();
		var title = tiddler.title;
		var ts = new Date().formatString("0hh:0mm:0ss");
		var suffix = "edit conflict %0".format(ts);
		var diffTitle = tiddlyspace.getLocalTitle(msgs.diffTitle.format(title), "", suffix);
		var diffTextTitle = tiddlyspace.getLocalTitle(msgs.diffTextTitle.format(title), "", suffix);
		var diffFieldsTitle = tiddlyspace.getLocalTitle(msgs.diffFieldTitle.format(title), "", suffix);
		plugin.makeDiffTiddler(diffTextTitle, true);
		plugin.makeDiffTiddler(diffFieldsTitle, true);
		var newTiddler = plugin.makeDiffTiddler(diffTitle, false);
		newTiddler.text = ['%0\n<<slider chkViewDiffText "%1" "%2">>\n',
			'<<slider chkViewDiffField "%3" "%4">>'].join("").
			format(msgs.diffHeader, diffTextTitle, msgs.diffTextHeader,
				diffFieldsTitle, msgs.diffFieldsHeader);
		store.saveTiddler(newTiddler);

		var callback = function(r) {
			var text = plugin.getDiffTiddlerTexts(r);
			store.getTiddler(diffTextTitle).text = text[0];
			store.getTiddler(diffFieldsTitle).text = text[1];
			story.refreshTiddler(diffTitle, null, true);
		};
		var workspace = "bags/%0".format(tiddler.fields["server.bag"]);
		ajaxReq({
			type: "get",
			dataType: "text",
			url: "/diff?format=unified&rev1=%0/%1/%2&rev2=%0/%1".format(workspace, title, latestRevision),
			success: callback,
			error: function() {
				displayMessage(msgs.reviewDiffError);
			}
		});
		story.displayTiddler(src, diffTitle);
	},
	resetToServerVersion: function(tiddler) {
		var adaptor = tiddler.getAdaptor();
		var ctx = { 
			host: tiddler.fields["server.host"],
			workspace: "bags/" + tiddler.fields["server.bag"]
		};
		adaptor.getTiddler(tiddler.title, ctx, null, function(context) {
			store.saveTiddler(context.tiddler);
			story.refreshTiddler(tiddler.title);
			store.setDirty(false);
		});
	},
	reportError: function(title) {
		var el = story.getTiddler(title);
		if(!el) {
			el = story.displayTiddler(null, title);
		}
		return $("<div />").addClass("error annotation").prependTo(el)[0];
	}
};

sssp.reportFailure = function(message, tiddler, context) {
	config.options.chkViewDiffText = config.options.chkViewDiffText === undefined ?
		true : config.options.chkViewDiffText;
	config.options.chkViewDiffFields = config.options.chkViewDiffFields || false;
	plugin.displayMessage(message, tiddler, context);
};

})(jQuery);
//}}}
|sortable|k
|!#|!Faculty|!Food request|!Notes|h
| 1|--Cynthia Fadem-- | |I'm in, but can forgo if others need it more :) Geoscience. @@will she actually be here?@@|
| 2|Becky Jestice | Turkey |Management|
| 3|Lynne ~Perkins-Socey| Turkey |Fine Arts -- Theatre|
| 4|Rajaram Krishnan| Hummus |Economics|
| 5|--Marya Bower--| Hummus |Philosophy|
| 6|--Monteze Snyder--| |Management|
| 7|--Mark Stocksdale--| Ham |Chemistry|
| 8|Kalani Seu| Hummus |Chemistry|
| 9|Julia May| Hummus (wrap)|Fine Art -- doing a talk|
| 10|--Susan W. Furukawa--| Hummus | Japanese Studies|
| 11|Corinne Deibel| Turkey |"this sounds like it would be very useful for gen chem and analytical and those are functions of Moodle that I don't know anything about."|
| 12|Bill Culverhouse| |I'm interested, and my new assistant Danielle may be interested also if there's room.|
| 13|Sarah Lee| | |
| 14|Amy Shrock| |(//No stipend//) "I am an adjunct and I have used Moodle in the past for "Contemporary Global Issues" and "American Perspectives," classes that Jane Terashima usually teaches. I will be teaching Global Issues again this fall, so I am interested in acquiring new Moodle knowledge and skills which I could use with this class."|
| 15|Danielle Steele| |Assistant Director of Choral Activity|
| 16|Welling Hall| | |
| 17|Jennifer Lewis| |INTD290 - Intro to Public Speaking|
| 18|Maxwell Paule| | Classics|
| 19|Ali Edington| |?|
| 20|John Howell| |late entrant|


Total {{ts{6/08/12 09:51}}} ''11''
Now available for Moodle 2.2:
* [[docs|http://docs.moodle.org/22/en/Sharing_Cart]]
* [[download from github|https://github.com/VERSION2-Inc/Sharing-Cart-2]]
* [[notification of latest release|http://moodle.org/mod/forum/discuss.php?d=87044#p763009]]
{{ts{17/07/12 10:46}}}
<<<
!!!Requirements
Moodle 2.0 to 2.2 (not compatible with 2.3)
<<<
[[Replies and Notifications]]

<<activity>>
Issues with porting over last year's courses.
!Latest News {{ts{14/12/12 16:42}}}
[[Make 1.9 blocks restorable in 2.3|http://tracker.moodle.org/browse/MDL-32880]] -- looks like this was incorporated into 2.3.4! @@So 2.3 will import 1.9 backup files@@ Test this out!
!!Constraints
# need to start with a new database -- current one polluted and full of garbage. Therefore have to do site wide course backup and restore.
** @@BUT@@ course backup format of 1.9 courses is incompatible with v 2.0.
# So, on the sandbox server, upgrade the 1.9 system to 2.newest and do course backups there.
** @@BUT@@ can only go from 1.9 -> 2.2. Cannot go straight to 2.3 or higher (this is quite common, to get to 1.9 from 1.6 you have to go via 1.8)
# To do this I need working modules for 2.2 equivalent to the ones used in 1.9. This should be straightforward.
** ''Note'' -- the LMB system is not needed for this effort.
# @@Enrollments@@ -- not clear whether enrollments are transportable. Only interested in teacher enrolls anyway.
# Problems with system wide course backups in @@1.9@@! Often because of large size. Chances are that if the course won't backup in 1.9 it won't backup in 2.2 either.
** Alternative options for transporting content
** For 'large' courses that don't successfully backup, do a course backup //without files// to get the Outline. Then zip up files and put them in System Folder area for user copying.
# Also files that are not used directly as Moodle Resources don't get included in the backup. (This is because resources work a different way in 2.x).
** workaround for this is to create a Directory resource that links to the Files area of the course.
!!Categories of courses:
* ancient and obsolete. Don't bother.
* ancient but might be wanted -- make available for migration and move over when asked.
** [[EC 2010-2011|https://moodle.earlham.edu/course/category.php?id=56]]
* 2012-2013 (201310, 201320) academic year -- migrate all courses ?
** [[EC Fall Semester, 2012-2013|https://moodle.earlham.edu/course/category.php?id=190]]
* 2011-2012 (201210, 201220) academic year -- migrate as requested ?
** [[EC Spring 2011-12|https://moodle.earlham.edu/course/category.php?id=113]]
** [[EC Fall 2011-12|https://moodle.earlham.edu/course/category.php?id=57]]
* MISC -- create backups. User initiated restore.
* COMM (committees) -- many are specific dates. Do the same as for MISC.
* MAT & MED -- migrate as requestd
** @@Community Documents@@ !!
!!Timing
* Can work on the Fall //201310// courses and move these over in the spring
* Have to 'freeze' Spring's courses (//201320//)to move over
* Run Pilot in Spring semester
** Need to have migration sandbox server running to move courses.
* Use pilot for summer / fall.
** When to move to v2.4?

# scp {{{moodledata}}} to naum on Dec 27th ? Or even earlier.
Also [[moodle 2 upgrade: migrate courses]]

!!Options
* Want to avoid having to do a lot of hands on course migrations
var user, userbag;
var friends = [];
var host = "http://tiddlyspace.com";

$.ajaxSetup({
	beforeSend: function(xhr) {
		xhr.setRequestHeader("X-ControlView", "false");
	}
});

function printMessage(txt) {
	alert(txt);
}

function printError(txt) {
	alert(txt);
}

var simpleDate = (function() {

	var measures = {
		second: 1,
		minute: 60,
		hour: 3600,
		day: 86400,
		week: 604800,
		month: 2592000,
		year: 31536000
	};

	var chkMultiple = function(amount, type) {
		return (amount > 1) ? amount + " " + type + "s":"a " + type;
	};

	return function(thedate) {

		var dateStr, amount,
			current = new Date().getTime(),
			diff = (current - thedate.getTime()) / 1000; // work with seconds

		if(diff > measures.year) {
			amount = Math.round(diff/measures.year);
			dateStr = "about " + chkMultiple(amount, "year") + " ago";
		} else if(diff > measures.month) {
			amount = Math.round(diff/measures.month);
			//if(typeof amount == "")
			dateStr = "about " + chkMultiple(amount, "month") + " ago";
		} else if(diff > measures.week) {
			amount = Math.round(diff/measures.week);
			dateStr = "about " + chkMultiple(amount, "week") + " ago";
		} else if(diff > measures.day) {
			amount = Math.round(diff/measures.day);
			dateStr = "about " + chkMultiple(amount, "day") + " ago";
		} else if(diff > measures.hour) {
			amount = Math.round(diff/measures.hour);
			dateStr = "about " + chkMultiple(amount, "hour") + " ago";
		} else if(diff > measures.minute) {
			amount = Math.round(diff/measures.minute);
			dateStr = "about " + chkMultiple(amount, "minute") + " ago";
		} else {
			dateStr = "a few seconds ago";
		}

		return dateStr;

	};
})();

function prettyDate(t) {
	var date = new Date(Date.UTC(
		parseInt(t.substr(0, 4), 10),
		parseInt(t.substr(4, 2), 10) - 1,
		parseInt(t.substr(6, 2), 10),
		parseInt(t.substr(8, 2), 10),
		parseInt(t.substr(10, 2), 10),
		parseInt(t.substr(12, 2) || "0", 10),
		parseInt(t.substr(14, 3) || "0", 10)
	));
	return simpleDate(date);
}

function endsWith(str, suffix) {
	return str.indexOf(suffix) == str.length - suffix.length;
}

function isShadow(tid) {
	var shadows = ["MarkupPreHead", "DefaultTiddlers", "PageTemplate", "SideBarTabs",
		"GettingStarted", "MainMenu", "SiteTitle", "SiteSubtitle", "ColorPalette",
		"SiteIcon", "ViewTemplate", "EditTemplate", "ServerSettings", "MarkupPostHead",
		"MarkupPostBody", "MarkupPreBody"];
	return tid.title.indexOf("StyleSheet") === 0 ||
		tid.title.indexOf("SideBar") === 0 ||
		shadows.indexOf(tid.title) > -1 || endsWith(tid.title, "SetupFlag") ? true : false;
}

function isPlugin(tid) {
	return tid.tags.indexOf("systemConfig") > -1 ? true : false;
}

function isArtifact(tid) {
	var follow = tid.tags.indexOf("follow") > -1;
	var type = tid.type;
	if(follow || type) {
		return true;
	} else {
		return false;
	}
}

function chooseTiddlers(tiddlers) {
	var _tiddlers = [];
	for(var i = 0; i < tiddlers.length; i++) {
		var tid = tiddlers[i];
		if(!isPlugin(tid) && !isShadow(tid) && !isArtifact(tid)) {
			_tiddlers.push(tid);
		}
	}
	return _tiddlers;
}

function bubbleDown() {
	var friends = $(".friend");
	friends.css({ position: "relative" });
	var target;
	friends.each(function(i, el) {
		if(!target && $(el).hasClass("silentFriend") &&
			$(el).next(".friend").hasClass("noisyFriend")) {
			target = el;
		}
	});
	if(target) {
		var other = $(target).next(".friend");
		// we want to move target above the prev element
		// target is an element which has the class noisy and the previous node is quiet
		var swapDuration = 50;
		var otherHeight = other.height();
		var thisHeight = $(target).height();
		$(target).animate({ top: + otherHeight }, { duration: swapDuration });
		$(other).animate({ top:  - thisHeight }, { duration: swapDuration,
				complete: function() {
					var newTarget = $(target).clone(true).insertAfter(other)[0];
					$(target).remove();
					$(other).css({ top: 0 });
					$(newTarget).css({ top: 0 });
					bubbleDown();
				}
		});
	}
}

function renderTiddlerList(container,friend) {
	var tidList = $("<ul />").appendTo(container)[0];
	$("<li />").text("loading").appendTo(tidList);
	var oncompletion = function() {
		if($(".errorFriend,.silentFriend,.noisyFriend").length === $(".friend").length) {
			bubbleDown();
		}
	}
	$.ajax({ dataType: "json",
		url: "/search?q=modifier:" + friend + "&select=modified:>3d&sort=-modified",
		error: function() {
			$(container).addClass("errorFriend");
			oncompletion();
		},
		success: function(tiddlers) {
			$(tidList).empty();
			tiddlers = chooseTiddlers(tiddlers);
			if(tiddlers.length === 0) {
				$(container).addClass("silentFriend");
				$("<li />").text("No recent activity.").appendTo(tidList);
				oncompletion();
				return;
			} else {
				$(container).addClass("noisyFriend").removeClass("inactiveFriend");
				oncompletion();
			}
			for(var i=0; i < tiddlers.length; i++) {
				var tiddler = tiddlers[i];
				var item = $("<li />").appendTo(tidList)[0];
				var win;
				var space = tiddler.bag.split("_")[0];
				var spaceUrl = "http://" + space + ".tiddlyspace.com";
				var path = "/bags/" + tiddler.bag + "/tiddlers/" + encodeURIComponent(tiddler.title);
				var link = $("<a />").text(tiddler.title).
					attr("href", spaceUrl + path).
					data("path", path).
					click(function(ev) {
						var win = $(ev.target).data("win");
						if($(ev.target).hasClass("active")) {
							$(win).toggle(1000);
						} else {
							$(ev.target).addClass("active");
							$(".text", win).text("loading...");
							$(win).show();
							$.ajax({
								url: $(ev.target).data("path"),
								data: {
									render: "y"
								},
								dataType: "json",
								success: function(tiddler) {
									$(".text",win).html(tiddler.render);
									$(win).show(1000);
								},
								error: function() {
									$(".text", win).text("error loading that tiddler");
								}
							});
						}
						ev.preventDefault();
					}).
					appendTo(item)[0];
				var space = tiddler.bag.split("_")[0];
				$("<span />").text(" in ").appendTo(item);
				$("<a />").attr("href", spaceUrl).text(space).appendTo(item);
				$("<span />").text(" (" + prettyDate(tiddler.modified) + ")").appendTo(item);
				win = $("<div />").addClass("tiddler").appendTo(item)[0];
				$("<div />").addClass("text").appendTo(win);
				var toolbar = $("<div />").addClass("toolbar").appendTo(win)[0];
				var extra = $("<div />").addClass("extra").appendTo(win)[0];
				$("<button />").data("bag", tiddler.bag).data("title", tiddler.title).text("give feedback").
					data("revision", tiddler.revision).click(function(ev) {
					var title = $(ev.target).data("title");
					var revision = $(ev.target).data("revision");
					var bag = $(ev.target).data("bag");
					var revisionURL = host + "/bags/" + bag + "/tiddlers/" + encodeURIComponent(title) + "/revisions/" + revision;
					var space = bag.split("_")[0];
					var area = $(ev.target).parents(".tiddler").children(".extra")[0];
					$(area).hide();
					$("<textarea />").appendTo(area);
					$("<button />").text("save feedback").click(function(ev) {
						var tid = new tiddlyweb.Tiddler("Feedback for " + title, userbag);
						tid.tags = ["feedback", "@" + space];
						tid.text = ["In reply to [[", title, "]]@", space,
							" (revision [[", revision, "|", revisionURL, "]])\n\n"].join("") + $("textarea", area).val();
						tid.put(function(tiddler) {
							$(area).empty();
							$("<span />").text("your comment: ").appendTo(area);
							$("<a />").attr("href", "/" + encodeURIComponent(tiddler.title)).text(tiddler.title).appendTo(area);
						}, function() {
							printError("error commenting!");
						});
					}).appendTo(area);
					$(area).show(1000);
					ev.preventDefault();
					$(ev.target).remove();
					return false;
				}).appendTo(toolbar);

				$(win).hide();
				$(link).data("win", win);
			}
		}
	})
}

function removeFriend(friend) {
	var tiddler = new tiddlyweb.Tiddler("@" + friend, userbag);
	var success = function() {
		printMessage("User removed from friends");
		var newFriends = [];
		for(var i = 0; i < friends.length; i++) {
			var f = friends[i];
			if(f !== friend) {
				newFriends.push(f);
			}
		}
		friends = newFriends;
		$("#friend-" + friend).hide(2000);
	};
	tiddler["delete"](success, function() {
		var old = new tiddlyweb.Tiddler(friend, userbag);
		old["delete"](success, function() {
			printError("Unable to remove friend " + friend);
		})
	})
}

function renderFriend(list, friend) {
	var bag = friend + "_public";
	var item = $("<li />").addClass("friend").attr("id", "friend-" + friend).addClass("inactiveFriend").appendTo(list)[0];
	$("<img />").attr("alt", friend).attr("title", friend).
		attr("src", host + "/bags/" + bag + "/tiddlers/SiteIcon").css({ width: 48, height: 48 }).appendTo(item);
	var heading = $("<h2>").appendTo(item)[0];
	$("<a />").attr("href", "#friend-" + friend).attr("name", "friend-" + friend).text(friend).appendTo(heading);
	$("<button />").data("who", friend).text("remove from friends").
		click(function(ev) {
			if(confirm("Are you sure you want to remove " + friend + " as a friend?")) {
				removeFriend($(ev.target).data("who"));
			}
		}).appendTo(item)[0];
	renderTiddlerList(item,friend);
}

function renderFriends() {
	var list = $("<ul />").appendTo("#friends")[0];
	$("<li />").text("Activity of your friends will appear below when available").appendTo(list);
	for(var i = 0; i < friends.length; i++) {
		var friend = friends[i];
		renderFriend(list, friend);
	}
}

function followWidget() {
	$("#friends").empty();
	var container = $("<div />").addClass("addfriends").appendTo("#friends")[0];
	$("<input />").attr("name", "friend").appendTo(container);
	$("<button />").text("add friend").click(function(ev) {
		var friend = $(ev.target).parent().children("[name='friend']").val();
		if(friends.indexOf(friend) > -1) {
			return printError("You already follow " + friend + "!");
		}

		var title;
		if(friend.indexOf("@") !== 0) {
			title = "@" + friend;
		} else {
			title = friend;
		}

		$.ajax({ dataType: "text", url: "/users/" + friend,
			success: function() {
				var tid = new tiddlyweb.Tiddler(title, userbag);
				tid.tags = ["follow", "excludeLists"];
				tid.put(function(tiddler) {
					printMessage("Added friend " + friend);
					renderFriend($("#friends ul")[0], friend);
					window.location.hash = "#friend-" + friend;
				}, function() {
					printError("Failed to add friend " + friend);
				})
			},
			error: function() {
				printError("No one with name " + friend + " exists!");
			}
		});
	}).appendTo(container);
	renderFriends();
}
$.ajax({
	url: "/status",
	dataType: "json",
	success: function(status) {
		user = status.username;
		userbag = new tiddlyweb.Bag(user + "_public", "/");
		$.ajax({ url: "/bags/" + user + "_public/tiddlers?select=tag:follow", dataType: "json", success: function(tiddlers) {
				for(var i = 0; i < tiddlers.length; i++) {
					var title = tiddlers[i].title;
					if(title.indexOf("@") === 0) {
						title = title.substr(1, title.length);
					}
					friends.push(title);
				}
				friends.sort();
				followWidget();
			}
		});
	}
})
As a substitute for [[Upgrading to Moodle 2]], ie doing a course backup and restore for //every// course.
Use {{{moodledata}}} dir as the basis for Server Files on the new server. On a //copy// of {{{moodledata}}}:
# Tidy up to remove superfluous files.
** delete all course backup zip files. This should be easy. 
** delete all zip files in the system (assuming that zip files are uploaded)
** delete all student upload data files
# rename numeric directory with directory name as shortcode
** (how? perhaps a database query listing the dir # & course shortcode and then a sed script to perform the substitution)
# Create departmental list of dirs and move course dirs into them
** [Top] : [Departments] : [Courses] -- from ''all'' years
# Now tar/gzip and ftp into appropriate location in {{{moodledata-production}}}. Expand and then nominate this dir tree as Server Files location.
!!!Issues
* Ownership & access. 
** Only teachers should have access (possible using roles?)
** But every teacher will be able to access any file. Nothing we can do about that.
** This means that you should be able to find the file you want from the previous course easily
* Will still need to restore course backups for Activities and Course outlines. 
* Q: Central location for course backups where teachers can do an import from?
!!Usage
# Open Server Files
# open Department folder
# locate course name and year
# list files to use or up and over to open another course
** ? could you copy //all// the course files from Server Files area into Private Files 
** or copy to local files in hidden course section
Posted in [[Re: Strategy for Moodle 2.x deployment|http://cme.clamp-it.org/mod/forum/discuss.php?d=716#p2510]] on {{ts{16/02/12 10:35}}}
<html>
<head>
	<title>Friends</title>
	<style type='text/css'>
		ul {
			list-style: none;
		}
		ul .friend {
			border-bottom: solid 1px black;
		}
		ul .friend .tiddler {
			margin-left: 10px;
			margin-bottom: 30px;
			padding: 10px;
			border: dotted 2px #CCC;
			color: #006100;
		}
		textarea {
			width: 100%;
			height: 150px;
		}
		.friend h2 {
			display: inline-block;
		}
		button {
			display: inline-block;
		}
		.inactiveFriend {
			background-color: #ccc;
			opacity: 0.1;
		}
	</style>
	<link rel="stylesheet" href="/HtmlCss" type="text/css">
</head>
<body>
<div id="container">
<div id="header">
<h1>Your friends</h1>
</div>
<noscript>
	javascript is required to see friend's activity
</noscript>
<div id='friends' class="section">loading...</div>
</div>
<script src="/bags/common/tiddlers/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/common/tiddlers/jquery-json.js" type="text/javascript" charset="utf-8"></script>
<script src="/bags/tiddlyspace/tiddlers/chrjs" type="text/javascript" charset="utf-8"></script>
<script type='text/javascript' src='/friendjs'></script>
</body>
</html>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg2" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="29pt" viewBox="13 43 29 29" width="29pt" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" onmousedown="if(jQuery) jQuery(document).trigger('cSmaller', {elem:this, comp:{animations:1}})" onmouseup="if(jQuery) jQuery(document).trigger('cResize', {elem:this, comp:{animations:1}})">
 <defs id="defs6">
 <linearGradient id="linearGradient001" y2="27.646" gradientUnits="userSpaceOnUse" x2="-45.8" y1="27.646" x1="-57.66">
   <stop id="stop1" stop-color="#B9B9FF" offset="0"/>
   <stop id="stop2" stop-color="#E8E8FF" offset="0.66462"/>
   <stop id="stop3" stop-color="#B9B9FF" offset="1"/>
  </linearGradient></defs>
<g id="icon" stroke-linecap="round" stroke-miterlimit="4">
 <rect id="iconBG" style="stroke-dasharray:none;" fill-rule="evenodd" ry="4.1663" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#696969" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="none"/>
 <rect id="iconFG" stroke-width="0" fill-rule="evenodd" ry="2.3755" transform="matrix(0, -1, 1, 0, 0, 0)" width="22" stroke-miterlimit="4" y="16.646" x="-68.6" height="22" fill="url(#linearGradient001)" class="showOnHover" opacity="0"/>
 <g id="iconSymbol" stroke-linejoin="miter" stroke="#4d4d4d" stroke-linecap="round" stroke-miterlimit="4" stroke-width="2">
  <rect id="rect2855" style="stroke-dasharray:none;" ry="0" height="9.7143" width="8.3827" y="50.654" x="21.214" fill="none"/>
  <rect id="rect3643" style="stroke-dasharray:none;" ry="0" height="9.7143" width="8.3827" y="54.56" x="26.097" fill="none"/>
 </g>
 <rect id="overlay" opacity="0.01" ry="4.1663" style="stroke-dasharray:none;" fill-rule="evenodd" transform="matrix(0, -1, 1, 0, 0, 0)" height="25" width="25" stroke="#e6e6e6" stroke-linecap="round" stroke-miterlimit="4" y="15.167" x="-70.116" stroke-width="1.2" fill="#e6e6e6" onmouseover="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})" onmouseout="if(jQuery) jQuery(document).trigger('cTglBg', {elem:this, comp:{animations:1}})"/>
</g>
</svg>