Server Side TiddlyWiki with PHP (easy)
4 Comments Published March 18th, 2009 in technology, tiddlywikiTiddlyWiki is an awesome reusable non-linear personal web notebook. That’s a lot of words. Keyword is awesome.
There have been a number of server-side implementations of TiddlyWiki that allow you to save data to a server (as opposed to locally as TiddlyWiki does by default). PHPTiddlyWiki is a good simple implementation using PHP/mySQL, but its an abandoned project with a couple of minor (but important) bugs. I’ve re-packaged PHPTiddlyWiki with the necessary fixes. Note that this is still essentially a non-upgradable version, but its easy to get it running today and I’m happy with the existing functionality. Here’s a video of what it can now do:
1. Download PHPTiddlyWiki:
Download my re-packaged version of PHPTiddlyWiki which includes a bug fix which was previously preventing proper server saves. Follow the instructions in tiddly_readme.html to install PHPTiddlyWiki in sub-directory on your server. You will need to have PHP and mySQL running (as most web hosts do)
2. Password protect:
You will probably want to password protect your wiki. You can do this easily using standard .htaccess/.htpasswd. Your host may even provide a GUI to do this though DirectAdmin (as mine does) or CPanel. Note that there are some special instruction if you’re using WordPress. I had to put the ErrorDocuments referenced in that link after “
3. Configure your theme:
The default PHPTiddlyWiki theme is a nice blue one, but I’m used to the Getting Things Done theme. I’ve hacked together an imitation style sheet (its probably imperfect, but fairly easy to tweak). Go to “All” Tiddlers and enter the following in the StyleSheetLayout Tiddler:
/*{{{*/ /* #displayArea{ position:absolute; top:0; width: 520px; _width: 545px; /* CSS UNDERSCORE HACK FOR PROPER WIN/IE DISPLAY */ } #mainMenu, #licensePanel{ float:right; clear:right; margin-right:0; margin-left:10px; } #contentWrapper{ width:1000px; } #sidebar{ font-size:12px; margin:10px 10px 0 0; width:215px; } #licensePanel{ margin-right:0px; } #logger{ xdisplay:block; } */ /*}}}*/
Enter the following for the StyleSheet Tiddler:
/*** !Calendar CSS ***/ /*{{{*/ .calendar{ border-bottom: 1px solid #550000; } .viewer .calendar{ width: 220px; } #mainMenu .calendar{ font-size: 8px; cursor: pointer; width: 100%; border: 0; border-collapse: collapse; } #mainMenu .calendar .button{ border: 0; } #mainMenu .calendar td{ font-size: 8pt; padding: 0; background: #fff; border: 0; } #mainMenu .calendar a{ margin: 0; color: #000; background: transparent; } #mainMenu .calendar a:hover{ color: #000; background: transparent; } #mainMenu .calendarMonthname, #mainMenu .calendar .calendarMonthTitle td a{ color: #fff; } #mainMenu .calendarDaysOfWeek td{ background: #500; color: #fff; } /*}}}*/ /*** !GTD Style !Generic rules /%==================================================================== %/ ***/ /*{{{*/ body { background: #464646 url('http://shared.snapgrid.com/images/tiddlywiki/bodygradient.png') repeat-x top fixed; color: #000; font: .82em/1.25em Arial, "Trebuchet MS", "Bitstream Vera Sans", Verdana, Helvetica, Arial, sans-serif; /*"Lucida Sans Unicode", "Lucida Grande","Trebuchet MS", */ } /*}}}*/ /*** !Header rules /%====================================================================== %/ ***/ /*{{{*/ #contentWrapper{ margin: 0 auto; width: 59em; position: relative; } .header, .tagging, .tagged{ display:none; } #siteTitle { font-size:30px; } #siteSubtitle { font-size: 1em; padding-left: .8em;; } #titleLine{ background: transparent; padding: 0; } #titleLine a { color: #CCFF66 background: transparent; } /*}}}*/ /*** !Sidebar rules /%====================================================================== %/ ***/ /*{{{*/ #sidebar{ left: 0; width: 18em; margin: .9em .9em 0 0; color: #000; background: transparent; } .button { border:none; } /*}}}*/ /*** !Main menu rules /%=================================================================== %/ ***/ /*{{{*/ #mainMenu { line-height: 166%; background: #600; border-right: 3px solid #500; font-size:12px; margin:10px 10px 0 0; width:215px; } #mainMenu h1{ padding: 0; margin: 0; font-size: 1em; font-weight: normal; } #mainMenu ul{ padding: 0; margin: 0; list-style: none; } #mainMenu h1 a, #mainMenu li a, #mainMenu li a.button{ display: block; padding: 0 5px 0 10px; border: 0; border-bottom: 1px solid #500; border-top: 1px solid #900; margin: 0; } #mainMenu a, #mainMenu a.button{ background:#770000 none repeat scroll 0 0; border-bottom:1px solid #550000; border-top:1px solid #990000; color:#FFFFFF; display:block; height:22px; line-height:22px; padding:0 5px 0 10px; } #mainMenu a:hover, #mainMenu a.button:hover { background: #b00; color: #fff; } /*}}}*/ /*** !Sidebar options rules /%============================================================ %/ ***/ /*{{{*/ #sidebarOptions { background: #eeb; border-right: 3px solid #bb8; color: #B4C675; padding: .5em 0; } #sidebarOptions a { margin:3px 10px; } #sidebarOptions a.button{ display:block; } #sidebarOptions a:hover, #sidebarOptions a:active { color: #fff; background: #700; border: 0; } #sidebarOptions input{ margin: 2px 10px; border: 1px inset #333; padding: 0; } #sidebarOptions .sliderPanel { background: #fff; color: #000; padding: 5px 10px; font-size: .9em; } #sidebarOptions .sliderPanel a{ font-weight: normal; margin: 0; } #sidebarOptions .sliderPanel a:link,#sidebarOptions .sliderPanel a:visited { color: #700; } #sidebarOptions .sliderPanel a:hover,#sidebarOptions .sliderPanel a:active { color: #fff; background: #700; } /*}}}*/ /*** !Sidebar tabs rules /%===================================================================== %/ ***/ /*{{{*/ #sidebarTabs { background: transparent; border-right: 3px solid #740; border-bottom: 3px solid #520; border: 0; padding: 0; } #contentWrapper #sidebarTabs a, #contentWrapper #displayArea .tabContents a{ color: #fff; } #contentWrapper #sidebarTabs a:hover, #contentWrapper #displayArea .tabContents a:hover { background: #000; color: #fff; } #contentWrapper #sidebarTabs a:active, #contentWrapper #displayArea .tabContents a:active{ color: #000; } #contentWrapper .tabSelected { background: #960; } #contentWrapper .tabUnselected{ background: #660; } #contentWrapper #sidebar .tabset{ background: #eeb; border-right: 3px solid #bb8; padding: 0 0 0 .75em; } #contentWrapper .tabContents{ font-size: .95em; background: #960; border:0; border-right: 3px solid #740; border-bottom: 3px solid #520; padding: .75em; } #contentWrapper .tabContents{ width: auto; } #contentWrapper #sidebarTabs .tabContents .tabset, #contentWrapper .tabContents .tabset{ border: 0; padding: 0; background: transparent; } #contentWrapper .tabContents .tabSelected, #contentWrapper .tabContents .tabContents { background: #700; border: 0; } #contentWrapper .tabContents .tabUnselected { background: #440; } #contentWrapper .tabset a { color: #fff; padding: .2em .7em; margin: 0 .17em 0 0; height: 2em; position: static; } #contentWrapper .tabset a:hover { background: #000; color: #fff; } #contentWrapper .tabset a:active { color: #000; } #contentWrapper .tabContents ul{ margin: 0; padding: 0; list-style: none; } #contentWrapper .tabContents .tabContents ul{ color: #eeb; } .tabContents ul a, .tabContents ul .button{ color: #fff; display: block; padding: .1em 0 .1em .7em; background: transparent; border: 0; } .tabContents ul a:hover { color: #fff; background: #000; } /*}}}*/ /*** !License panel rules /%==================================================================== %/ ***/ /*{{{*/ #licensePanel { padding: 0px 1em; font-size: .9em; } #licensePanel a { color: #960; display: block; margin-top: .9em; } #licensePanel a:hover { color: #fff; background: transparent; } /*}}}*/ /*** !Popup rules /%================================================================= %/ ***/ /*{{{*/ .popup { font-size: .8em; padding: 0em; background: #333; border: 1px solid #000; } .popup hr { margin: 1px 0 0 0; visibility: hidden; } .popup li.disabled { color: #666; } .popup li a, .popup li a:visited{ color: #000; border: .1em outset #cf6; background: #cf6; } .popup li a:hover { border: .1em outset #cf6; background: #ef9; color: #000; } /*}}}*/ /*** !Message area rules /%================================================================= %/ ***/ /*{{{*/ #messageArea{ font-size: .9em; padding: .4em; background: #FFE72F; border-right: .25em solid #da1; border-bottom: .25em solid #a80; position: fixed; top: 10px; right: 10px; color: #000; } #contentWrapper #messageArea a{ color: #00e; text-decoration: none; } #contentWrapper #messageArea a:hover{ color: #00e; text-decoration: underline; background: transparent; } #contentWrapper #messageArea .messageToolbar a.button{ border: 1px solid #da1; } #contentWrapper #messageArea .messageToolbar a.button:hover{ color: #00e; text-decoration: none; border: 1px solid #000; background: #fff; } /*}}}*/ /*** !Tiddler display rules /%================================================================== %/ ***/ /*{{{*/ #displayArea { width: 39.75em; margin: 0 0 0 17em; position:absolute; top:0; } .subtitle{ padding:5px; } .tiddler { margin: 0 0 .9em 0; padding: 0 1em; border-right: .25em solid #aaa; border-bottom: .25em solid #555; background: #fff; } .title { font-size: 1.5em; font-weight: bold; color: #900; padding:5px; } .toolbar { font-size: .8em; padding: .5em 0; } .toolbar .button{ padding: .1em .3em; color: #000; border: .1em outset #cf6; background: #cf6; margin: .1em; } .toolbar .button:hover { background: #ef9; color: #000; } .toolbar .button:active { background: #ff0; } /*}}}*/ /*** !Viewer rules /% ------------------------------------------------------------------------------------------ %/ ***/ /*{{{*/ .viewer { line-height: 1.4em; font-size: 1em; } .viewer a:link, .viewer a:visited { color: #15b; } .viewer a:hover { color: #fff; background: #000; } .viewer .button{ background: transparent; border-top: 1px solid #eee; border-left: 1px solid #eee; border-bottom: 1px solid #000; border-right: 1px solid #000; } .viewer .button:hover{ background: #eee; color: #000; } .viewer .button:active{ background: #ccc; border-bottom: 1px solid #eee; border-right: 1px solid #eee; border-top: 1px solid #111; border-left: 1px solid #111; } .viewer blockquote { border-left: 3px solid #777; margin: .3em; padding: .3em; } .viewer pre{ background: #fefefe; border: 1px solid #f1f1f1; } .viewer pre, .viewer code{ color: #000; } .viewer ul { padding-left: 30px; } .viewer ol { padding-left: 30px; } ul{ list-style-type: asquare; } ol{ list-style-type: decimal; } ol ol{ list-style-type: lower-alpha; } ol ol ol{ list-style-type: lower-roman; } .viewer ul, .viewer ol, .viewer p { margin: .0; } .viewer li { margin: .2em 0; } h1,h2,h3,h4,h5,h6 { color: #000; font-weight: bold; background: #eee; padding: 2px 10px; margin: 5px 0; } .viewer h1 {font-size: 1.3em;} .viewer h2 {font-size: 1.2em;} .viewer h3 {font-size: 1.1em;} .viewer h4 {font-size: 1em;} .viewer h5 { font-size: .9em;} .viewer h6 { font-size: .8em;} .viewer table { border: 2px solid #303030; font-size: 11px; margin: 10px 0; } .viewer th, .viewer thead td{ color: #000; background: #eee; border: 1px solid #aaa; padding: 0 3px; } .viewer td { border: 1px solid #aaa; padding: 0 3px; } .viewer caption { padding: 3px; } .viewer hr { border: none; border-top: dotted 1px #777; height: 1px; color: #777; margin: 7px 0; } .viewer { margin: .5em 0 0 0; padding: .5em 0; border-top: 1px solid #ccc; } .highlight { color: #000; background: #ffe72f; } /*}}}*/ /*** !Editor rules /% ----------------------------------------------------------------------------------------- %/ ***/ /*{{{*/ .editor { font-size: .8em; color: #402C74; padding: .3em 0; } .editor input, .editor textarea { font: 1.1em/130% "Andale Mono", "Monaco", "Lucida Console", "Courier New", monospace; margin: 0; border: 1px inset #333; padding: 2px 0; } .editor textarea { height: 42em; width: 100%; } input:focus, textarea:focus { background: #ffe; border: 1px solid #000; } .footer { padding: .5em 0; margin: .5em 0; border-top: 1px solid #ddd; color: #555; text-align: center; } /*}}}*/ /*** !IE Display hacks /% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%/ ***/ /*{{{*/ body{ _text-align: center; } #contentWrapper { /* _width: 770px; CSS UNDERSCORE HACK FOR PROPER WIN/IE DISPLAY */ _text-align: left; /* CSS UNDERSCORE HACK FOR PROPER WIN/IE DISPLAY */ } #messageArea{ _position: absolute; } /*}}}*/
Can I translate the original php-TW to my native language (da)?
Isn’t there a way to upgrade the php-TW with systemConfig-tiddlers?
I’ve tried to implement a translation-tiddler – but it doesn’t save it..
YS Måns Mårtensson
Hi Måns,
Unfortunately I haven’t tried translating TiddlyWiki, but let us know if you get it work!
Good luck,
- Boris
Hi Boris,
thanks for making this available – exactly what I was looking for!
It works fine except one thin: I can’t delete any tiddlers. After using the delete button tiddlers remain in the db and are shown as tiddlers just like before.
Renaming has a similar effect: Changing a tiddler’s title just creates a new entry.
Any ideas?
Stefan
hmm.. very strange. I don’t seem to have that problem. Unfortunately I can’t investigate at the moment. Hope you are able to figure it out!