Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
In Socialtext Unplugged, the selected pages of your Socialtext workspace are displayed as individual "tiddlers" on the page. When the mouse passes over a tiddler a short toolbar menu appears at the top right. Use the commands here to manipulate that particular tiddler: notably closing and editting it. (You can double click on a tiddler as a shortcut to directly enter edit mode).
Over on the right hand side of the window are commands that affect the entire page, in particular "close all" which can be useful to clear the decks when many tiddlers are open at once.
The user is encouraged to ensure that they can SaveChanges before embarking on widespread editing.
Welcome to Socialtext Unplugged. This is a specially designed web page that you can use to view and edit your Socialtext content without having to be online to your Socialtext server.
There are three steps to using Socialtext Unplugged:
* First, learn how to SaveChanges to your local hard drive. This keeps your work safe even if you close your browser or have to reboot your computer
* Secondly, find out how to BrowseAndEdit your content while it is unplugged
* Thirdly, when you can reconnect to your Socialtext server, you can SyncChanges to save your unplugged changes to the server so that other people can see them too
You should also check your system meets the SystemRequirements.
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
<div class="socialtextLogo"><img src="http://www.eu.socialtext.net/static/2.3.0.0/images/st/logo/socialtext-logo-152x26.gif" width=152 height=26></div>
</div>
<!--}}}-->
Socialtext Unplugged lets you browse and edit your content while you're offline. When you make a change you need to SaveChanges to save the change to your local hard drive, before later performing a SyncChanges to synchronise the change back to the server.
The procedure for SaveChanges is slightly different for different browsers:
* SavingOnInternetExplorer
* SavingOnFireFox
* SavingOnSafari
* SavingOnOpera
You can save changes with any version of FireFox, and also many other browsers in the FireFox family, such as Camino on the Mac and MiniMo on mobile devices. The procedure is:
# Click the button labelled 'save changes' over in the right hand sidebar
# If prompted with an "Internet Security" dialog as follows, click the checkbox labelled "Remember this decision" and then the "Allow" button
## "A script from "file://" is requesting enhanced capabilities that are UNSAFE and could be used to compromise your machine or data..."
# You should then see a message at the top right of the window saying "Main TiddlyWiki file saved"
If you accidentally //deny// permission instead, you may need to UnravelFireFoxPermissions.
You can save changes with Internet Explorer versions 6 and 7, but not the earlier versions. The procedure is:
# Click the button labelled 'save changes' over in the right hand sidebar
# If prompted as follows, click "Yes":
## "An ActiveX control on this page might be unsafe to interact with other parts of the page. Do you want to allow this interaction?"
# You should then see a message at the top right of the window saying "Main TiddlyWiki file saved"
Note that there is currently [[a bug|http://trac.tiddlywiki.org/tiddlywiki/ticket/39]] that prevents Internet Explorer from saving correctly if you have specified a backup directory in AdvancedOptions.
To SaveChanges on Opera, see the instructions for using the TiddlySaver Java applet.
To SaveChanges on Safari, see the instructions for using the TiddlySaver Java applet.
<<search>><<closeAll>><<permaview>><<newTiddler 'New Tiddler' fields:'server.host:"https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443" server.workspace:"strix" wikiformat:socialtext'>><<newJournal 'DD MMM YYYY' fields:'server.host:"https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443" server.workspace:"strix" wikiformat:socialtext'>><<saveChanges>><<backstage sync>><<slider chkSliderOptionsPanel OptionsPanel 'options ยป' 'Change TiddlyWiki advanced options'>>
https://saturn.ffzg.hr/strix/
[[SocialtextScreenStyle]]
[[SocialtextStyleOverrides]]
[[Styles HorizontalMainMenu]]
@@The user interface for synchronization is not finalized@@
To synchronize your changes back to the Socialtext server:
# click on [[Sync]] in the right-hand sidebar
<<tabs txtMoreTab Orphans 'Orphaned tiddlers' TabMoreOrphans Shadowed 'Shadowed tiddlers' TabMoreShadowed>>
Under FireFox, you can run into problems if you accidentally click 'Deny' on the permission request dialog, and have selected //Remember this decision//.
To reverse the effects, first locate the file {{{prefs.js}}} in your FireFox profile directory. Under Windows you'll find it at something like {{{C:\Documents and Settings\Jeremy\Application Data\Mozilla\Firefox\Profiles\o3dhupu6.default\prefs.js}}}, where {{{Jeremy}}} is the name of your windows profile and {{{o3dhupu6}}} will be a similar string of gobbledegook. On the Mac it'll be at {{{~/Library/Application Support/Firefox/Profiles/o3dhupu6.default/prefs.js}}} and on most versions of Linux, at {{{~/.mozilla/firefox/o3dhupu6.default/prefs.js}}}.
Open the file in a text editor and find the line {{{user_pref("capability.principal.codebase.p0.denied", "UniversalXPConnect");}}} and simply replace the word {{{denied}}} with {{{granted}}}.
//(Thanks to JonScully for figuring out this fix)//
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler references > fields syncing jump'></div>
<div class='workspace' id='st-page-wiki-title' macro='view socialtext.workspace'></div>
<div class='title' id='st-page-titletext' macro='view title'></div>
<div class='subtitle'>
Created on <span macro='view created date [[MMM DD, 0hh:0mm]]'></span>.
Updated by <span macro='view modifier link'></span>
on <span macro='view modified date [[MMM DD, 0hh:0mm]]'></span></div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></span></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
/***
To use, add {{{[[Styles HorizontalMainMenu]]}}} to your StyleSheet tiddler.
See http://www.w3schools.com/css/css_colors.asp for a color chart.
***/
/*{{{*/
#mainMenu {position:relative;left:auto;width:auto;text-align:left;line-height:normal;padding 0em 1em 0em 1em;font-size:normal;}
#mainMenu br {display:none;}
#mainMenu {background:#336699;}
#mainMenu {padding:2px;}
#mainMenu .button, #mainMenu .tiddlyLink {padding-left:0.5em;padding-right:0.5em;color:white;font-size:115%;}
#displayArea {
margin-top:0;margin-right:20em;margin-bottom:0;margin-left:1em;
padding-top:.1em;padding-bottom:.1em;
}
/*}}}*/
|''Type:''|socialtext|
|''URL:''|https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443 |
|''Workspace:''|strix|
|''WorkspaceList:''||
|''Description:''|STRIX|
The TiddlySaver Java applet allows TiddlyWiki from a {{{file://}}} URL to save changes Safari, Opera and other browsers.
It is a small file named [["TiddlySaver.jar"|TiddlySaver.jar]] that must be placed in the same directory as your TiddlyWiki file. Before you can use it, you need to give it the necessary privileges by editting your {{{.java.policy}}} file.
For Windows, the file will be at {{{C:\Documents and Settings\your-user-name\.java.policy}}}. Add the following lines (substituting the directory of your TiddlyWiki file as appropriate):
{{{
grant codeBase "file:${user.home}/My Documents/tiddlywiki-folder/*" {
permission java.io.FilePermission "${user.home}${/}My Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
On Mac OS X, the file is found at {{{/Users/your-user-name/.java.policy}}}:
{{{
grant codeBase "file:${user.home}/Documents/tiddlywiki-folder/*" {
permission java.io.FilePermission "${user.home}${/}Documents${/}tiddlywiki-folder${/}*", "read,write";
};
}}}
It can be tricky creating files whose name starts with a period, so you can use this [[pre-built .java.policy file|.java.policy]]. The same file is suitable for Macs too, just edit it and delete the "My " bit, leaving just "Documents". Make sure you save it in the right place for each operating system!
If you have trouble setting up the permissions correctly, you can try granting broader permissions to the applet like this:
{{{
grant codeBase "file://localhost/home/users/Desktop/
TiddlySaver.jar"
{ permission java.security.AllPermission; };
}}}
Note that there is currently [[a bug|http://trac.tiddlywiki.org/ticket/172]] that prevents TiddlySaver from working if you have specified a backup directory in AdvancedOptions.
/***
|''Name:''|SocialtextLocaleOverrides|
|''Description:''|Text changes for Socialtext|
***/
//{{{
merge(config.views.wikified.tag,{
labelNoTags: "No Tags",
labelTags: "Tags"});
merge(config.commands.references,{
text: "incoming links",
tooltip: "Show tiddlers that link to this one",
popupNone: "No incoming links"});
//}}}
/***
|''Name:''|SocialtextTweaksPlugin|
|''Description:''|Allows changes to be synchronised with a Socialtext server|
|''Source:''|http://stunplugged.tiddlywiki.com/#SocialtextTweaksPlugin|
|''Author:''|JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Version:''|1.0.2|
|''Date:''|Jun 15, 2006|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.2|
Make minor configuration tweaks specific to Socialtext Unplugged
***/
//{{{
// Ensure that the SocialtextTweaksPlugin is only installed once.
if(!version.extensions.SocialtextTweaksPlugin) {
version.extensions.SocialtextTweaksPlugin = {installed:true};
// Check version number of core code
if(version.major < 2 || (version.major == 2 && version.minor < 2))
{alertAndThrow("SocialtextTweaksPlugin requires TiddlyWiki 2.2 or later.");}
merge(config.defaultCustomFields,{
wikiformat:'socialtext',
'server.host':'https://saturn.ffzg.hr%2C%20saturn.ffzg.hr:443'
});
config.options.chkSinglePageMode = true;
config.options.chkEnableAnimations = true;
} // end of "install only once"
//}}}
/***
|''Name:''|SocialtextFormatterPlugin|
|''Description:''|Allows Tiddlers to use [[Socialtext|http://www.socialtext.com/]] text formatting|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextFormatterPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/formatters/SocialtextFormatterPlugin.js|
|''Version:''|0.9.4|
|''Date:''|Jan 21, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.1.0|
This is the SocialtextFormatterPlugin, which allows you to insert Socialtext formated text into a TiddlyWiki.
The aim is not to fully emulate Socialtext, but to allow you to work with Socialtext content off-line and then resync the content with your Socialtext wiki later on, with the expectation that only minor edits will be required.
To use Socialtext format in a Tiddler, tag the Tiddler with SocialtextFormat or set the tiddler's {{{wikiformat}}} extended field to {{{socialtext}}}
Please report any defects you find at http://groups.google.co.uk/group/TiddlyWikiDev
***/
//{{{
// Ensure that the SocialtextFormatter Plugin is only installed once.
if(!version.extensions.SocialtextFormatterPlugin) {
version.extensions.SocialtextFormatterPlugin = {installed:true};
if(version.major < 2 || (version.major == 2 && version.minor < 1))
{alertAndThrow('SocialtextFormatterPlugin requires TiddlyWiki 2.1 or later.');}
SocialtextFormatter = {}; // 'namespace' for local functions
wikify = function(source,output,highlightRegExp,tiddler)
{
if(source && source != '') {
var w = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
var out = output;
if(tiddler && (tiddler.isTagged(config.parsers.socialtextFormatter.formatTag) || (tiddler.fields.wikiformat==config.parsers.socialtextFormatter.format)) ) {
var d1 = createTiddlyElement(output,'div','content-display-body','content-section-visible');
var d2 = createTiddlyElement(d1,'div','wikipage');
out = createTiddlyElement(d2,'div',null,'wiki');
}
var time1,time0 = new Date();
w.subWikifyUnterm(out);
if(tiddler && config.options.chkDisplayInstrumentation) {
time1 = new Date();
var t = tiddler ? tiddler.title : source.substr(0,10);
displayMessage("Wikify '"+t+"' in " + (time1-time0) + " ms");
}
}
};
stDebug = function(out,str)
{
createTiddlyText(out,str.replace(/\n/mg,'\\n').replace(/\r/mg,'RR'));
createTiddlyElement(out,'br');
};
SocialtextFormatter.Tiddler_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
if((this.fields.wikiformat==config.parsers.socialtextFormatter.format) || this.isTagged(config.parsers.socialtextFormatter.formatTag)) {
// update the links array, by checking for Socialtext format links
this.links = [];
var tiddlerLinkRegExp = /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg;
tiddlerLinkRegExp.lastIndex = 0;
var match = tiddlerLinkRegExp.exec(this.text);
while(match) {
var link = match[2];
this.links.pushUnique(link);
match = tiddlerLinkRegExp.exec(this.text);
}
}/* else {
return SocialtextFormatter.Tiddler_changed.apply(this,arguments);
}*/
this.linksUpdated = true;
};
SocialtextFormatter.wafl = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var lm2 = lookaheadMatch[2];
switch(lookaheadMatch[1]) {
case 'image':
var img = createTiddlyElement(w.output,'img');
img.src = w.tiddler.title + '/' + lm2;
createTiddlyText(img,lm2);
break;
case 'file':
var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
var a = createTiddlyElement(s,'a');
a.href = w.tiddler.title + '/' + lm2;
createTiddlyText(a,lm2);
break;
case 'link':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createTiddlyElement(s,'a');
var t = w.tiddler ? w.tiddler.title + ':' : '';
a.setAttribute('href','#' + t + lm2);
a.title = 'section link';
createTiddlyText(a,lm2);
break;
case 'weblog':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
var text = lm2;
var link = 'Weblog: ' + lm2;
createTiddlyText(createTiddlyLink(s,link,false,null,w.isStatic),text);
break;
case 'section':
a = createTiddlyElement(w.output,'a');// drop anchor
t = w.tiddler ? w.tiddler.title + ':' : '';
a.setAttribute('name',t + lm2);
break;
case 'date':
createTiddlyText(w.output,lm2);
break;
case 'user':
var oldSource = w.source;
w.source = lm2;
w.nextMatch = 0;
w.subWikifyUnterm(w.output);
w.source = oldSource;
break;
// Shortcut expansions - not strictly syntax
case 'google':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://www.google.com/search?q='+lm2);
createTiddlyText(a,lm2);
break;
case 'fedex':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://www.fedex.com/Tracking?tracknumbers='+lm2);
createTiddlyText(a,lm2);
break;
case 'map':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://maps.google.com/maps?q='+lm2);
createTiddlyText(a,lm2);
break;
case 'wikipedia':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://en.wikipedia.org/wiki/'+lm2);
createTiddlyText(a,lm2);
break;
case 'rt':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'http://rt.socialtext.net/Ticket/Display.html?id='+lm2);
createTiddlyText(a,lm2);
break;
case 'stcal':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'https://calendar.socialtext.net:445/view_t.php?timeb=1&id=3&date='+lm2);
createTiddlyText(a,lm2);
break;
case 'svn':
s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
a = createExternalLink(s,'https://repo.socialtext.net/listing.php?rev='+lm2+'sc=1');
createTiddlyText(a,lm2);
break;
default:
w.outputText(w.output,w.matchStart,w.nextMatch);
return;
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
};
SocialtextFormatter.presence = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var p = lookaheadMatch[1];
var text = lookaheadMatch[2];
var link;
var src;
if(p=='aim') {
link = 'aim:goim?screenname=' + text + '&message=hello';
src = 'http://big.oscar.aol.com/sleepleft?on_url=http://www.aim.com/remote/gr/MNB_online.gif&off_url=http://www.aim.com/remote/gr/MNB_offline.gif';
} else if(p=='yahoo'||p=='ymsgr') {
link = 'ymsgr:sendIM?'+text;
src = 'http://opi.yahoo.com/online?u=chrislondonbridge&f=.gif';
} else if(p=='skype'||p=='callto') {
link = 'callto:'+text;
src = 'http://goodies.skype.com/graphics/skypeme_btn_small_green.gif';
} else if(p=='asap') {
link = 'http://asap2.convoq.com/AsapLinks/Meet.aspx?l='+text;
src = 'http://asap2.convoq.com/AsapLinks/Presence.aspx?l='+text;
}
var s = createTiddlyElement(w.output,'span',null,'nlw_phrase');
var a = createExternalLink(s,link);
var img = createTiddlyElement(a,'img');
createTiddlyText(a,text);
img.src = src;
img.border='0';
img.alt = '(' + lookaheadMatch[1] + ')';
if(p=='aim') {
img.width='11'; img.height='13';
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
};
config.formatterHelpers.singleCharFormat = function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[0].substr(lookaheadMatch[0].length-2,1) != ' ') {
w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
};
config.socialtext = {};
config.socialtext.formatters = [
{
name: 'socialtextHeading',
match: '^\\^{1,6} ?',
termRegExp: /(\n+)/mg,
handler: function(w)
{
var len = w.matchText.trim().length;
var e = createTiddlyElement(w.output,'h' + len);
var a = createTiddlyElement(e,'a');// drop anchor
var t = w.tiddler ? w.tiddler.title + ':' : '';
len = w.source.substr(w.nextMatch).indexOf('\n');
a.setAttribute('name',t+w.source.substr(w.nextMatch,len));
w.subWikifyTerm(e,this.termRegExp);
}
},
{
name: 'socialtextTable',
match: '^\\|(?:(?:.|\n)*)\\|$',
lookaheadRegExp: /^\|(?:(?:.|\n)*)\|$/mg,
cellRegExp: /(?:\|(?:[^\|]*)\|)(\n|$)?/mg,
cellTermRegExp: /((?:\x20*)\|)/mg,
handler: function(w)
{
var table = createTiddlyElement(w.output,'table');
var rowContainer = createTiddlyElement(table,'tbody');
var prevColumns = [];
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
var r = this.rowHandler(w,createTiddlyElement(rowContainer,'tr'),prevColumns);
if(!r) {
w.nextMatch++;
break;
}
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
},
rowHandler: function(w,e,prevColumns)
{
this.cellRegExp.lastIndex = w.nextMatch;
var cellMatch = this.cellRegExp.exec(w.source);
while(cellMatch && cellMatch.index == w.nextMatch) {
w.nextMatch++;
var cell = createTiddlyElement(e,'td');
w.subWikifyTerm(cell,this.cellTermRegExp);
if(cellMatch[1]) {
// End of row
w.nextMatch = this.cellRegExp.lastIndex;
return true;
}
// Cell
w.nextMatch--;
this.cellRegExp.lastIndex = w.nextMatch;
cellMatch = this.cellRegExp.exec(w.source);
}
return false;
}
},
{
name: 'socialtextList',
match: '^[\\*#]+ ',
lookaheadRegExp: /^([\*#])+ /mg,
termRegExp: /(\n+)/mg,
handler: function(w)
{
var stack = [w.output];
var currLevel = 0, currType = null;
var itemType = 'li';
w.nextMatch = w.matchStart;
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
var listType = lookaheadMatch[1] == '*' ? 'ul' : 'ol';
var listLevel = lookaheadMatch[0].length;
w.nextMatch += listLevel;
if(listLevel > currLevel) {
for(var i=currLevel; i<listLevel; i++) {
stack.push(createTiddlyElement(stack[stack.length-1],listType));
}
} else if(listLevel < currLevel) {
for(i=currLevel; i>listLevel; i--) {
stack.pop();
}
} else if(listLevel == currLevel && listType != currType) {
stack.pop();
stack.push(createTiddlyElement(stack[stack.length-1],listType));
}
currLevel = listLevel;
currType = listType;
var e = createTiddlyElement(stack[stack.length-1],itemType);
w.subWikifyTerm(e,this.termRegExp);
this.lookaheadRegExp.lastIndex = w.nextMatch;
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
}
}
},
{
name: 'socialtextQuoteByLine',
match: '^>+',
lookaheadRegExp: /^>+/mg,
termRegExp: /(\n)/mg,
element: 'blockquote',
handler: function(w)
{
var stack = [w.output];
var currLevel = 0;
var newLevel = w.matchLength;
var i;
do {
if(newLevel > currLevel) {
for(i=currLevel; i<newLevel; i++) {
stack.push(createTiddlyElement(stack[stack.length-1],this.element));
}
} else if(newLevel < currLevel) {
for(i=currLevel; i>newLevel; i--) {
stack.pop();
}
}
currLevel = newLevel;
w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
createTiddlyElement(stack[stack.length-1],'br');
this.lookaheadRegExp.lastIndex = w.nextMatch;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
if(matched) {
newLevel = lookaheadMatch[0].length;
w.nextMatch += newLevel;
}
} while(matched);
}
},
{
name: 'socialtextRule',
match: '^----+$\\n+',
handler: function(w)
{
createTiddlyElement(w.output,'hr');
}
},
{
name: 'socialtextPreformatted',
match: '^\\.pre\\s*\\n',
lookaheadRegExp: /^.pre\s*\n((?:.|\n)*?)\n.pre\s*\n/mg,
element: 'pre',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'socialtextHtml',
match: '^\\.html',
lookaheadRegExp: /\.html((?:.|\n)*?)\.html/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
createTiddlyElement(w.output,'span').innerHTML = lookaheadMatch[1];
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'macro',
match: '<<',
lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
w.nextMatch = this.lookaheadRegExp.lastIndex;
invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
}
}
},
{
name: 'socialtextExplicitLink',
match: '(?:".*?" ?)?\\[',
lookaheadRegExp: /(?:\"(.*?)\" ?)?\[([^\]]*?)\]/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var link = lookaheadMatch[2];
var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
createTiddlyText(createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler),text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextExternalLink',
match: '(?:".*?" ?)?<[a-z]{2,8}:',
lookaheadRegExp: /(?:\"(.*?)\" ?)?<([a-z]{2,8}:.*?)>/mg,
imgRegExp: /\.(?:gif|ico|jpg|png)/g,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var link = lookaheadMatch[2];
var text = lookaheadMatch[1] ? lookaheadMatch[1] : link;
this.imgRegExp.lastIndex = 0;
if(this.imgRegExp.exec(link)) {
var img = createTiddlyElement(w.output,'img');
if(lookaheadMatch[1]) {
img.title = text;
}
img.alt = text;
img.src = link;
} else {
createTiddlyText(createExternalLink(w.output,link),text);
}
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextUrlLink',
match: config.textPrimitives.urlPattern,
handler: function(w)
{
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
}
},
{
name: 'socialtextBold',
match: '\\*(?![\\s\\*])',
lookaheadRegExp: /\*(?!\s)(?:.*?)(?!\s)\*(?=[$\s\|\._\-,])/mg,
termRegExp: /((?!\s)\*(?=[$\s\|\.\-_,]))/mg,
element: 'strong',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextItalic',
match: '_(?![\\s_])',
lookaheadRegExp: /_(?!\s)(?:.*?)(?!\s)_(?=[$\s\|\.\*\-,])/mg,
termRegExp: /((?!\s)_(?=[$\s\|\.\*\-,]))/mg,
element: 'em',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextStrike',
match: '-(?![\\s\\-])',
lookaheadRegExp: /-(?!\s)(?:.*?)(?!\s)-(?=[$\s\|\.\*_,])/mg,
termRegExp: /((?!\s)-(?=[$\s\|\.\*_,]))/mg,
element: 'del',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextMonoSpaced',
match: '`(?![\\s`])',
lookaheadRegExp: /`(?!\s)(?:.*?)(?!\s)`(?=[$\s\.\*\-_,])/mg,
termRegExp: /((?!\s)`(?=[$\s\.\*\-_,]))/mg,
element: 'tt',
handler: config.formatterHelpers.singleCharFormat
},
{
name: 'socialtextParagraph',
match: '\\n{2,}',
handler: function(w)
{
createTiddlyElement(w.output,'p');
}
},
{
name: 'socialtextLineBreak',
match: '\\n',
handler: function(w)
{
createTiddlyElement(w.output,'br');
}
},
{
name: 'socialtextNoWiki',
match: '\\{\\{',
lookaheadRegExp: /\{\{((?:.|\n)*?)\}\}/mg,
element: 'span',
handler: config.formatterHelpers.enclosedTextHelper
},
{
name: 'socialtextTrademark',
match: '\\{tm\\}',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = '™';
}
},
{
name: 'socialtextWafl',
match: '\\{(?:[a-z]{2,16}): ?.*?\\}',
lookaheadRegExp: /\{([a-z]{2,16}): ?(.*?)\}/mg,
handler: SocialtextFormatter.wafl
},
{
name: 'socialtextPresence',
match: '(?:aim|yahoo|ymsgr|skype|callto|asap):\\w+',
lookaheadRegExp: /(aim|yahoo|ymsgr|skype|callto|asap):(\w+)/mg,
handler: SocialtextFormatter.presence
},
{
name: 'socialtextMailTo',
match: '[\\w\.]+@[\\w]+\.[\\w\.]+',
lookaheadRegExp: /([\w\.]+@[\w]+\.[\w\.]+)/mg,
handler: function(w)
{
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var text = lookaheadMatch[1];
createTiddlyText(createExternalLink(w.output,'mailto:'+text),text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
},
{
name: 'socialtextHtmlEntitiesEncoding',
match: '&#?[a-zA-Z0-9]{2,8};',
handler: function(w)
{
createTiddlyElement(w.output,'span').innerHTML = w.matchText;
}
}
];
config.parsers.socialtextFormatter = new Formatter(config.socialtext.formatters);
config.parsers.socialtextFormatter.format = 'socialtext';
config.parsers.socialtextFormatter.formatTag = 'SocialtextFormat';
} // end of 'install only once'
//}}}
/***
|''Name:''|SocialtextAdaptorPlugin|
|''Description:''|Adaptor for moving and converting data to and from Socialtext Wikis|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com) and JeremyRuston (jeremy (at) osmosoft (dot) com)|
|''Source:''|http://www.martinswiki.com/#SocialtextAdaptorPlugin|
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/SocialtextAdaptorPlugin.js|
|''Version:''|0.5.1|
|''Date:''|Feb 25, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev|
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|''~CoreVersion:''|2.2.0|
Socialtext REST documentation is at:
http://www.eu.socialtext.net/st-rest-docs/index.cgi?socialtext_rest_documentation
***/
//{{{
if(!version.extensions.SocialtextAdaptorPlugin) {
version.extensions.SocialtextAdaptorPlugin = {installed:true};
function SocialtextAdaptor()
{
this.host = null;
this.workspace = null;
return this;
}
SocialtextAdaptor.mimeType = 'text/x.socialtext-wiki';
SocialtextAdaptor.serverType = 'socialtext';
SocialtextAdaptor.serverParsingErrorMessage = "Error parsing result from server";
SocialtextAdaptor.errorInFunctionMessage = "Error in function SocialtextAdaptor.%0";
SocialtextAdaptor.prototype.setContext = function(context,userParams,callback)
{
if(!context) context = {};
context.userParams = userParams;
if(callback) context.callback = callback;
context.adaptor = this;
if(!context.host)
context.host = this.host;
if(!context.workspace && this.workspace)
context.workspace = this.workspace;
return context;
};
SocialtextAdaptor.doHttpGET = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('GET',uri,data,contentType,username,password,callback,params,headers);
};
SocialtextAdaptor.doHttpPOST = function(uri,callback,params,headers,data,contentType,username,password)
{
return doHttp('POST',uri,data,contentType,username,password,callback,params,headers);
};
SocialtextAdaptor.fullHostName = function(host)
{
if(!host)
return '';
if(!host.match(/:\/\//))
host = 'http://' + host;
if(host.substr(host.length-1) != '/')
host = host + '/';
return host;
};
SocialtextAdaptor.minHostName = function(host)
{
return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
};
// Convert a page title to the normalized form used in uris
SocialtextAdaptor.normalizedTitle = function(title)
{
var n = title.toLowerCase();
n = n.replace(/\s/g,'_').replace(/\//g,'_').replace(/\./g,'_').replace(/:/g,'').replace(/\?/g,'');
if(n.charAt(0)=='_')
n = n.substr(1);
return String(n);
};
// Convert a Socialtext date in YYYY-MM-DD hh:mm format into a JavaScript Date object
SocialtextAdaptor.dateFromEditTime = function(editTime)
{
var dt = editTime;
return new Date(Date.UTC(dt.substr(0,4),dt.substr(5,2)-1,dt.substr(8,2),dt.substr(11,2),dt.substr(14,2)));
};
SocialtextAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
this.host = SocialtextAdaptor.fullHostName(host);
context = this.setContext(context,userParams,callback);
if(context.callback) {
context.status = true;
window.setTimeout(function() {callback(context,userParams);},0);
}
return true;
};
SocialtextAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
this.workspace = workspace;
context = this.setContext(context,userParams,callback);
if(context.callback) {
context.status = true;
window.setTimeout(function() {callback(context,userParams);},0);
}
return true;
};
SocialtextAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces';
var uri = uriTemplate.format([context.host]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getWorkspaceListCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getWorkspaceListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getWorkspaceListCallback']);
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
var item = {
title:info[i].title,
name:info[i].name,
modified:SocialtextAdaptor.dateFromEditTime(info[i].modified_time)
};
list.push(item);
}
context.workspaces = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages?order=newest';//!! ? or ;
var uri = uriTemplate.format([context.host,context.workspace]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerListCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerListCallback']);
if(status) {
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
var list = [];
for(var i=0; i<info.length; i++) {
var tiddler = new Tiddler(info[i].name);
tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
tiddler.modifier = info[i].last_editor;
tiddler.tags = info[i].tags;
tiddler.fields['server.page.id'] = info[i].page_id;
tiddler.fields['server.page.name'] = info[i].name;
tiddler.fields['server.page.revision'] = String(info[i].revision_id);
list.push(tiddler);
}
context.tiddlers = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
var host = this && this.host ? this.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = this && this.workspace ? this.workspace : tiddler.fields['server.workspace'];
uriTemplate = '%0%1/index.cgi?%2';
info.uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(tiddler.title)]);
return info;
};
SocialtextAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
return this.getTiddlerRevision(title,null,context,userParams,callback);
};
SocialtextAdaptor.prototype.getTiddlerRevision = function(title,revision,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
// request the page in json format to get the page attributes
if(revision) {
var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions/%3';
context.revision = revision;
} else {
uriTemplate = '%0data/workspaces/%1/pages/%2';
context.revision = null;
}
uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),revision]);
context.tiddler = new Tiddler(title);
context.tiddler.fields.wikiformat = 'socialtext';
context.tiddler.fields['server.host'] = SocialtextAdaptor.minHostName(context.host);
context.tiddler.fields['server.workspace'] = context.workspace;
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback,context,{'accept':'application/json'});
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
context.statusText = SocialtextAdaptor.errorInFunctionMessage.format(['getTiddlerCallback']);
if(status) {
try {
eval('var info=' + responseText);
context.tiddler.tags = info.tags;
context.tiddler.fields['server.page.id'] = info.page_id;
context.tiddler.fields['server.page.name'] = info.name;
context.tiddler.fields['server.page.revision'] = String(info.revision_id);
context.tiddler.modifier = info.last_editor;
context.tiddler.modified = SocialtextAdaptor.dateFromEditTime(info.last_edit_time);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
context.status = true;
} else {
context.statusText = xhr.statusText;
if(context.callback)
context.callback(context,context.userParams);
return;
}
var uriTemplate = context.revision ? '%0data/workspaces/%1/pages/%2/revisions/%3' : '%0data/workspaces/%1/pages/%2';
var host = SocialtextAdaptor.fullHostName(context.tiddler.fields['server.host']);
var workspace = context.workspace ? context.workspace : context.tiddler.fields['server.workspace'];
uri = uriTemplate.format([host,workspace,SocialtextAdaptor.normalizedTitle(context.tiddler.title),context.revision]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerCallback2,context,{'accept':SocialtextAdaptor.mimeType});
};
SocialtextAdaptor.getTiddlerCallback2 = function(status,context,responseText,uri,xhr)
{
context.tiddler.text = responseText;
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.getTiddlerRevisionList = function(title,limit,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
var uriTemplate = '%0data/workspaces/%1/pages/%2/revisions?accept=application/json';
if(!limit)
limit = 5;
var uri = uriTemplate.format([context.host,context.workspace,SocialtextAdaptor.normalizedTitle(title),limit]);
var req = SocialtextAdaptor.doHttpGET(uri,SocialtextAdaptor.getTiddlerRevisionListCallback,context);
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.getTiddlerRevisionListCallback = function(status,context,responseText,uri,xhr)
{
context.status = false;
if(status) {
var content = null;
try {
eval('var info=' + responseText);
} catch (ex) {
context.statusText = exceptionText(ex,SocialtextAdaptor.serverParsingErrorMessage);
if(context.callback)
context.callback(context,context.userParams);
return;
}
list = [];
for(var i=0; i<info.length; i++) {
var tiddler = new Tiddler(info[i].name);
tiddler.modified = SocialtextAdaptor.dateFromEditTime(info[i].last_edit_time);
tiddler.modifier = info[i].last_editor;
tiddler.tags = info[i].tags;
tiddler.fields['server.page.id'] = info[i].page_id;
tiddler.fields['server.page.name'] = info[i].name;
tiddler.fields['server.page.revision'] = info[i].revision_id;
list.push(tiddler);
}
var sortField = 'server.page.revision';
list.sort(function(a,b) {return a.fields[sortField] < b.fields[sortField] ? +1 : (a.fields[sortField] == b.fields[sortField] ? 0 : -1);});
context.revisions = list;
context.status = true;
} else {
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.putTiddler = function(tiddler,context,userParams,callback)
{
context = this.setContext(context,userParams,callback);
context.tiddler = tiddler;
context.title = tiddler.title;
var uriTemplate = '%0data/workspaces/%1/pages/%2';
var host = context.host ? context.host : SocialtextAdaptor.fullHostName(tiddler.fields['server.host']);
var workspace = context.workspace ? context.workspace : tiddler.fields['server.workspace'];
var uri = uriTemplate.format([host,workspace,tiddler.title,tiddler.text]);
//var req = doHttp('POST',uri,tiddler.text,SocialtextAdaptor.mimeType,null,null,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"});
var req = SocialtextAdaptor.doHttpPOST(uri,SocialtextAdaptor.putTiddlerCallback,context,{"X-Http-Method": "PUT"},tiddler.text,SocialtextAdaptor.mimeType);
return typeof req == 'string' ? req : true;
};
SocialtextAdaptor.putTiddlerCallback = function(status,context,responseText,uri,xhr)
{
if(status) {
context.status = true;
} else {
context.status = false;
context.statusText = xhr.statusText;
}
if(context.callback)
context.callback(context,context.userParams);
};
SocialtextAdaptor.prototype.close = function()
{
return true;
};
config.adaptors[SocialtextAdaptor.serverType] = SocialtextAdaptor;
} //# end of 'install only once'
//}}}
/***
SocialtextStyleOverrides
***/
/*{{{*/
.headerShadow {padding: 2em 0em .5em 1em;}
.headerForeground {padding: 2em 0em .5em 1em;}
#st-page-wiki-title {
font-size: 80%;
}
.subtitle {
font-style: italic;
font-size 80%;
}
/* from #st-tags */
.tagged {
border-color: #bbeebb;
background-color: #f4fff4;
}
.tagged .listTitle {
color: #595;
font-weight: bold;
}
.tagged .button {
color: #000;
}
.selected .tagged {
background-color: ColorPalette::TertiaryLight;
border: 1px solid ColorPalette::TertiaryMid;
}
/* from #st-incoming-links */
.tagging {
border-color: #ebb;
background-color: #fff4f4;
}
.tagging .listTitle {
color: #b78;
font-weight: bold;
}
.tagging .button {
color: #999;
}
.selected .tagging {
background-color: ColorPalette::TertiaryLight;
border: 1px solid ColorPalette::TertiaryMid;
}
.tiddler {/* Tiddler body */
border:1px solid #ccc;
margin:0.5em;
background:#fff;
padding:0.5em;
}
.viewer blockquote {border-left: 0px solid}
.tiddlyLinkNonExisting {
font-style: italic;
border-bottom: 1px dashed;
}
.editor input, .editor textarea {
background: #ffd;
border-style: solid;
border-color: #888 #ccc #ccc #888;
border-width: 2px;
}
.tabContents {white-space: nowrap;}
#displayArea {margin: 1em 20em 0em 14em;}
#sidebar {
position: absolute;
right: 3px;
width: 21em;
font-size: .9em;
}
#sidebarOptions .button {
border-color: #eee;
}
#sidebarTabs .tabContents {
width: 20em;
overflow: hidden;
}
.viewer tt {
font-size: 1.2em;
line-height: 1.4em;
}
ul {list-style-type: square;}
ul ul {list-style-type: circle;}
ol {list-style-type: decimal;}
ol ol {list-style-type: decimal;}
ol ol ol {list-style-type: decimal;}
ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol {list-style-type: decimal;}
ol ol ol ol ol ol {list-style-type: decimal;}
/*}}}*/
/***
SocialtextScreenStyle
http://www.eu.socialtext.net/static/2.0.0.1/css/st/screen.css
***/
/*{{{*/
body {
font-family: Arial, sans-serif;
color: #000;
background: #eee;
margin: 0;
}
/* Wiki Navigation */
.st-wiki-nav {
clear: both;
margin-left: 10px;
margin-right: 10px;
}
.st-wiki-nav-content {
background: url('../../images/st/wiki-nav/solid.gif') repeat-x left bottom;
margin-left: 24px;
margin-right: 24px;
padding-top: 3px;
min-height: 24px;
}
* html .st-wiki-nav-content {
padding-bottom: 3px;
height: 24px;
}
.st-wiki-nav-right {
background: url('../../images/st/wiki-nav/right-round.gif') no-repeat bottom right;
}
.st-wiki-nav-left {
background: url('../../images/st/wiki-nav/left-round.gif') no-repeat bottom left;
}
#st-home {
float: left;
margin-right: 60px;
padding-top: 2px;
}
#st-home-link {
color: white;
text-decoration: none;
font-weight: bold;
font-family: Helvetica, sans-serif;
font-size: 90%;
}
#st-editing-prefix-container {
border-collapse: collapse;
width: 100%;
padding: 0px;
margin: 0px;
margin-bottom: -20px;
}
#st-editing-prefix-container tr td {
margin: 0px;
padding: 0px;
}
#st-editing-title {
color: black;
background-color: white;
text-decoration: none;
font-weight: bold;
font-family: Helvetica, sans-serif;
font-size: 90%;
margin-bottom: 0.4em;
}
#st-wiki-title-invite {
font-size: 50%;
font-family: Helvetica, sans-serif;
}
#st-wiki-title-central-page-link {
font-size: 50%;
font-family: Helvetica, sans-serif;
}
#st-wiki-title-invite a {
color: #00f;
}
#st-wiki-logo {
text-align: center;
clear: both;
}
#st-wiki-logo-image {
}
.st-wiki-nav-actions {
float: right;
color: black;
font-size: 75%;
padding-top: 3px;
}
.st-wiki-nav-actions a {
padding: 2px;
color: white;
text-decoration: none;
font-family: Helvetica, sans-serif;
}
/* Wiki Subnav */
#st-wiki-subnav {
margin-top: 2px;
font-size: 70%;
font-weight: bold;
font-family: Helvetica, sans-serif;
color: #888;
}
#st-wiki-subnav a {
padding: 2px;
color: #008;
text-decoration: none;
}
#st-wiki-subnav-right {
float: right;
margin-right: 6em;
}
#st-wiki-subnav-left {
float: left;
margin-left: 6em;
}
* html #st-wiki-subnav-left {
margin-left: 3em;
}
/* Wiki Navigation Search Bar */
#st-search-form {
margin: 0;
padding: 0;
padding-top: 1px;
}
#st-search-form .button-table {
float: left;
font-size: 79%;
font-weight: bold;
margin-left: 5px;
margin-top: 1px;
}
#st-search-form #st-search-term {
float: left;
font-size: 60%;
}
/* Content Outline */
#st-content-border, #st-edit-border {
position: relative;
clear: both;
margin-left: 3px;
margin-right: 2px;
margin-bottom: 0px;
margin-top: 0px;
border-bottom: 1px solid #eee;
}
#st-content-border-left, #st-edit-border-left {
background: url('../../images/st/page-shadow/left.gif') left top repeat-y;
position: relative;
}
#st-content-border-right, #st-edit-border-right {
background: url('../../images/st/page-shadow/right.gif') right top repeat-y;
position: relative;
}
#st-content-border-top, #st-edit-border-top {
position: relative;
background: url('../../images/st/page-shadow/top.gif') left top repeat-x;
}
#st-content-border-bottom, #st-edit-border-bottom {
background: url('../../images/st/page-shadow/bottom.gif') left bottom repeat-x;
position: relative;
}
#st-content-border-left-top, #st-edit-border-left-top {
background: url('../../images/st/page-shadow/left-top.gif') left top no-repeat;
position: relative;
}
#st-content-border-right-top, #st-edit-border-right-top {
background: url('../../images/st/page-shadow/right-top.gif') right top no-repeat;
position: relative;
}
#st-content-border-left-bottom, #st-edit-border-left-bottom {
background: url('../../images/st/page-shadow/left-bottom.gif') left bottom no-repeat;
position: relative;
}
#st-content-border-right-bottom, #st-edit-border-right-bottom {
background: url('../../images/st/page-shadow/right-bottom.gif') right bottom no-repeat;
padding-top: 5px;
padding-bottom: 9px;
position: relative;
}
* html #st-content-border-right-bottom, * html #st-edit-border-right-bottom {
padding-top: 4px;
padding-left: 7px;
padding-right: 8px;
position: relative;
}
.st-content-width-controller {
width: 100%;
position: relative;
border-collapse: collapse;
}
.st-content-width-controller td {
vertical-align: top;
}
.st-content {
position: relative;
background-color: white;
margin-top: 0px;
margin-left: 7px;
margin-right: 8px;
margin-bottom: -1px;
border-left: 1px dotted #80a9f3;
border-right: 1px dotted #80a9f3;
border: 1px solid #80a9f3;
padding: 6px 12px 12px 12px;
}
* html .st-content {
margin-top: 0px;
margin-left: 0px;
margin-right: 0px;
}
/* This textarea is only for Safari. However, if we use display:none; here Safari ignores the .value operation in JS */
#st-raw-wikitext-textarea {
width:1px;
height:1px;
margin:0;
padding:0;
}
/* Action Buttons */
.button-table, .button-table tr td {
border-collapse: collapse;
margin: 0;
padding: 0;
}
.button-rounded {
background: url('../../images/st/grey-button/left-top-rounded.png') top left no-repeat;
margin: 0;
}
.button-rounded-right-top {
background: url('../../images/st/grey-button/right-top-rounded.png') top right no-repeat;
margin: 0;
}
.button-rounded-left-bottom {
background: url('../../images/st/grey-button/left-bottom-rounded.png') bottom left no-repeat;
margin: 0;
}
.button-rounded-right-bottom {
background: url('../../images/st/grey-button/right-bottom-rounded.png') bottom right no-repeat;
margin: 0;
}
.button-straight {
background: url('../../images/st/grey-button/left-top-straight.png') top left no-repeat;
margin: 0;
}
.button-straight-right-top {
background: url('../../images/st/grey-button/right-top-straight.png') top right no-repeat;
margin: 0;
}
.button-straight-left-bottom {
background: url('../../images/st/grey-button/left-bottom-straight.png') bottom left no-repeat;
margin: 0;
}
.button-straight-right-bottom {
background: url('../../images/st/grey-button/right-bottom-straight.png') bottom right no-repeat;
margin: 0;
}
.button-content {
font-size: 90%;
}
.button-content a {
display: block;
padding: 2px;
padding-left: 10px;
padding-right: 10px;
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
text-decoration: none;
color: black;
}
.button-content input.submit {
border: 0px;
padding: 2px;
padding-left: 10px;
padding-right: 10px;
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
text-decoration: none;
color: black;
background-color: transparent;
}
/* Personal Homepage */
#st-homepage {
background: white url('../../images/st/homepage/blue-fade.gif') top left no-repeat;
}
#st-homepage-layout {
margin-top: 15px;
clear: both;
width: 100%;
border-collapse: collapse;
}
#st-homepage-layout tr td.st-homepage-layout-cell {
padding: 5px;
vertical-align: top;
}
#st-homepage-layout-dashboard {
width: 50%
}
#st-homepage-layout-notes {
width: 50%;
}
#st-homepage-notes, #st-homepage-dashboard {
text-align: left;
width: 95%;
}
#st-user-greeting, #st-wiki-title {
font-family: Helvetica, Verdana, sans-serif;
font-size: 150%;
}
#st-wiki-title {
margin-left: 5px;
}
#st-user-greeting {
position: relative;
text-align: right;
float: right;
}
#st-group-notes-content, #st-personal-notes-content {
}
.st-homepage-section {
margin-bottom: 15px;
}
#st-homepage-notes .st-homepage-section {
background-color: white;
border: 1px solid #aaa;
padding: 15px;
}
.st-homepage-section-title {
font-size: 110%;
font-family: Helvetica, Verdana, sans-serif;
}
#st-homepage-notes .st-homepage-section-title {
color: #aaa;
text-decoration: underline;
}
.st-homepage-notes-edit-link {
background: url('../../images/st/homepage/edit-icon.gif') no-repeat left top;
display: block;
text-indent: -2000px;
height: 13px;
width: 36px;
text-decoration: none;
padding:0;
}
* html .st-homepage-notes-edit-link {
border:1px solid white;
}
.st-homepage-notes-edit {
font-family: Verdana, sans-serif;
font-size: 65%;
float: right;
}
.st-homepage-notes-content {
font-size: 85%;
margin-top: 10px;
padding-top: 0px;
padding-bottom: 0px;
font-family: Verdana, Helvetica, sans-serif;
}
#st-dyk {
border-color: #cca !important;
background-color: #ffe !important;
}
#st-dyk-title {
color: #e4a020 !important;
text-decoration: none !important;
}
/* Homepage Simple List */
#st-whats-new-title-link {
background: url('../../images/st/homepage/icon-28-pages.gif') no-repeat left top;
}
#st-watchlist-title-link {
background: url('../../images/st/homepage/icon-28-star.gif') no-repeat left top;
}
#st-wikis-title-link {
background: url('../../images/st/homepage/icon-28-group.gif') no-repeat left top;
}
.st-homepage-simplelist-title-link {
display: block;
padding-left: 32px;
min-height: 32px;
}
* html .st-homepage-simplelist-title-link {
height: 32px;
}
.st-homepage-simplelist-title {
}
.st-homepage-simplelist-table {
margin-left: 25px;
border: 1px dashed #ddd;
border-collapse: collapse;
font-family: Verdana, Helvetica, sans-serif;
font-size: 80%;
width: 95%;
}
.st-homepage-simplelist-table td {
padding: 2px;
}
.st-homepage-simplelist-table tr.st-homepage-simplelist-row-odd {
background-color: #f3f7f7;
}
.st-homepage-simplelist-table tr.st-homepage-simplelist-row-even {
background-color: white;
}
.st-homepage-simplelist-table a {
color: #4f55dd;
text-decoration: none;
}
.st-homepage-simplelist-table a:visited {
color: #551a8b;
}
.st-homepage-simplelist-subleft {
font-size: 80%;
margin-left: 1em;
color: #666;
}
.st-homepage-simplelist-right {
width: 20%;
}
.st-homepage-simplelist-subright {
font-size: 80%;
color: #666;
}
.st-homepage-simplelist {
}
.st-homepage-simplelist-header {
min-height: 35px;
}
.st-homepage-simplelist-header .button-table {
float: right;
margin-right: 15px;
font-size: 95%;
}
.st-homepage-simplelist-header .button-table .button-content {
padding: 1px;
}
.st-homepage-whatsnew-author, .st-homepage-whatsnew-date {
color: #555;
}
.st-homepage-whatsnew-attribution {
padding-left: 1em;
font-size: 80%;
color: #aaa;
}
/* Homepage Wikis List */
#st-wikis-title {
}
/* Data and Templates */
.st-jst-template, .st-json {
display: none;
}
/* Page Sidebox Common Styles */
#st-page-boxes-toggle {
position: relative;
float: right;
text-align: right;
font-family: Verdana, Arial, sans-serif;
font-weight: bold;
font-size: 80%;
margin-bottom: 0.7em;
}
#st-page-boxes-toggle-link {
text-decoration: none;
}
#st-page-boxes-underlay {
float: right;
margin-top: -10px;
margin-right: 10px;
background: white;
z-index: 198;
clear: both;
margin-left: 15px;
}
* html #st-page-boxes-underlay {
margin-right: 4px;
}
#st-page-boxes {
background: inherit;
position: absolute;
right: 23px;
z-index: 199;
margin-top: 15px;
margin-left: 20px;
}
#st-page-boxes, #st-page-boxes-underlay {
width: 225px;
/* padding-left: 15px; */ /* Gives the white border effect, cwest dislikes it. */
}
.st-page-box {
border: 1px solid black;
padding: 5px;
font-family: Verdana, Helvetica, sans-serif;
font-size: 80%;
margin-top: 15px;
}
.st-page-box-title {
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
margin-bottom: 10px;
}
.st-page-box-listing {
margin: 0;
padding: 0;
}
.st-page-box-listing-entry {
display: block;
}
.st-page-boxes-nobacklinks {
font-family: Verdana, Helvetica, sans-serif;
font-size: 90%;
color: #888;
}
.st-page-box-first {
margin-top: 0px;
}
/* Page Display */
#st-page-content {
clear: left;
margin-top: 6px;
margin-bottom: 0;
padding-bottom: 0;
}
#st-page-content, #st-page-content td {
font-family: Verdana, Helvetica, sans-serif;
font-size: 90%;
}
#st-page-wiki-title {
font-family: Helvetica, Verdana, sans-serif;
font-size: 65%;
font-weight: bold;
color: #aaa;
margin-bottom: 0.2em;
margin-top: 0.1em;
padding-top: 0;
}
#wiki {
margin: 0;
padding: 0;
}
#st-page-title {
}
#st-page-titletext, .st-page-title {
font-family: Helvetica, Verdana, sans-serif;
font-size: 150%;
font-weight: bold;
color: #888;
border-bottom: 1px solid #888;
}
#st-newpage-pagename-edit {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
color: #000;
border: 1px solid black;
padding-left: 0.3em;
background-color: #ffd;
}
#st-page-details {
font-style: italic;
font-size: 75%;
font-family: Georgia, serif;
margin: 6px 10px 0 10px;
}
#st-page-details-feed-icon {
vertical-align: middle;
border: none;
}
#st-page-stats {
float: right;
vertical-align: middle;
}
#st-attribution {
float: left;
margin-bottom: 10px;
}
#st-page-editing-wysiwyg {
background: #ffd;
border-style: solid;
border-color: #888 #ccc #ccc #888;
border-width: 2px;
width: 100%;
}
#st-page-editing-toolbar {
margin-left: -6px;
overflow: hidden;
float: left;
height: 25px;
}
#wikiwyg_wikitext_textarea {
margin-top: 4px;
background: #ffd;
border-style: solid;
border-color: #888 #ccc #ccc #888;
border-width: 2px;
width: 100%;
font-family: monospace;
}
#st-page-maincontent {
}
#st-page-editing, #wikiwyg_wikitext_textarea {
}
#st-page-editing-pagebody-decoy, #st-page-editing-wysiwyg {
display: none;
}
#st-editing-tools-edit {
display: none;
}
#st-mode-wysiwyg-button
{
font-size: 70%;
margin-left: 4em;
}
#st-mode-wikitext-button
{
font-size: 70%;
}
#st-edit-tips
{
font-size: 70%;
}
.wikiwyg_button {
background: #FFFFFF;
border: 1px solid #FFFFFF;
cursor: pointer;
width: 20px;
height: 20px;
vertical-align: bottom;
}
.wikiwyg_button:hover {
border: 1px outset;
}
.wikiwyg_button:active {
border: 1px inset;
}
#wikiwyg_toolbar {
display: none;
}
/* Sidebox Pagetools: Revisions, Watchlist */
#st-side-box-pagetools {
border-collapse: collapse;
}
#st-rewind-norevisions {
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
color: #777;
text-decoration: none;
}
#st-side-box-pagetools a {
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
color: #555;
text-decoration: none;
}
/* Page View Tags/Incoming Links Sidebox */
#st-tags {
background: #f4fff4;
border-color: #bbeebb;
color: #999;
}
#st-tags-title {
color: #595;
}
#st-tags-addlink, #st-tags-addbutton {
font-weight: bold;
}
#st-tags-listing {
margin-bottom: 5px;
}
#st-tags-addinput, #st-tags-message, #st-tags-suggestion {
display: none;
}
#st-tags-deletemessage {
font-size: 90%;
color: #555;
display: none;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
#st-tags-suggestion {
margin-top: 2px;
}
.st-tags-level1 {
font-size: 90%;
}
.st-tags-level2 {
font-size: 100%;
}
.st-tags-level3 {
font-size: 110%;
}
.st-tags-level4 {
font-size: 120%;
}
.st-tags-level5 {
font-size: 130%;
}
.st-tags-tagline .st-tags-tagdelete {
text-decoration: none;
color: #ccc;
}
.st-tags-tagline a {
text-decoration: none;
color: #444;
}
#st-tags-field {
width: 95%;
}
#st-incoming-links {
border-color: #ebb;
background-color: #fff4f4;
}
#st-incoming-links-title {
color: #b78;
}
#st-attachments {
border-color: #bbe;
background-color: #f4f4ff;
}
#st-attachments-uploadbutton, #st-attachments-managebutton {
}
#st-attachments-buttons-uploadbutton {
margin: 0px;
padding: 0px;
padding-left: 2px;
}
#st-attachments-buttons-managebutton {
margin: 0px;
padding: 0px;
padding-right: 2px;
}
#st-attachments-buttons td {
padding-right: 3px;
font-size: 99%;
}
#st-attachments-buttons {
border-collapse: collapse;
margin: 0px;
padding: 0px;
margin-top: 5px;
}
#st-attachments-title {
color: #77b;
}
.st-attachments-line {
width:100%;
overflow:hidden;
}
/* Actions Bar */
#st-actions-bar-spacer {
clear:both;
height:0.5em;
overflow:hidden;
}
#st-actions-bar-spacer-clear {
clear:both;
height:1px;
overflow:hidden;
}
#st-actions-bar, #st-editing-tools-bar {
margin-left: 30px !important;
margin-right: 30px !important;
}
/* Footer */
#st-footer {
margin-top: -8px;
margin-bottom: 5px;
clear: both;
}
/* Socialtext Attribution */
#st-socialtext-attribution {
clear: both;
text-align: center;
font-size: 80%;
font-family: Helvetica, sans-serif;
}
#st-socialtext-attribution-link {
text-decoration: none;
}
#st-socialtext-attribution-image {
border: 0;
}
/* Page Actions */
#st-edit-button-border-left-middle, #st-login-to-edit-button-border-left-middle {
background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-button-border-right-middle, #st-login-to-edit-button-border-right-middle {
background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}
#st-edit-button-border-left-top, #st-login-to-edit-button-border-left-top {
background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-button-border-right-top, #st-login-to-edit-button-border-right-top {
background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}
#st-edit-button-border-left-bottom, #st-login-to-edit-button-border-left-bottom {
background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}
#st-edit-button-border-right-bottom, #st-login-to-edit-button-border-right-bottom {
background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}
#st-edit-button-link, #st-login-to-edit-button-link {
}
#st-comment-button-border-left-middle {
background: url('../../images/st/button-purple/left-middle.gif') left top repeat-y;
}
#st-comment-button-border-right-middle {
background: url('../../images/st/button-purple/right-middle.gif') right top repeat-y;
}
#st-comment-button-border-left-top {
background: url('../../images/st/button-purple/left-top.gif') left top no-repeat;
}
#st-comment-button-border-right-top {
background: url('../../images/st/button-purple/right-top.gif') right top no-repeat;
}
#st-comment-button-border-left-bottom {
background: url('../../images/st/button-purple/left-bottom.gif') left bottom no-repeat;
}
#st-comment-button-border-right-bottom {
background: url('../../images/st/button-purple/right-bottom.gif') right bottom no-repeat;
}
#st-comment-button-link {
}
#st-save-button-border-left-middle {
background: url('../../images/st/button-green/left-middle.gif') left top repeat-y;
}
#st-save-button-border-right-middle {
background: url('../../images/st/button-green/right-middle.gif') right top repeat-y;
}
#st-save-button-border-left-top {
background: url('../../images/st/button-green/left-top.gif') left top no-repeat;
}
#st-save-button-border-right-top {
background: url('../../images/st/button-green/right-top.gif') right top no-repeat;
}
#st-save-button-border-left-bottom {
background: url('../../images/st/button-green/left-bottom.gif') left bottom no-repeat;
}
#st-save-button-border-right-bottom {
background: url('../../images/st/button-green/right-bottom.gif') right bottom no-repeat;
}
#st-save-button-link {
}
#st-preview-button-border-left-middle {
background: url('../../images/st/button-gold/left-middle.gif') left top repeat-y;
}
#st-preview-button-border-right-middle {
background: url('../../images/st/button-gold/right-middle.gif') right top repeat-y;
}
#st-preview-button-border-left-top {
background: url('../../images/st/button-gold/left-top.gif') left top no-repeat;
}
#st-preview-button-border-right-top {
background: url('../../images/st/button-gold/right-top.gif') right top no-repeat;
}
#st-preview-button-border-left-bottom {
background: url('../../images/st/button-gold/left-bottom.gif') left bottom no-repeat;
}
#st-preview-button-border-right-bottom {
background: url('../../images/st/button-gold/right-bottom.gif') right bottom no-repeat;
}
#st-preview-button-link {
}
#st-cancel-button-border-left-middle {
background: url('../../images/st/button-crimson/left-middle.gif') left top repeat-y;
}
#st-cancel-button-border-right-middle {
background: url('../../images/st/button-crimson/right-middle.gif') right top repeat-y;
}
#st-cancel-button-border-left-top {
background: url('../../images/st/button-crimson/left-top.gif') left top no-repeat;
}
#st-cancel-button-border-right-top {
background: url('../../images/st/button-crimson/right-top.gif') right top no-repeat;
}
#st-cancel-button-border-left-bottom {
background: url('../../images/st/button-crimson/left-bottom.gif') left bottom no-repeat;
}
#st-cancel-button-border-right-bottom {
background: url('../../images/st/button-crimson/right-bottom.gif') right bottom no-repeat;
}
#st-cancel-button-link {
}
#st-edit-more-button-border-left-middle {
background: url('../../images/st/button-blue/left-middle.gif') left top repeat-y;
}
#st-edit-more-button-border-right-middle {
background: url('../../images/st/button-blue/right-middle.gif') right top repeat-y;
}
#st-edit-more-button-border-left-top {
background: url('../../images/st/button-blue/left-top.gif') left top no-repeat;
}
#st-edit-more-button-border-right-top {
background: url('../../images/st/button-blue/right-top.gif') right top no-repeat;
}
#st-edit-more-button-border-left-bottom {
background: url('../../images/st/button-blue/left-bottom.gif') left bottom no-repeat;
}
#st-edit-more-button-border-right-bottom {
background: url('../../images/st/button-blue/right-bottom.gif') right bottom no-repeat;
}
#st-edit-more-button-link {
}
.st-page-action-button-link {
min-height: 24px;
min-width: 100px;
text-align: center;
font-family: Helvetica, Verdana, sans-serif;
font-size: 90%;
text-decoration: none;
color: #fff;
font-weight: bold;
display: block;
padding-top: 8px;
padding-bottom: 0px;
margin-bottom: -3px;
width: 100%;
margin-left: -2px;
}
* html .st-page-action-button-link {
padding-top: 5px;
padding-bottom: 0px;
height: 24px;
}
.st-page-action-button {
float: left;
margin: 0;
padding: 0;
margin-right: 10px;
min-height: 20px;
border-collapse: collapse;
width: 100px;
}
/* Attach File Interface */
#st-attachments-attachinterface {
font-family: Helvetica, sans-serif;
font-size: 90%;
display: none;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 2000;
background-image: url('../../images/st/popup/bg.png');
}
#st-attachments-manageinterface {
font-family: Helvetica, sans-serif;
font-size: 90%;
display: none;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 2000;
background-image: url('../../images/st/popup/bg.png');
}
* html #st-attachments-attachinterface {
background-image: none;
}
* html #st-attachments-manageinterface {
background-image: none;
}
* html .popup-overlay {
background-image: url('../../images/st/popup/bg.png');
background-color: #000;
opacity: .70;
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 2001;
}
#st-attachments-attach-interface {
z-index: 2002;
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 1em;
width: 520px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position: absolute;
top: 0px;
}
* html #st-attachments-attach-interface {
}
#st-attachments-attach-formtarget {
width: 0px;
height: 0px;
border: 0;
padding: 0;
margin: 0;
}
#st-attachments-attach-message {
font-size: 90%;
font-family: Verdana, Arial, Helvetica, Sans-Serif;
}
#st-attachments-attach-title {
font-weight: bold;
font-size: 120%;
}
#st-attachments-attach-close {
float: right;
margin-top: 6px;
}
#st-attachments-attach-uploadbutton {
float: right;
margin-right: 6px;
margin-top: 6px;
padding-bottom: 0;
}
#st-attachments-attach-fileprompt {
margin: 0.2em 0 0.4em 0;
padding-bottom: 0px;
}
#st-attachments-attach-submit {
font-size: 90%;
font-weight: bold;
}
#st-attachments-attach-filename {
font-size: 90%;
}
#st-attachments-attach-uploadmessage {
font-weight: bold;
margin-bottom: 1em;
display: none;
}
#st-attachments-attach-error {
font-weight: bold;
color: #f00;
margin-bottom: 1em;
display: none;
}
#st-attachments-attach-list {
display: none;
color: #666;
font-size: 90%;
margin-top: 1em;
margin-bottom: 1em;
border-top: 1px solid #4949BA;
border-bottom: 1px solid #4949BA;
background-color: #F5F5F5;
padding: 3px;
}
.st-attachments-attach-listlabel {
font-size: 90%;
color: #4949BA;
}
/* Queue File Dialog */
#st-attachmentsqueue-interface {
font-family: Helvetica, sans-serif;
font-size: 90%;
display: none;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background-image: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
z-index: 2000;
}
* html #st-attachmentsqueue-interface {
background-image: none;
}
#st-attachmentsqueue-dialog {
z-index: 2002;
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 1em;
width: 530px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position: absolute;
top: 0px;
}
* html #st-attachmentsqueue-dialog {
}
#st-attachmentsqueue-fileprompt {
margin-bottom: 0.4em;
margin-top: 0;
padding-bottom: 0;
}
#st-attachmentsqueue-title {
font-weight: bold;
font-size: 120%;
}
#st-attachmentsqueue-close {
float: right;
margin-top: 6px;
}
#st-attachmentsqueue-uploadbutton {
float: right;
margin-right: 6px;
margin-top: 6px;
padding-bottom: 0;
}
#st-attachmentsqueue-submit {
font-size: 90%;
}
#st-attachmentsqueue-filename {
font-size: 90%;
}
#st-attachmentsqueue-message {
font-size: 90%;
font-family: Verdana, Arial, Helvetica, Sans-Serif;
}
#st-attachmentsqueue-uploadmessage {
font-weight: bold;
margin-bottom: 1em;
display: none;
}
#st-attachmentsqueue-error {
font-weight: bold;
color: #f00;
margin-bottom: 1em;
display: none;
}
#st-attachmentsqueue-list {
display: none;
color: #666;
font-size: 90%;
margin-top: 1em;
margin-bottom: 1em;
border-top: 1px solid #4949BA;
border-bottom: 1px solid #4949BA;
background-color: #F5F5F5;
padding: 3px;
}
.st-attachmentsqueue-listlabel {
font-size: 90%;
color: #4949BA;
}
/* Lists */
tr.st-trbg-even, tr.st-trbg-even td{
background-color: #f3f7f7;
}
tr.w-st-even-row, tr.w-st-even-row td {
background-color: #f3f7f7;
}
.query-results-header-title, .query-results-header-last-edit-by {
text-align: left;
}
.query-results-row-revisions {
text-align: right;
}
.query-results-content {
font-size: 85%;
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.query-results-row {
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.query-results-row a {
text-decoration: underline;
color: #00f;
}
.query-results-row td {
font-family: Verdana;
padding: 0.3em;
border-left: 1px dashed #ddd;
border-right: 1px dashed #ddd;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.query-results-header-row {
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.query-results-header-row a {
text-decoration: underline;
color: #00f;
}
.query-results-header-row th {
font-family: Helvetica;
padding: 0.3em;
border-left: 1px dashed #ddd;
border-right: 1px dashed #ddd;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
div.st-actionbutton {
float: left;
}
div#deleteme-st-actions-bar {
clear: both;
margin: 0.8em 20px 0.2em auto;
padding: 0;
}
/* Manage File Interface */
#st-attachments-manage-interface {
z-index: 2002;
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 1em;
width: 520px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position: absolute;
top: 0px;
}
#st-attachments-manage-filetable {
height: 150px;
margin: 0;
padding: 0;
width: 100%;
overflow: auto;
border: 1px solid #ccc;
}
#st-attachments-manage-filelisting tbody td {
font-size: 90%;
}
#st-attachments-manage-filelisting {
width: 100%;
border-collapse: collapse;
border: 0;
margin: 0;
padding: 0;
}
#st-attachments-manage-fileheader {
background: #ccc;
font-weight: bold;
border-bottom: 1px black solid;
}
#st-attachments-manage-close {
float: right;
margin-top: 3px;
margin-right: -2px;
font-weight: bold;
}
#st-attachments-manage-delete {
margin-top: 3px;
float: left;
font-weight: bold;
}
.st-attachments-manage-filerow {
border-bottom: 1px solid #ccc;
}
.row-odd {
background-color: #eee;
}
.row-even {
background-color: #fff;
}
.row-on {
background-color: #009 !important;
color: white !important;
}
.row-on a {
color: #fff !important;
}
#st-attachments-manage-deletemessage {
color: red;
}
/* Page tools icons */
#st-pagetools-print {
background: url('../../images/st/pagetools/print.gif')
left center no-repeat;
}
#st-pagetools-email {
background: url('../../images/st/pagetools/email.gif')
left center no-repeat;
}
#st-pagetools-tools {
background: url('../../images/st/pagetools/tools.gif')
left center no-repeat;
}
/*
#st-pagetools-watch {
background: url('../../images/st/pagetools/watch-blue.gif')
left center no-repeat;
}
*/
/* *********** Settings *********** */
#st-settings-pane {
}
* html #settings-pane { font-size: 85%;}
.settings-start-table {
}
* html .settings-start-table { font-size: 90%;}
#st-settings-select {
padding: 0px 10px 10px 10px;
vertical-align: top;
width: 1px;
background-color: #eff1ec;
border: none;
}
#st-settings-section {
padding: 0px 10px 10px 10px;
vertical-align: top;
}
.settings-top-header {
margin-top: 1em;
font-weight: bold;
width: 15em;
}
.settings-header {
margin-top: 1em;
font-weight: bold;
}
.settings-selections {
padding: 0px 0px 0px 20px;
line-height: 1.5em;
}
.settings-selections a:visited, .settings-selections a:active {
color: #0000ff;
}
.settings-link {
clear: both;
display: block;
}
.settings-section-left {
text-align: right;
}
.settings-label {
font-weight: bold;
}
.settings-help {
color: #888;
}
.settings-comment {
}
.users-invite-message {
padding: 0.5em 0.5em 0.5em 2em;
background-color: #eee;
/* This seems necessary to fix an IE bug that sometimes
causes the text in this div to be invisible */
z-index: 1000;
}
.workspace-entry-header {
margin-top: .5em;
font-weight: bold;
}
.workspace-entry {
margin-left: 3em;
}
.workspace-entry-p {
margin-top: .5em;
margin-bottom: .75em;
}
.workspace-subentry {
font-style: italic;
font-weight: bold;
margin-left: 1.5em;
}
.preferences-td {
padding:.5em 0 1.5em 0;
}
.preferences-query {
text-align: left;
}
.preference-radio {
background-color: #cec;
}
.user-settings-listall-headings td {
background-color: #eff3ef;
}
#st-settings-save {
padding-bottom: 0.5em;
}
.standard-button-cancel {
font-weight: bold;
background-color: #71004b;
border-left: 1px solid #aaa;
border-top: 1px solid #aaa;
border-bottom: 2px solid #333;
border-right: 2px solid #333;
color: #f4f3b9;
width: 8em;
}
.standard-button-submit {
font-weight: bold;
background-color: #656084;
border-left: 1px solid #aaa;
border-top: 1px solid #aaa;
border-bottom: 2px solid #333;
border-right: 2px solid #333;
color: #f4f3b9;
width: 8em;
}
#st-settings {
font-family: Verdana, Arial, Helvetica, Sans-Serif;
font-size: 90%;
}
/* Listview Tabs */
#st-listview a:visited {
color: #551a8b;
}
#st-listview-tabs ul {
display: block;
list-style: none outside;
margin: 0 0 0 4em;
padding: 0;
font-family: Helvetica, Arial, Sans-serif;
font-size: 80%;
}
#st-listview-tabs li {
display: block;
float: left;
margin: 0 0.8em 0 0;
padding: 3px 0.6em 0 0.6em;
border: 1px solid #d8d8d8;
border-bottom: 1px solid rgb(128, 169, 243);
background-color: #f4f4f4;
position: relative;
bottom: -2px;
}
#st-listview-tabs li.spacer {
margin: 0 0.8em 0 2em;
}
#st-listview-tabs a {
color: #bbb;
text-decoration: none;
}
#st-listview-tabs li.selected {
background-color: #fff !important;
border: 1px solid rgb(128, 169, 243) !important;
border-bottom: 1px solid #fff !important;
font-weight: bold !important;
}
#st-listview-tabs li.selected a {
color: #000 !important;
}
/* Category List Display */
#st-category-display-links {
margin-bottom: 1em;
font-size: 90%;
}
#st-tag-listbody {
font-family: Helvetica, Verdana, sans-serif;
}
/* Attachments List Display */
#st-attachments-list-body table.button-table {
margin-top: 0.1em;
font-size: 80%;
}
/* ********** PageTools Menu ************** */
div#st-editing-tools {
float: left;
}
div#st-pagetools {
z-index: 300;
font-family: Helvetica, Verdana, sans-serif;
font-size: 10px;
float: right;
margin: 18px 0 0 0em;
color: #000;
vertical-align: bottom;
position: relative;
}
#st-pagetools a {
text-decoration: none;
color: black;
padding-left: 17px;
}
#st-pagetools span {
color: inherit;
padding-left: 17px;
vertical-align: top;
}
#st-pagetools span.st-watchlist-link {
color: inherit;
vertical-align: top;
}
.st-watchlist-link {
cursor: pointer;
}
div#st-pagetools ul.level2 {
z-index: 300;
margin: 0;
padding: 0;
background: white;
border: 1px solid #CCC;
border-width: 0 1px;
}
div#st-pagetools li {
position: relative;
list-style: none;
margin: 0;
float: left;
width: 7em;
line-height: 11px;
}
div#st-pagetools ul ul li:hover {
background: #BFE2FF;
}
div#st-pagetools li a {
display: block;
text-decoration: none;
}
div#st-pagetools>ul a {
width: auto;
}
div#st-pagetools ul ul {
position: absolute;
width: auto;
display: none;
}
div#st-pagetools ul ul li {
line-height: 1.5em;
/* width: 100%; */
width: 14em;
}
.first {
border-top: 1px solid #CCC;
}
.separator {
border-bottom: 1px solid #CCC;
}
div#st-pagetools ul ul li a {
border-bottom: 1px solid #CCC;
padding-left: 15px;
padding-right: 3px;
margin-right: 3px;
border: 0px;
}
div#st-pagetools li.submenu li.submenu:hover {
z-index: 300;
background-color: #BFE2FF;
}
div#st-pagetools ul.level1 li.submenu:hover ul.level2 {
display:block;
}
div#st-pagetools ul.level2 {
top: 1.0em;
left: -9.5em;
}
/*
=head2 Revision List Display
Change these styles to update the page revision list.
*/
#st-revision-list-table {
border-collapse: collapse;
font-size: 85%;
color: #000;
}
.st-page-title-decorator {
color: #C80000;
}
.st-revision-header-emphasis {
color: #C80000;
}
.st-revision-list-compare-button-row {
}
.st-revision-list-compare-button-cell {
padding-top: 0.3em;
text-align: center;
}
.st-revision-list-compare-button {
}
#st-revision-list-header-row {
}
#st-revision-list-header-select {
padding: 6px 2px 2px 2px;
text-align: center;
}
#st-revision-list-header-revision {
padding: 6px 2px 2px 2px;
text-align: left;
}
#st-revision-list-header-edited-by {
padding: 6px 2px 2px 2px;
text-align: center;
}
#st-revision-list-header-date {
padding: 6px 2px 2px 2px;
text-align: center;
}
.st-revision-list-row {
border-collapse: collapse;
border: 1px dashed #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
.st-revision-list-row td {
font-family: Verdana;
padding: 0.3em;
border-left: 1px dashed #ddd;
border-right: 1px dashed #ddd;
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
.st-revision-list-row-select {
padding: 3px 0 2px 0;
text-align: center;
}
.st-revision-list-row-select-old {
}
.st-revision-list-row-select-new {
}
.st-revision-list-row-revision {
}
.st-revision-list-row-revision-link {
}
.st-revision-list-row-edited-by {
}
.st-revision-list-row-date {
}
/* Revision Menu */
#st-pagetools.st-revision-view-bar {
float: left;
}
ul.st-revision-menu {
list-style: none;
margin: 0;
padding: 0.2em;
font-size: 80%;
}
ul.st-revision-menu li {
float: left;
padding: 0 0.4em 0 0.4em;
border-right: thin solid #000000;
}
ul.st-revision-menu li.st-last {
border-right: none;
}
#st-restore-revision-button {
font-size: 80%;
}
/*
=head2 Revision Compare Display
When comparing two revisions of a page, these styles apply.
*/
#st-revision-compare-table {
background-color: #f0f0f0;
}
#st-revision-compare-table td {
background-color: white;
}
.st-revision-compare-old {
background-color: #fdd;
text-decoration: line-through;
}
.st-revision-compare-new {
background-color: #dfd;
font-weight: bold;
}
/* Weblog View */
#st-weblog {
padding: 0;
}
#st-content-weblog-display-width-controller {
}
#st-content-weblog-display-width-controller-nav {
width: 230px;
margin-left: 15px;
border-left: 5px solid #ddd;
margin-top: -1px;
}
#st-weblog-content {
font-family: Verdana, Helvetica, sans-serif;
margin-top: -1px;
margin-bottom: -1px;
border-top: 1px solid #80a9f3;
border-bottom: 1px solid #80a9f3;
}
#st-weblog-title {
font-family: 'Trebuchet MS', Verdana, Helvetica, sans-serif;
font-family: 'Times New Roman', serif;
background-color: #80a9f3;
color: #fff;
font-size: 150%;
font-weight: bold;
padding: 0.2em;
padding-left: 1em;
}
#st-weblog-wikititle {
font-family: Helvetica, Verdana, sans-serif;
font-style: italic;
font-size: 40%;
color: #fff;
margin-bottom: 0.2em;
margin-top: 0.1em;
padding-top: 0;
}
#st-weblog-titletext {
font-family: Helvetica, Verdana, sans-serif;
font-weight: bold;
color: #fff;
}
div.st-weblog-entry {
margin-top: 0.2em;
margin-bottom: 4.8em;
padding: 0 1.5em 0 1.5em;
}
.st-page-title {
clear: both;
}
div.st-weblog-entrytitle span.text {
font-family: Helvetica, Verdana, sans-serif;
font-size: 150%;
font-weight: bold;
color: #000;
}
.st-weblog-entrycontent {
font-family: Verdana, Helvetica, sans-serif;
font-size: 90%;
border-bottom: 1px solid #888;
}
.st-weblog-byline {
float: left;
text-align: left;
font-style: italic;
font-size: 70%;
font-family: Verdana, Helvetica, sans-serif;
}
.st-weblog-post-links {
float: right;
text-align: right;
font-size: 70%;
font-family: Verdana, Helvetica, sans-serif;
}
#st-weblog-archives, #st-weblog-navigation {
position: relative;
float: right;
width: 230px;
}
#st-weblog-archives {
margin-top: 15px;
clear: right;
}
#st-weblog-archives-title, #st-weblog-navigation-title {
margin-left: 15px;
font-family: Helvetica, sans-serif;
font-size: 95%;
font-weight: bold;
color: #999;
border-bottom: 2px solid #f99;
padding-bottom: 5px;
padding-top: 5px;
margin-bottom: 5px;
}
#st-weblog-navigation-content {
margin-left: 15px;
font-size: 80%;
}
#st-weblog-archives ul {
margin: 0;
padding: 0;
}
#st-weblog-archives ul li {
/* list-type: none; */
display: block;
font-size: 80%;
font-family: Helvetica, sans-serif;
padding-left: 15px;
}
#st-weblog-newpost {
padding: 0.5em 0.7em 0.3em 0.3em;
}
#st-weblog-newpost-button {
}
#st-weblog-actionbar-chooseweblog {
float: right;
}
#st-weblog-postbyemail {
font-size: 70%;
font-family: Verdana, Helvetica, sans-serif;
color: #def;
padding-top: 0.4em;
}
#st-weblog-postbyemail-link {
color: #00c;
}
.st-weblog-chooseprompt {
font-size: 90%;
font-family: Verdana, Helvetica, sans-serif;
padding-right: 0.2em;
color: #000;
}
.st-spacer {
padding-right: 0.1em;
padding-left: 0.1em;
}
.st-weblog-preventries {
padding-bottom: 20px;
clear: both;
}
.st-weblog-nextentries {
clear: both;
}
div.st-weblog-entrynav {
margin-top: 0.2em;
margin-bottom: 1.8em;
padding: 0;
}
span.st-weblog-previousentries, span.st-weblog-nextentries {
font-size: 90%;
font-family: Verdana, Helvetica, sans-serif;
padding-left: 1em;
}
/* ******* Page Stats ******** */
#st-usagereport-navbar {
font-size: 80%;
padding: 0;
margin: 0;
}
#st-usagereport-date {
font-weight: bold;
margin-top: 1em;
}
#st-page-usagereport h1 {
font-size: 1.3em;
font-weight: bold;
margin-top: 1.2em;
margin-bottom: 0.3em;
}
#st-page-usagereport h2 {
font-size: 1.1em;
font-weight: bold;
margin-top: 0.8em;
margin-bottom: 0.3em;
}
/* New Page */
#st-newpage-save, #st-newpage-duplicate {
display: none;
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
background: url('../../images/st/popup/bg.png'); /* Don't forget IE hack for ship! */
z-index: 2000;
}
#st-newpage-save-interface {
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 0.5em;
width: 450px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position:absolute;
top:0px;
z-index:2003;
}
#st-newpage-duplicate-interface {
background-color: #fff;
color: #000;
border: 4px solid #ccc;
padding: 0.5em;
width: 530px;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
position:absolute;
top:0px;
z-index:2003;
}
#st-newpage-save-title, #st-newpage-duplicate-title {
margin: 0;
padding: 0;
font-weight: bold;
font-family: Helvetica, sans-serif;
font-size: 100%;
}
#st-newpage-save-prompt, #st-newpage-duplicate-prompt {
font-family: Helvetica, sans-serif;
font-size: 90%;
margin-bottom: 0.4em;
}
#st-newpage-save-buttons, #st-newpage-duplicate-buttons {
margin-top: 0.8em;
text-align: right;
}
.st-newpage-duplicate-option {
font-family: Helvetica, sans-serif;
font-size: 90%;
margin: 0;
padding: 0;
}
#st-newpage-duplicate-pagename {
font-size: 90%;
}
.st-newpage-duplicate-emphasis {
background-color: #FFFF00;
font-weight: bold;
}
#st-newpage-save-field-pagename {
margin-bottom: 0;
margin-top: 0.2em;
padding-bottom: 0;
font-size: 90%;
}
#st-newpage-save-tip {
margin-bottom: 0;
margin-top: 1.2em;
padding-bottom: 0;
font-size: 75%;
color: #888;
}
/* Wikitext Styling */
.wiki {
}
.wiki hr {
margin-top: .4em;
margin-bottom: .4em;
}
.wiki .short-rule {
width: 25%;
}
.wiki .medium-rule {
width: 50%
}
.wiki ul,
.wiki ol,
.wiki blockquote {
margin-left: 2em;
padding-left: 0em;
}
.wiki table {
border-collapse: collapse;
}
.wiki td {
border: 1px;
border-style: solid;
padding: .2em;
vertical-align: top;
}
.wiki h1,
.wiki h2,
.wiki h3,
.wiki h4,
.wiki h5,
.wiki h6 {
font-weight: bold;
font-style: normal;
margin-top: 0.1em;
margin-bottom: 8px;
}
.wiki h1 {font-size: 200%;}
.wiki h2 {font-size: 170%;}
.wiki h3 {font-size: 145%;}
.wiki h4 {font-size: 125%;}
.wiki h5 {font-size: 110%;}
.wiki h6 {font-size: 100%;}
.wiki pre {
background-color: #eee; /* XXX */
margin-left: 1em;
margin-right: 1em;
padding: .2em;
}
.wiki .incipient {
text-decoration: none;
border-bottom: 1px dashed;
}
.wiki-include-title {
background-color: #ccccff;
}
.wiki .wiki {
position: relative;
background-color: #ddddff;
border: 1px solid #ccccff;
padding: 3px;
}
.wafl_existence_error {
color: rgb(200,0,0);
border-bottom: 0.2em dashed rgb(200,0,0);
}
#st-edit-mode-container {
}
#st-edit-mode-view {
}
#st-page-editing-uploadbutton {
z-index: 1500;
float: left;
}
/* Comment UI */
body#st-commentui {
background: #ffffff;
}
#st-commentui-container {
}
#st-commentui-container a:visited,
#st-commentui-container a:active {
color: #00f;
}
#st-commentui-notetop {
}
#st-commentui-controls {
}
#st-commentui-savelink {
background-color: #fffebd;
}
#st-commentui-cancellink {
}
#st-commentui-customfield {
}
#st-commentui-customfield .customfield-label {
}
#st-commentui-customfield .customfield-input {
}
#st-commentui-textarea {
padding: 0;
border-style: inset;
border-width: thin;
background-color: #ffd;
color: black;
width: 99%;
height: 150px;
}
/*
=head2 Send Page by Email
Styles for the 'Send Page by Email' popup, accessed from the 'Email' dropdown
menu on the page bar.
*/
#email-page {
background: #ffffff;
font-size: 80%;
}
.email-page-row {
clear: both;
}
.email-page-row-label {
font-weight: bold;
float: left;
width: 5em;
margin-left: 1.2em;
margin-right: 1.2em;
text-align: right;
}
.email-page-row-content {
float: left;
padding-bottom: 1.2em;
}
.email-page-user-select-column {
float: left;
padding-right: 1.2em;
width: 14em;
}
#email-page-user-select-column-center {
width: 10em;
}
.email-page-user-select-label {
text-align: center;
}
#email-page-user-select-add-label {
padding-top: 1em;
}
.email-page-user-select-button-group {
padding-bottom: 2em;
}
.email-page-input {
width: 120px;
clear: both;
display: block;
}
.email-page-select {
width: 175px;
font-size: x-small;
}
#email-page-error-message {
text-align: center;
}
#email-page-buttons-container {
clear: both;
}
#email-page-buttons {
text-align: center;
}
.email-page-input-new {
width: 175px;
}
/* System Status, Red with icon */
#st-system-status-alert {
clear: both;
width: 50%;
margin-left: 25%;
margin-top: 10px;
padding: 5px;
color: #c00;
font-weight: bold;
font-size: 80%;
background: transparent url('../../images/st/system-message/important-note.gif') no-repeat 5px center;
padding-left: 60px;
min-height: 38px;
}
* html #st-system-status-alert {
height: 38px;
}
/* System Status, Green */
#st-system-status {
clear: both;
text-align:center;
width: 80%;
margin-left: 10%;
padding: 8px 0 3px 0;
color: #0a0;
font-family: Arial, Helvetica, sans-serif;
font-size: 80%;
}
.socialtextLogo {
text-align: center;
}
/*}}}*/
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};
//--
//-- Sparklines
//--
config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
var data = [];
var min = 0;
var max = 0;
var v;
for(var t=0; t<params.length; t++) {
v = parseInt(params[t]);
if(v < min)
min = v;
if(v > max)
max = v;
data.push(v);
}
if(data.length < 1)
return;
var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
box.title = data.join(",");
var w = box.offsetWidth;
var h = box.offsetHeight;
box.style.paddingRight = (data.length * 2 - w) + "px";
box.style.position = "relative";
for(var d=0; d<data.length; d++) {
var tick = document.createElement("img");
tick.border = 0;
tick.className = "sparktick";
tick.style.position = "absolute";
tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
tick.style.left = d*2 + "px";
tick.style.width = "2px";
v = Math.floor(((data[d] - min)/(max-min)) * h);
tick.style.top = (h-v) + "px";
tick.style.height = v + "px";
box.appendChild(tick);
}
};
}
//}}}
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};
//--
//-- Crypto functions and associated conversion routines
//--
// Crypto "namespace"
function Crypto() {}
// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
var be = Array();
var len = Math.floor(str.length/4);
var i, j;
for(i=0, j=0; i<len; i++, j+=4) {
be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
}
while (j<str.length) {
be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
j++;
}
return be;
};
// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
var str = "";
for(var i=0;i<be.length*32;i+=8)
str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
return str;
};
// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
var hex = "0123456789ABCDEF";
var str = "";
for(var i=0;i<be.length*4;i++)
str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
return str;
};
// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
return Crypto.be32sToHex(Crypto.sha1Str(str));
};
// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
// Add 32-bit integers, wrapping at 32 bits
add32 = function(a,b)
{
var lsw = (a&0xFFFF)+(b&0xFFFF);
var msw = (a>>16)+(b>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
};
// Add five 32-bit integers, wrapping at 32 bits
add32x5 = function(a,b,c,d,e)
{
var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
};
// Bitwise rotate left a 32-bit integer by 1 bit
rol32 = function(n)
{
return (n>>>31)|(n<<1);
};
var len = blen*8;
// Append padding so length in bits is 448 mod 512
x[len>>5] |= 0x80 << (24-len%32);
// Append length
x[((len+64>>9)<<4)+15] = len;
var w = Array(80);
var k1 = 0x5A827999;
var k2 = 0x6ED9EBA1;
var k3 = 0x8F1BBCDC;
var k4 = 0xCA62C1D6;
var h0 = 0x67452301;
var h1 = 0xEFCDAB89;
var h2 = 0x98BADCFE;
var h3 = 0x10325476;
var h4 = 0xC3D2E1F0;
for(var i=0;i<x.length;i+=16) {
var j,t;
var a = h0;
var b = h1;
var c = h2;
var d = h3;
var e = h4;
for(j = 0;j<16;j++) {
w[j] = x[i+j];
t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=16;j<20;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=20;j<40;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=40;j<60;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
for(j=60;j<80;j++) {
w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
}
h0 = add32(h0,a);
h1 = add32(h1,b);
h2 = add32(h2,c);
h3 = add32(h3,d);
h4 = add32(h4,e);
}
return Array(h0,h1,h2,h3,h4);
};
}
//}}}
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};
//--
//-- Deprecated code
//--
// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};
// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = function(w)
{
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var text = lookaheadMatch[1];
if(config.browser.isIE)
text = text.replace(/\n/g,"\r");
createTiddlyElement(w.output,"pre",null,null,text);
w.nextMatch = lookaheadRegExp.lastIndex;
}
};
// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
createTiddlyElement(place,"br");
};
// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
var i = this.indexOf(item);
return i == -1 ? null : i;
};
// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
return store.getLoader().internalizeTiddler(store,this,title,divRef);
};
// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
return store.getSaver().externalizeTiddler(store,this);
};
// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
return store.allTiddlersAsHtml();
}
// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
refreshPageTemplate(title);
}
// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
story.displayTiddlers(srcElement,titles,template,animate);
}
// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
story.displayTiddler(srcElement,title,template,animate);
}
// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;
// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");
}
//}}}
^ SQL funkcije
Mnoge ฤeste operacije na bazi podataka mogu se u Strix-u raditi koriลกtenjem SQL funkcija.
* [UserCanDoOnObject] - provjera ACL prava na neki objekt
* [string2float] - pretvara tip `varchar` u `float` za brojke formata xx.xxx,xx
Za opis osnovih koncepta i tablica, proฤitajte [uvod], nakon toga moลพete ฤitati {category: tutorial} stranice ili {category: docs} za svu dokumentaciju.
Osnovni komand funkcionalnosti u STRIX-u je {category: module} dok sam engine moลพe imati {category: plugin} i to za {category: smarty} template engine ili {category: internal}.
[Install] ([Prerequisites])
{category: development} - sve za hard-core developere
{category: profile} - ubrzavanje, na pola puta izmeฤu developera i admina
{category: admin} stuff
{category: trick} ovi za svaลกta
tehnologije: {category: html} {category: css}
^ apc cache
Nemojte storati boolean vrijednosti (php true ili false) jer apc_fetch funkcija ne razlikuje vrijednost false od greske
^ pdo
* PDO ne vraca 't' i 'f' za boolean vrijednosti nego ih casta u php boolean vrijednosti
* kod prepareanja statementa nemojte zaboraviti staviti :ime_placeholdera npr.
* jos jedan problem - kod preparea: http://bugs.php.net/bug.php?id=33876
> krivo:
.pre
$data = array(
'user_id' => $user_id
, 'perm' => $perm
, 'acl_id' => $acl_id
, 'acl_object_id' => $acl_object_id
);
.pre
> ispravno:
.pre
$data = array(
':user_id' => $user_id
, ':perm' => $perm
, ':acl_id' => $acl_id
, ':acl_object_id' => $acl_object_id
);
.pre
step 1 - brisanje deklaracija global $_s_pod;
.pre
grep -rli 'global [^;]*\$_s_pod' * | grep -v \.svn | xargs -i sed -i \
-e 's/\(global [^;]*\)\$_s_pod/\1/g' \
-e 's/global[[:blank:]]\{1,\},/global /g' \
-e 's/,[[:blank:]]*\([,;]\)/\1/g' \
-e 's/global[[:blank:]]\{1,\};//g' {}
.pre
step 2 - zamjena $_s_pod sa $_SESSION['_s_pod']
.pre
grep -rli '\$_s_pod' * | grep -v \.svn | xargs -i sed -i "s/\$_s_pod/\$_SESSION['_s_pod']/gi" {}
.pre
step 3 - zamjena $GLOBALS['_s_pod'] sa $_SESSION['_s_pod']
.pre
grep -rli globals\\[\s*\\\([\'\"]*\\\)_s_pod\\1\\\s*\\\] * | xargs -i sed s/globals\\[\s*\\\([\'\"]*\\\)_s_pod\\1\\\s*\\\]/_SESSION['_s_pod']/gi -i {}
.pre
^ Dozvole i ACL
^^ Nasljedjivanje
Dozvole se definiraju nad nekom jedinicom sadrลพaja - site, kategorija/stranica, vijest, dokument.
Dozvole se daju korisniku ili grupi korisnika.
Dozvole mogu biti READ, WRITE, AUTHOR/SUGGEST, ADMIN/OWN itd. (Skup dozvola nije ograniฤen i po potrebama se moลพe proลกiriti.)
Dozvola korisniku je jaฤa od dozvole grupi. Ako je dozvola dana ili oduzeta korisniku zanemaruju se dozvole koje bi taj korisnik imao kao pripadnik grupama kojima je dana dozvola.
Kako postoji hijerarhija jedinica sadrลพaja tako postoji i nasljeฤivanje dozvola.
Ako je jednoj grupi ili korisniku definirana dozvola viลกe puta u viลกe razina, u obzir se uzima dozvola definirana hijerarhijski najbliลพe jedinici sadrลพaja, ali opet se uzima pravilo: dozvola korisniku je jaฤa od dozvole grupi. Npr. ako je Peru nad siteom definirano pravo READ, ali mu je nad konkretnim dokumentom PeroNemaPravo.doc zabranjeno READ, on neฤe moฤi pristupiti tom dokumentu.
^^ Alternativni opis
Postoje tri pojma:
SUBJEKT = korisnik, grupa korisnika
OBJEKT = dokument/folder
PRAVO = za dokumente READ ili OWN, za foldere READ, SUGGEST, AUTHOR, OWN (svako od prava ima vrijednost DA ili NE)
Jedan zapis u ACL-u mora imati definirane sve tri vrijednosti.
Vrijede pravila:
โข PRAVO korisniku je jaฤe od PRAVA grupi. Ako je PRAVO dano ili oduzeto (vrijednost DA ili NE) korisniku, zanemaruju se PRAVA koje bi taj korisnik imao kao pripadnik grupama kojima je dana dozvola.
โข ACL se moลพe nasljeฤivati s jedne razine na drugu (npr. sa foldera na podfolder ili dokument ลกto je defaultno ponaลกanje document managementa)
โข Ako je jednoj grupi ili korisniku definiran ACL viลกe puta u viลกe razina, u obzir se uzima PRAVO definirano hijerarhijski najbliลพe jedinici sadrลพaja (dokumentu ili folderu), ali opet se uzima pravilo: PRAVO korisniku je jaฤe od PRAVA grupi.
โข Zabrana (PRAVO=Ne) u kontekstu korisnika je jaฤe od dozvole (PRAVO=Da)
โข U kontekstu grupe, dozvola (PRAVO=Da) je jaฤe od zabrane (PRAVO=Ne)
^^ Ostalo
Za sada, moลพete pogledati AclHacks za _hands-on_ stvari koje moลพete napraviti direktno u bazi.
{include: [AclHacks]}
{include: [UserCanDoOnObject]}
^ Prava pristupa i dozvole za sadrลพaje
.pre
select UserCanDoOnObject(user_id, perm, acl_id, object_id);
.pre
*perm* odreฤuje pravo. Postojeฤe permisije mogu se pogledati sa:
.pre
strix=# select * from perms order by flag ;
.pre
| flag | mark |
| 1 | PERM_READ |
| 2 | PERM_WRITE |
| 2 | PERM_SUGGEST |
| 4 | PERM_AUTHOR |
| 8 | PERM_ADMIN |
| 8 | PERM_OWN |
Neke od njih su aliasi tako da se iste dozvole mogu koristiti u razlicitim kontekstima.
Kratko objaลกnjenje kako su zamiลกljene osnovne razine dozvola u STRIXu:
# PERM_READ - korisnik s tom dozvolom ima pravo pristupa (u kontekstu kategorije tj. stranice) odnosno pravo ฤitanja sadrลพaja (u kontekstu jedinice sadrลพaja)
# PERM_WRITE ili njezin alias PERM_SUGGEST (alias u kontekstu dozvola na foldere) - korisnik ima pravo predlaganja sadrลพaja, glasanja, komentiranja, postavljanje pitanja. Predloลพeni sadrลพaj se ne objavljuje direktno nego se ฤeka dozvola administratora stranice koji za taj sadrลพaj moลพe dozvoliti objavu ili odbiti.
# PERM_AUTHOR - korisnik ima pravo direktne objave svog contenta bez posredstva administratora. Korisnik s tom dozvolom ne moลพe mijenjati tuฤi content, ali moลพe svoj.
# PERM_ADMIN - korisnik je administrator stranice.
*acl_id* su tipovi sadrลพaja. Mogu se pogledati sa:
.pre
strix=# select * from acl_register ;
.pre
| id | table_name | id_col_name | detail_col_name | description |
| grup | grupe | id | naziv | Group |
| site | site | id | naziv | Site |
| kats | kategorija | id | naziv | Category |
| file | document | id | title | File |
| news | news | id | title | Vijest |
| faq | faq_qanda | id | question | FAQ |
| foru | f_topics | id | title | Forum |
| cale | calendar | id | title | Calendar |
*object_id* je identifikator objekta (obiฤno primarni kljuฤ) objekta za koji se provjerava permisija.
Primjer koriลกtenja:
.pre
select UserCanDoOnObject(1, 'PERM_ADMIN', 'news', 42 );
.pre
^ Uvod u STRIX engine
Svaka web stranica koju engine generira i koja ima svoj URL se strogo veลพe uz jednu kategoriju (kategorija). Za svaku stranicu, tj. kategoriju engine uฤitava iz baze njen izgled i sadrลพaj. Izgled stranice je odreฤen pre-definiranim glavnim templateom (template) i rasporedom modula unutar nje. [Moduli] (modules) su funkcionalno neovisni dijelovi web stranice koji generiraju konaฤan sadrลพaj. Za svaku kategoriju, moduli se po ลพelji odabiru i rasporeฤuju unutar nje (layout).
Viลกe ureฤenih kategorija ฤini jedan site (site). Site sluลพi za zgodno grupiranje npr. prava pristupa ili dizajna.
Engine podrลพava do 3 ureฤene (poredane) liste modula (npr. za lijevi, srednji i desni stupac).
Podrลพana je i jedna ne-ureฤena (slobodna) lista modula, ฤija pozicija prikaza je definirana unutar glavnog templatea (npr. glavna navigacija, baneri, footer, breadcrumbs, datum i vrijeme i sliฤne). Ovi moduli ฤe se prikazivati na svim stranicama koje imaju isti template.
Module je moguฤe definirati i za cijeli site, u kojem sluฤaju se oni prikazuju iznad ili ispod modula definiranih za pojedinu stranicu (pre_layout).
Prilikom generiranja stranice, engine dohvati sve instance modula za trenutnu kategoriju, izvrลกi ih, a njihove generirane sadrลพaje posloลพi u glavni template.
^ Opisi glavnih relacija
^ kategorija
| id | unique id svake kategorije |
| url | uniqur url svake kategorija |
| naziv | puni naziv (ime) kategorije |
| knaziv | kratki naziv koji se ispisuje u navigaciji |
| customize | - ne koristi se |
| flags | - 0.bit - stranica je viลกejeziฤna , ostali niลกta |
| template_id | id templatea koji se koristi prilkom generiranja stranice |
| site_id | id sitea kojem stranica pripada |
| description | opis (za search) |
| keywords | kljuฤne rijeฤi (za search) |
| lang | defaultni jezik stranice. |
| lastchange | - ne koristi se |
| redirecturl | ukoliko postoji, engine redirecta uneseni url |
| special | kategorije za posebne namjene (nema ih u navigaciji) |
| force_ssl | cijela stranica se isporuฤยจuje preko SSL |
.pre
Foreign-key constraints:
"$3" FOREIGN KEY (site_id) REFERENCES site(id) ON UPDATE CASCADE ON DELETE
CASCADE
"$2" FOREIGN KEY (lang) REFERENCES lang(id) ON UPDATE CASCADE ON DELETE CASCADE
"$1" FOREIGN KEY (template_id) REFERENCES "template"(id) ON UPDATE CASCADE ON
DELETE CASCADE
.pre
^ site
| id | unique id svakog sitea |
| naziv | naziv sitea |
| admin_mail | defaultni e-mail |
| forcedesign | - defaultni design, ne korsti se |
| default_template | - defualtni template, ne koristi se |
| root | glavni (root) url site |
| content_providers | id grupe content providera (admina) |
| ordstr | za prkaz siteova u hijerarhiji |
^ template
| id | uniqe id |
| tfilename | ime filea glavnog templatea ('main.tpl'). |
| tflags | - ne koristi se |
| design_id | id designa koji se koristi za template |
| tname | puno ime templatea |
.pre
Foreign-key constraints:
"$1" FOREIGN KEY (design_id) REFERENCES design(id)
.pre
Glavni template (*tfilename*) je html/smarty file, koji se svaki put koristi prilikom generiranje konaฤne stranice. U fileu su definirane pozicije za prikaz ureฤenih i slobodih modula, kao i includeovi za CSS i JS.
^ design
| id | unique id |
| name | ime teme i foldera u /img/themes |
| data | dio CSS-a koji se koristi |
| special | true za administracijski site |
| htmlareabodystyle | - ne korsti se (stlye za htmlarea) |
| htmlareapagestyle | - ne korsti se (stlye za htmlarea) |
^ layout
| id | uniqe id svake instance PAGE modula |
| user_id | - ne koristi se (id usera koji ga je postavio) |
| kategorija_id | kategoria u kojoj se modul nalazi |
| pozicija | 0,1,2 => ureฤene liste (stupci lijevo,sredina,desno); 3 => slobodni |
| module_id | id modula koju se prikazuje |
| redoslijed | integer po kojem se instance sortiraju unutar ureฤene liste DESC |
| module_args | argumenti koji se ลกalju toj instanci modula (npr. title=nesto) |
| state | stanje prikaza: 0 => prikazano, 1 => zarolano |
| notitle | true ukoliko se ne ลพeli prikazati naslov (titlebar) modula |
.pre
Foreign-key constraints:
"$3" FOREIGN KEY (module_id) REFERENCES modules(id) ON UPDATE CASCADE ON DELETE CASCADE
"$2" FOREIGN KEY (kategorija_id) REFERENCES kategorija(id) ON UPDATE CASCADE ON DELETE CASCADE
"$1" FOREIGN KEY (user_id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE
.pre
^ pre_layout
| layout_id | uniqe id svake instance SITE modula |
| template_id | id templatea koji je vezan za site u kojem se pokazuje modul |
| pozicija | isto kao i kod layout |
| redoslijed | isto kao i kod layout, ako je <0 prikazuju se *nakon* layout modula |
| module_id | isto kao i kod layout |
| module_args | isto kao i kod layout |
| notitle | isto kao i kod layout |
.pre
Foreign-key constraints:
"$2" FOREIGN KEY (module_id) REFERENCES modules(id) ON UPDATE CASCADE ON DELETE CASCADE
"$1" FOREIGN KEY (template_id) REFERENCES "template"(id) ON UPDATE CASCADE ON DELETE CASCADE
.pre
^ modules
| id | unique id svakog modula |
| name | sistemsko ime modula (ime filea bez '.php', npr. 'mod_docman') |
| fname | opisno puno ime (ispisuje se kod odabira) |
| hidden | true ako su skriveni (admin) moduli |
| nocache | true ako se nikada ne ลพeli koristit caching za taj modul |
| pos | veliฤina: 0 => Large or small, 1 => Large, 2 => Small |
| fdescript | opisni tekst (ispisuje se kod odabira) |
{feed: http://reblog.rot13.org/out/rss.php?user=1 full}
^ [Klase]
Ovdje se nalazi opisi korisnih klasa koje postoje unutar Strix engina.
Dokumentacija klasa koje su napisane tako da se dotiฤna moลพe iz njih automatski izgenerirati pomoฤu "phpDocumentora"<http://www.phpdoc.org/> nalazi se dostupna na http://plivaweb.pliva.hr/phpdoc/
phpDocumentator se pokreฤe sa:
.pre
$ phpdoc -o HTML:frames:phpedit -f class.foo.php -t /data/phpdoc
.pre
Opcije su:
-o : definira izlaz u obliku output:converter:templatedir
-f : datoteka koja sadrลพi klasu za koju generiramo dokumentaciju
-t : path do direktorija gdje ฤe se zapisati generirana dokumentacija
Viลกe o opcijama koje nudi phpDocumentator moลพe se saznati sa:
.pre
$ phpdoc -h
.pre
Dobar Quickstart manual nalazi se "ovdje"<http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_phpDocumentor.quickstart.pkg.html>.
Sve novo ลกto bi svaki STRIX developer trebao znati... :-)
Dvije funkcije koje se mogu koristi bilo gdje u kodu:
* _time_start('name_of_timer')
* _time_stop('name_of_timer')
Stranice pozvane sa profiling url-om oblika
http://www.example.com/?_do_profile=1
koristiti ฤe ove timer-e.
Timeri se mogu u ugnjeลพฤivati. To se koristi u STRIX-u za mjerenje
ukupnog vremena potroลกenog na Smarty, layout i cijelu stranicu.
Ako je profile ukljuฤen, postaviti ฤe se i cookie _do_profile, tako da moลพete dalje surfati po site-u i gledati profile informacije svake stranice.
Modifikacije u datotekama:
.pre
index.php
sysinc/dbinit.php
sysinc/time_profile.php
sysinc/MemCachedClient.inc.php
mod_admin_qlinks.php
templates/admin_qlinks.tpl
app/profile/*
.pre
^ Logiranje rada programa i greลกaka
_Logging for fun and profit!_
^^ Kako logirati pogreลกke?
jednostavno:
.pre
<?php
_debug("...");
_info("...");
_error("boink, error: "._var($foo));
?>
.pre
Level logiranja definira se u konfiguracijskoj datoteci ili u enviromentu servera. _Defaultne_ vrijednosti su:
.pre
<?php
$_LOG_ERROR = 1;
$_LOG_INFO = 0;
$_LOG_DEBUG = 0;
?>
.pre
*Oprez!* Info level se po _defaultu_ ne zapisuje u log.
^^ Log datoteke
Lokacija log file-a definirana je u `php.ini` datoteci (obiฤno u /etc/php4/apache/php.ini) kao:
.pre
; Log errors to specified file.
error_log = /var/log/php.log
.pre
Vlasnik log datoteke mora biti korisnik pod kojim se izvrลกava web server (na Debianu www-data) da bi se iลกta zapisivalo u nju osim PHP Warninga.
^^ ล to se trenutno logira?
U _server details_ admin quick links postoji ispis koji je trenutan log level, npr:
.pre
Logging: errors, debug, info
.pre
^ mod_docman
modul omoguฤava uvid u bilo koji dio stabla datoteka koje se nalaze na serveru (ispod root direktorija docmana koji se definira u konfiguraciji).
Zbog toga je nakon njegovog dodavanja na stranicu potrebno odrediti *root* direktorij te instance docman-a (u protivnom Strix vraฤa korisniku greลกku i ลกalje je e-mail-om jer mod_docman nije do kraja konfiguriran).
Meฤutim, ako se radi o *prvom dodavanju docmana* na novu instalaciju onda vrlo vjerojatno ne postoji niti jedan pod-direktorij. Rjeลกenje je jednostavno:
* instalirati jedan docman tako da ima podeลกen svoj *root* na sam root
** ova instanca moลพe se koristiti za dodavanje direktorija za druge docman-e
** ova instanca ฤe vidjeti *sve* datoteke u sustavu -- rad sa njome moลพe postati naporan zbog koliฤine podataka, pa se ne preporuฤa da bude jedina
* instalirati druge docmane tako da vide samo dio stabla direktorija
^ [Ostalo]
* [GlobalneConfigVarijable]
* [ParametriModula]
* [DozvoleACL]
* [SqlSkripta] za dodavanje OWN prava autorima
* [StrixDocumentManagementForProgrammers] (s naglaskom na import dokumenata)
^ mod_share_price
Prikazuje promjenu cijena dionica na zagrebaฤkoj (ZSE) i londonskoj burzi (LSE), ukljuฤujuฤi i grafiฤke prikaze.
^^ Parametri
Nema.
^^ [Ostalo]
Podaci s londonske burze dohvaฤaju se SOAP-om s posluลพitelja `rem.pliva.hr` gdje se nalazi izvorna baza s podacima. Cijene dionica sa zagrebaฤke burze pohranjeni su u lokalnoj bazi, dohvaฤaju se periodiฤki pokretanjem skripte `inc/scripts/zgstock-fetch.php`, npr.:
.pre
$ ./zgstock-fetch.php organisation
.pre
Grafovi koji prikazuju kretanje cijene dionica u posljednjih 30 odnosno 365 dana generiraju se periodiฤki pokretanjem odgovarajuฤe skripte.
LSE u posljednjih 30 dana:
.pre
$ ./share_graph.php organisation 30
.pre
LSE u posljednjih 365 dana:
.pre
$ ./share_graph.php organisation 365
.pre
ZSE u posljednjih 30 dana:
.pre
$ ./share_graph_zse.php organisation 30
.pre
ZSE u posljednjih 30 dana:
.pre
$ ./share_graph_zse.php organisation 365
.pre
^^ Datoteke
* mod_share_price.php
* templates/share_price.tpl
* inc/scripts/share_graph.php
* inc/scripts/share_graph_zse.php
* inc/scripts/zgstock-fetch.php
Opis svih modula koji se nalaze u STRIX-u. Za viลกe detalja pogledajte {category: development}.
^ Strix Document Management s naglaskom na import dokumenata
^ O dokumentu
Nove verzije ovog dokumenta bi se mogle naci na strix wikiju.
Verzija 1: Matko Anฤeliniฤ, Srpanj 2005., Inicijalna verzija
^ Opis tablica
^^ Tablica "document"
Glavna tablica. Zapisi i za dokumente i foldere.
| id | integer | jedinstveni id dokumenta |
| title | character varying(256) | naslov dokumenta (ne nuzno isto sto i filename) |
| description | text | opis - text/html polje s opisom dokumenta |
| activation_time | timestamp without time zone | vrijeme aktivacije dokumenta |
| expiration_time | timestamp without time zone | vrijema isteka dokumenta |
| creation_time | timestamp without time zone | vrijeme dokumenta (glavno datumsko polje na dokumentu) |
| lang_id | integer | jezik u tablici lang |
| allow_discussion | boolean | t/f - dopusteno otvaranje diskusije o dokumentu na forumu |
| author_id | integer | zastarjelo polje za autora. pogledaj tablicu document_author |
| parent_folder_id | integer | id parent foldera (zapis u istoj tablici) |
| folder | boolean | t/f - radi li se o folderu ili o dokumentu |
| locked | boolean | nije u upotrebi |
| approved | boolean | dokument je odobren - ako je false dokument se pojavljuje u "waiting for approval" popisu |
| keywords | text | kljucne rijeci |
| edit_time | timestamp without time zone | zadnje vrijeme promjene zapisa |
| edit_user | integer | korisnik koji je napravio zadnju promjenu (tablica users) |
| source | text | free text polje - atribut "izvor dokumenta" |
> PRIMARY KEY (id)
^^ Tablica "document_revision"
Tablica koja veze verziju dokumenta s filenameom na filesystemu servera. Filename
je samo filename i *ne* ukljucuje path (ni relativni ni apsolutni).
| document_id | integer | id dokumenta |
| version_num | smallint | redni broj verzija (nije vezan ni za jednu sekvencu) |
| filename | character varying(256) | naziv dokumenta na filesystemu (bez patha, samo filename) |
| filesize | integer | veliฤina fajla u bajtovima |
| edit_time | timestamp without time zone | vrijeme promjene |
| editor_id | integer | user koji je napravio promjenu |
| last_author | integer | polje last author (mijenja se preko sucelja) |
> PRIMARY KEY (document_id, version_num)
Napomena 1: Verzioniranje ide redom 1, 2, ....
Napomena 2: Iako folderi ne mogu imati verzije, za njih je svejedno potrebno
imati zapis u ovoj tablici s version_num=0, te proizvoljnim vrijednostima u
ostalim poljima.
Napomena 3: Lokacija dokumenta na disku se racuna ovako:
> $docman_dir/$document_id/$version_num/$filename
gdje je
* $docman_dir - konfiguracijska varijabla iz etc/.conf.php
* $document_id - id dokumenta (public.document.id ili public.document_revision.id)
* $version_num - redni broj verzije dokumenta (public.document_revision.version_num)
* $filename - vrijednost u polju public.document_revision.filename
^^ Tablica "document_author"
Vise zapisa po dokumentu. Informacija o autorima dokumenta koja se moze unositi
i mijenjati preko sucelja. Po defaultu bi trebao biti barem jedan zapis s npr.
osobom koja je uploadala dokument.
| document_id | integer | id dokumenta |
| version_num | smallint | verzija |
| author_id | integer | autor iz tablice users |
> PRIMARY KEY (document_id, version_num, author_id)
> FOREIGN KEY (document_id, version_num) referencira "document_revision"
^^ Ostale tablice
atributi
komentari
^ Dozvole
Koristi se STRIX-ov sustav dozvola - {category: ACL}. Oznaka za dokumente u ACL-u je 'file'.
^^ Tablice acl_user i acl_group
Opis ACL-a nije u scopeu ovog dokumenta pa se nece opisivati. Vazno je da postoje
te tablice, te zgodna plpgsql funkcija:
> acl_userObjectAddPerm(user_id, 'file', document_id, perm)
Za dokumente perm moze biti:
* 'PERM_READ' ili integer vrijednost 1
* 'PERM_SUGGEST' ili integer vrijednost 2
* 'PERM_AUTHOR' ili integer vrijednost 4
* 'PERM_OWN' ili integer vrijednost -1 ili 8
^^ Automatska, defaultna dodjela dozvola
Uploaderu se, na razini baze (triggerom) automatski dodjeljuje OWN pravo. Bez
obzira na suฤelje kojim je zapis zavrsio u bazi. Uploader je osoba upisana
u polju author_id prilikom inserta recorda u tablicu document.
Za one koji zele znati vise, za to je zaduzen sljedeci zapis u tablici
acl_users_default:
.pre
acl_id | default_sql
--------+-----------------------------------------------------------------------
file | SELECT 'file', NEW.id, author_id, -1 FROM document WHERE id = NEW.id
.pre
Dodatno, preporuka je da se OWN pravo dodijeli i svim osobama navedenim kao autori
dokumenta u tablici document_author.
> SELECT acl_userObjectAddPerm($user_id, 'file', $document_id, 'PERM_OWN');
^ Mali primjer importa dokumenta koristenjem PHP libraryja
Zamislimo slucaj da imamo na filesystemu dokument /data/tmp/dokument.doc kojeg
zelimo importati u novi folder "Novi folder" koji bi se nalazio ispod postojeceg
foldera XXXX sa id-jem 9.
Stanje sadrzaja foldera XXXX prije pokretanja skripte za import:
.pre
plivaweb=# select id, title, folder, depth, ord from getDocumentTree(9);
id | title | folder | depth | ord
----+-----------+--------+-------+-----
12 | Bayer.zip | f | 0 | 1
13 | Lilly.zip | f | 0 | 2
(2 rows)
.pre
Skripta za import: {file: docman-import.php}
.pre
<?php
include_once("sysinc/stdlib.php");
include_once "docman.php";
// globalna varijabla koja (ako je true) libraryju govori da
// pobrise OWN dozvole koje su automatski dodijeljene uploaderu (author_id)
// preko triggera u bazi
$PD_no_automatic_perms = false;
$parent_folder = 9;
$document_path = "/data/tmp/dokument.doc";
$in = array (
"title" => "Novi folder"
, "description" => ""
, "creation_time" => strftime("%Y-%m-%d")
, "lang_id" => "1"
, "allow_discussion" => "t"
, "author_id" => "4"
, "approved" => "t"
, "keywords" => "testni folder, document import"
, "edit_time" => ""
, "edit_user" => ""
, "source" => ""
, "folder" => "t"
);
$folder = PlivawebDocuments::createFolder($parent_folder, $in);
if (PlivawebDocumentsError::isError($folder)) die ($folder->text);
//ako smo ovdje u varijabli $folder imamo id novokreiranog foldera
$in = array (
"title" => "Moj dokument"
, "description" => "Dokument koji sam uploadao"
, "creation_time" => strftime("%Y-%m-%d")
, "lang_id" => 1
, "allow_discussion" => "t"
, "author_id" => 3
, "approved" => "t"
, "keywords" => ""
, "edit_time" => strftime("%Y-%m-%d")
, "edit_user" => 3
, "source" => ""
, "attributes" => array()
, "local_file_name" => $document_path
);
$did = PlivawebDocuments::addDocument($folder, $in);
if (PlivawebDocumentsError::isError($did)) die ($did->text);
echo "Document created";
?>
.pre
Pokrenuta skripta:
> $ php4 docmanimport-example.php plivaweb
Stanje sadrzaja foldera XXXX poslije pokretanja skripte za import:
.pre
plivaweb=# select id, title, folder, depth, ord from getDocumentTree(9);
id | title | folder | depth | ord
------+--------------+--------+-------+-----
4949 | Novi folder | t | 0 | 3
4950 | Moj dokument | f | 1 | 4
12 | Bayer.zip | f | 0 | 6
13 | Lilly.zip | f | 0 | 7
(4 rows)
.pre
Napomena 1: PHP library u `inc/docman.php` nije ni blizu kompletan i 100% fail safe,
ali je dobar start za nekoga tko zeli importati dokumente kroz skriptu.
Napomena 2: Nema razloga da se ne napise skripta u nekom drugom jeziku koja
bi direktno pisala po document* tablicama pridrzavajuci se gore opisanih pravila.
^ Dodatak: Funkcije za dohvat podataka
Postoji niz funkcija za rukovanje (dohvacanje podataka). One su mahom rekurzivne.
Popis tih plpgsql funkcija, zajedno s implementacijom moze se naci u
tables2/docman.sql.
Najcesce koristena takva funkcija je `getDocumentTree(folder_id integer)` koja
vraca popis zapisa iz document tablicom skupa s dvije dodatne kolone depth (dubina,
razina) te ord (redoslijed po kriteriju folder, title)
Npr.
.pre
plivaweb=# select id, title, folder, depth, ord from getDocumentTree(26);
id | title | folder | depth | ord
-----+------------------------------------+--------+-------+-----
27 | forms | t | 0 | 1
28 | AC form | f | 1 | 2
426 | ChemClient Izjava | f | 1 | 3
427 | Formular za publikacije | f | 1 | 4
417 | HTS_form.pdf | f | 1 | 5
418 | New_PL_form.pdf | f | 1 | 6
419 | New_PL_form.xls | f | 1 | 7
422 | PK&M form | f | 1 | 8
29 | Publications Form | f | 1 | 9
428 | Rjesenje GO | f | 1 | 10
429 | Zahtjev za nabavu | f | 1 | 11
33 | instructions | t | 0 | 12
35 | LabNotebooks law.pdf | f | 1 | 13
421 | Pravilnik za pisanje lab. dnevnika | f | 1 | 14
420 | Upute o kretanju NII.pdf | f | 1 | 15
30 | instruments | t | 0 | 16
31 | instruments_development.xls | f | 1 | 17
32 | instruments_research.xls | f | 1 | 18
37 | presentations | t | 0 | 19
(19 rows)
.pre
Preporuka je, ne koristiti ovu funkciju bas za svaku moguci dohvat dokumenata,
jer dodavanje WHERE uvjeta nad ovakav upit nece nimalo ubrzati dohvat podataka.
Ako bi se dodao Where uvjet, svejedno bi se za svaki upit izgenerirao kompletan
result set nakon cega se tek radi filtriranje. Bolje rjesenje je da se za svaku
specificnu upotrebu pri kojoj je bitna efikasnost pise svoja rekurzivna funkcija.
Napomena: Iako to nije slucaj sa funkcijama u tables2/docman.sql, zgodno je
dodati STABLE u definiciji takve funkcije sto bi moglo bitno ubrzati te funkcije
u nekim slucajevima. (Npr. u sucajevima kada se u jednom upitu radi visestruko
pozivanje iste funkcije s istim parametrima).
U STRIXU postoje dvije vrste plugina:
* Smarty plugini `(sysinc/plugins/*.php)` - koriste se u templateima
* interni plugini za razliฤite infrastrukture `(inc/plugins/*)` - koriste se u PHP datotekama
^ Smarty plugini
Detaljna dokumentacija o njihovoj arhitekturi nalazi se na [http://smarty.php.net/manual/en/plugins.php]
Osim standradnih plugina koji dolaze sa Smartyjem, u STRIXU postoje i custom-made Smarty plugini:
{search: plugin smarty}
^ interni plugini
Interni plugini postoje za sljedeฤe infrastrukuture (svaka ima svoj direktorij u inc/plugins):
{search: plugin internal}
za ACL _vidi_ [UserCanDoOnObject]
^ Hacking ACL
Ovo je _quick guide_ kako napraviti zanimljive stvari sa ACL-ovima.
^^ Nasljeฤivanje ACL-ova za kategorije
Kako pogledati koja ktegorija nasljeฤuje od koje?
.pre
select
(select url from kategorija where id = parent_object_id),
(select url from kategorija where id = object_id)
from acl_inherits
where acl_id = 'kats' and parent_acl_id = 'kats'
.pre
^ "PostgreSQL"<http://www.postgresql.org/> autorizacije koriลกtenjem ident-a
/etc/postgresql/pg_ident.conf:
.pre
# MAPNAME IDENT-USERNAME PG-USERNAME
skole dpavlin strix
skole www-data strix
...
.pre
/etc/postgresql/pg_hba.conf:
.pre
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
local skole strix ident skole
.pre
^ SQL za dohvaฤanje podataka iz P Connecta (ime, prezime, kompanija, e-mail)
.pre
SELECT
companycode,
lname || ' ' || name AS fullname,
email
FROM hemployees
WHERE
active=1 AND
(
facility IS NULL OR
facility='C'
) AND
trim(coalesce(email,''))<>'' AND
trim(coalesce(lname,''))<>''
ORDER BY
companycode,
lname,
name
;
.pre
^ SQL za "odrollavanje" naziva kompanija za gornje ljude
.pre
SELECT
code,
name
FROM legalchart_hstructure
WHERE
code IN (
SELECT DISTINCT
companycode
FROM hemployees
WHERE
active=1 AND
(
facility IS NULL OR
facility='C'
) AND
trim(coalesce(email,''))<>'' AND
trim(coalesce(lname,''))<>''
)
;
.pre
^ rss/*
Ova infrastruktura namijenjena je da omoguฤi ลพeljenim modulima generiranje RSS feeda. Feedove generira skripta `rss/rssfeeder.php` kojoj je potrebno predati tri GET parametra:
* rss_uid - ID korisnika za kojeg je namijenjen dotiฤni feed kako bi se feed izgenerirao u skladu s njegovim dozvolama
* rss_kid - ID kategorije u kojoj se nalazi sadrลพaj za kojeg ฤe biti generiran feed
* rss_ct - ID tipa sadrลพaja, dogovor je da, kad god je to moguฤe, dotiฤni odgovara ID-ovim ACL-a iako se to nigdje striktno ne provjerava
U skripti `rss/rssfeeder.php` nalaze se konstante koje omoguฤavanju njezino konfiguriranje:
* DEBUG - aktivira debug naฤin rada u kojem skripta prima sve konekcije (u normalom naฤinu rada skripta prima konekcije samo s localhosta (`127.0.0.1`) odnosno s IP adrese definirane u konfiguracijskoj varijabli `_rss_ip_regex` (u datoteci `etc/*.conf.php`), po pretpostavci `false`.
* PLUGIN_DIR - direktorij s RSS pluginima, po pretpostavci `../inc/plugins/rss/`
* PLUGIN_EXT - ekstenzija za plugin datoteke, po pretpostavci `.php`
* PLUGIN_FUNCTION_PREFIX - prefix za funkciju koja se poziva unutar plugina, po pretpostavci `rssfeed_`
* CACHE_DIR - direktorij za RSS cache, po pretpostavci `/tmp`
* DEFAULT_TTL - vijeme ลพivota cachea (Time To Live) u sekundama, po pretpostavci `300`
Za generiranje RSS-a skripta `rss/rssfeeder.php` koristi biblioteku `inc/ContentFeeder.class.php`.
Svaki modul koji ลพeli koristiti ovu infrastrukturu (tj. generirati RSS feed) mora imati zasebnu datoteku u direktoriju `inc/plugins/rss/`. Ime datoteke mora biti isto kao i dogovoreni ID tipa sadrลพaja (parametar `rss_ct`), a pretpostavljena ekstenzija datoteke je `.php`.
Unutar datoteke plugina mora se nalaziti funkcija ฤije je ime kombinacija PLUGIN_FUNCTION_PREFIX-a i ID tipa sadลพaja. Dotiฤna funkcija vraฤa rezultat odgovarajuฤeg upita iz baze pomoฤu metode `getAllTable`. Iz vraฤenog rezultata skripta `rss/rssfeeder.php` izgenerirat ฤe RSS feed.
^^ Primjer
Za modul Vijesti (`mod_news`) dogovoreni identifikacijski parametar `news`. Zato se datoteka u `inc/plugins/rss` zove `news.php`, a funkcija koja ฤe biti pozvana zove se `rssfeed_news`:
.pre
<?php
$rssfeed_channel = "News";
$rssfeed_description = "News";
$rssfeed_ttl = "300";
function rssfeed_news ($uid, $kid) {
$q = new SQLquery("SELECT *
FROM news, news_kategorija, kategorija
WHERE news.id = news_kategorija.news_id
AND kategorija.id = news_kategorija.kategorija_id
AND news_kategorija.kategorija_id = " . $kid . "
AND news.visible = TRUE
AND news_kategorija.approved = TRUE
AND news_kategorija.archived = FALSE
AND userCanDoOnObject (" . $uid . ", 1, 'news', news.id)
AND (news_kategorija.time_to > NOW() OR news_kategorija.time_to IS NULL)
AND (news_kategorija.time_from < NOW() OR news_kategorija.time_from IS NULL)
ORDER BY news_kategorija.pos DESC, news.date DESC");
$data = $q->getAllTable();
return $data;
}
?>
.pre
Na poฤetku plugina nalaze se tri konfiguracijske varijable:
* rssfeed_channel - ime RSS kanala
* rssfeed_description - opis RSS kanala
* rssfeed_ttl - vrijeme ลพivota cache, override za vrijednost u `rss/rssfeeder.php`
Za funkciju je dovoljno da sadลพava samo odgovarajuฤi SQL query te da vrati "sirove" rezultate.
---
Mislim da ฤe trebati CACHE_DIR razdjeliti nekako, npr. site_name/rss_kid/rss_uid-rss_ct jer ฤemo ลพeljeti pobrisati samo dio RSS-ova nakon ลกto npr. netko snimi novu vijest, a mi je preuzimamo na 10 drugih mjesta na site-u.
_contributed by {user: dpavlin@pliva.hr} on {date: 2006-11-18 00:34:16 GMT}_
^ mod_webnote
Modul koji omoguฤava editiranje _post-it like_ biljeลกki koriลกtenjem web-a.
^^ Parametri
* name=foobar - kreira webnote koji se zove foobar
Parametri se prenose URL enkodirani (%20 umjesto razmaka) i u UTF-8
enkodingu (oprez sa naลกim slovima).
Fiksni parametri modula `URL do strix.cgi, ลกirina (100%), visina (600px)` su upisani unutar templatea `webnote.tpl`.
^^ Datoteke
* mod_webnote.php
* templates/webnote.tpl
* tables2/webnote.sql
* app/webnote/*
^ Box model
Ako je neki `block` element (DIV, `TABLE`) preลกirok te se zbog njega pojavljuje horizontalni scrollbar, pokuลกajte sljedeฤe:
.pre
#block {
box-sizing: border-box !important; /* for M$IE 5.x, but doesn't hurt in 6+ as well.
also proposed for upcoming CSS3 */
-moz-box-sizing: border-box !important; /* for Mozilla/Gecko */
}
.pre
Za viลกe informacija pogledajte "ovdje"<http://www.quirksmode.org/css/box.html>.
^ Kako zamijeniti tekst slikom?
> NAPOMENA: kako bi ovo radilo, dotiฤni HTML element mora biti block-level element.
Jedan od naฤina je content dotiฤnog elementa staviti u neki HTML tag koji po defaultu nema nikakav stil, npr. `DIV` ili (preporuฤeno) `SPAN`. Dakle:
.pre
<h1>Ovo je neki naslov</h1>
.pre
postaje
.pre
<h1><span>Ovo je neki naslov</span></h1>
.pre
Zatim se CSS-om dotiฤnom elementu (ovdje H1) dodijeli background image, te mu se podesi veliฤina tako da odgovara veliฤini tog image-a, a child element (`SPAN`) se sakrije (display: none). Takoฤer se `overflow` stavi na `hidden` (za sluฤaj da je originalni tekst ลกiri od replacement slike). Dakle:
.pre
H1 {
background-image: url(foo.jpg);
background-repeat: none;
width: 100px; /* prilagoditi prema velicini slike */
height: 100px; /* prilagoditi prema velicini slike */
overflow: hidden;
}
H1 SPAN {
display: none;
}
.pre
Meฤutim, ova metoda se ne preporuฤuje, jer osim ลกto izgleda ruลพno (zahtijeva jedan _dummy_ element u strukturi HTML-a), veฤina screen readera ima problema sa display: block, te time HTML gubi svoj accessibility. Sreฤom, postoji alternativno rjeลกenje: u CSS dotiฤnog elementa se jednostavno stavi atribut `text-indent` sa jako velikom *negativnom* vrijednoลกฤu, npr. -9000px. Dakle, HTML ostaje kakav je i bio, a novi CSS je:
.pre
H1 {
background-image: url(foo.jpg);
background-repeat: none;
width: 100px; /* prilagoditi prema velicini slike */
height: 100px; /* prilagoditi prema velicini slike */
text-indent: -9000px;
}
.pre
Zaฤuฤujuฤe, obje metode rade dobro na svim _mainstream_ browserima. `:-)`
Za viลกe informacija o prvoj metodi vidi "ovdje"<http://www.stopdesign.com/articles/replace_text/>, a o drugoj vidi "ovdje"<http://phark.typepad.com/phark/2003/08/accessible_imag.html>.
^ Kako u plain HTML-u detektirati postojanje/verziju M$ Internet Explorera?
Internet Explorer 5.0 i veฤe verzije prepoznaje neke uvjete unutar HTML komentara, tzv. _conditional comments_
Ostali browseri zanemarit ฤe cijeli takav blok kao obiฤan HTML komentar.
Evo primjera:
.pre
<body>
<!--[if IE]>
According to the conditional comment, this is Internet Explorer.
<![endif]-->
<!--[if IE 5]>
According to the conditional comment, this is Internet Explorer 5.
<![endif]-->
<!--[if IE 5.0]>
According to the conditional comment, this is Internet Explorer 5.0.
<![endif]-->
<!--[if IE 5.5]>
According to the conditional comment, this is Internet Explorer 5.5.
<![endif]-->
<!--[if IE 6]>
According to the conditional comment, this is Internet Explorer 6.
<![endif]-->
<!--[if gte IE 5]>
According to the conditional comment, this is Internet Explorer 5 and up.
<![endif]-->
<!--[if lt IE 6]>
According to the conditional comment, this is Internet Explorer lower than 6.
<![endif]-->
<!--[if lte IE 5.5]>
According to the conditional comment, this is Internet Explorer lower or equal to 5.5.
<![endif]-->
</body>
.pre
Za viลกe informacija vidi "ovdje"<http://www.quirksmode.org/css/condcom.html>.
*Opฤenito:*
* dizajn (HTML, !JavaScript, CSS) mora biti kompatibilan s web preglednicima Firefox 1.0+, Mozilla 1.7+, IE 5.5+
* optimalna rezolucija je 1024x768, na drugim rezolucijama ne smije dolaziti do gubitka sadrลพaja
* izgled tablica, linkova, naslova, podnaslova, teksta i ostalih elemenata sadrลพaja treba biti definiran CSS-om
* upotreba !JavaScripta je moguฤa
* Java i Flash elementi su nepoลพeljni, kao i svi ostali elementi koji nisu u funkciji sadrลพaja, a znaฤajno produลพuju vrijeme uฤitavanja stranice
*Koncept dizajna:*
* koncept dizajna moลพe se vidjeti na "STRIX portalu"<http://www.strix-portal.com/>
* srediลกnji dio stranice sastoji se od 3 stupca, srednji strupac je najลกiri i predtavlja centralni sadrลพaj na stranici
* svaki stupac sastoji se od viลกe modula (vijesti, dokumenti, anketa, kalendar...) koji su smjeลกteni jedan ispod drugog
* svaki modul na vrhu ima traku s naslovom (naslovi su ฤisti tekst, a ne slika)
* na traci od modula nalaze se ikone za minimiziranje modula, pomicanje modula (gore, dolje, lijevo i desno), pretplatu na promjenu sadrลพaja tog modula i help za taj modul
* izbjegavati da tekst bude dio integralni slike (ukoliko je predviฤeno da se u pozadini dotiฤnog teksta nalazi slika), takav sluฤaj treba rijeลกiti na naฤin da se tekst napiลกe HTML-om preko slike koja je u pozadini (od ovog pravila su izuzeti razni logotipovi)
* navigacija mora podrลพavati barem 4 nivoa dubine stranica (npr. prvi nivo moลพe biti horizontalna navigacija, a ostali nivoi se mogu nalaziti u vertikalnoj navigaciji; primjer dostupan na [http://www.strix-portal.com/it/])
^ Software koji treba biti instaliran za Strix
* Linux
* apache (ili apache2)
* postgresql (konfiguriran sa odgovarajuฤim autorizacijama - [PostgreSQLAuth])
* php4 php4-cli php4-common php4-ldap php4-pear php4-pgsql libapache2-mod-php4
^^ Podeลกavanje
^^^ aktivirati postgresql podrลกku u php-u
/etc/php4/apache2/php.ini:
extension=pgsql.so
Ukoliko ovo nedostaje, pri prvom pristupu na Strix site dobiti ฤe se prazna strana duลพine 0.
^ Kako instalirati prazan Strix?
Za listu software-a koji treba biti instaliran pogledajte [StrixPrerequisites]
* napraviti checkout strix-a iz repozitorija
$ cd _data_ $ mkdir foo
$ cd foo
$ svn co svn://svn.pliva.hr/strix/foo
* popraviti permissione i napraviti direktorije za upload
$ cd foo
$ ./utils/fix_perms.sh
* napraviti konfiguracijske datoteke
etc/foo.conf.php
etc/foo-httpd.conf
Detaljan opis parametara u `foo.conf.php` je na stranici GlobalneConfigVarijable.
* ukljuฤiti virtualni host u apache configuraciju
Dodati u `/etc/apache/httpd.conf` (ili ekvivalentnu) neลกto kao
Include /data/foo/strix/etc/foo-httpd.conf
Pretpostavlja se da je DNS podeลกen ispravno.
Nakon toga restartati apache
/etc/init.d/apache reload
* kreirati korisnika i bazu podataka za site, dodati plpgsql jezik u bazu
$ createuser --no-adduser --no-createdb foouser
$ createdb --encoding=latin2 --owner=foouser foo
$ createlang plpgsql foo
editirati `tables2/Makefile` tako da varijable `db` i `user` budu iste kao u pretkodnom koraku
db = foo
user = foouser
....
nakon toga pokrenuti u tables2 direktoriju `make init`
$ cd tables2
$ make init
* napraviti direktorij za logove
$ sudo mkdir /var/log/strix/
$ sudo chown www-data /var/log/strix/
^ Kreiranje site-a koriลกtenjem FreeMind-a
Ovo podrazumjeva da imate napravljenu mapu web-a u
[http://freemind.sourceforge.net FreeMind]-u snimljenu u `/data/foo/strix/utils/freemind/` i da ลพelite stvoriti prazan site.
$ cd /data/foo/strix/table2/
$ make init
Pogledajte takoฤer:
NoviSite
^ string2float
.pre
=> select string2float('12.345,67');
string2float
--------------
12345.67
.pre
Funkcija iz predanog podataka pokuลกava izbaciti sve toฤke, a zarez zamijeniti toฤkom. Tako dobiveni podatak se pokuลกava pretvoriti u `float`. U sluฤaju da pretvorba ne uspije, funkcija vraฤa `NULL` vrijednost.
^ mod_static3
Modul za ispis statiฤkog HTML-a.
^^ Parametri
* lid=10000 - override za ID layouta dotiฤne instance modula (ovako se moลพe preuzeti statiฤki sadrลพaj iz neke druge instance mod_static3
*OPREZ:* U sluฤaju koriลกtenja ovog parametra promjene na *bilo kojoj* instanci modula su vidljive na *svim modulima* koji koriste taj layout ID.
^^ Datoteke
* mod_static3.php
* templates/static3.tpl
* templates/static3_edit.tpl
* tables2/static3.sql
insert into acl_user
select 'file', document_id, author_id, -1
from document_author
where version_num = (
select max(version_num)
from document_revision
where document_revision.document_id = document_author.document_id
) and not exists (
select *
from acl_user
where acl_id = 'file'
and object_id = document_id
and user_id = author_id
) and document_id in (select id from getDocumentTree(179)) ;
Ovaj zadnji uvjet ograniฤava dio stabla
^ mod_sitemap
Prikazuje strukturu stranica po pojedinim siteovima, uzimajuฤi u obzir i stranice u multistaticima.
*Upozorenje:* Da bi se site pojavio u site mapu, u tablici `site` *MORA* imati definiran redoslijed prikaza (atribut `ordstr`).
^^ Parametri
* site_id=1 - prikazuje *samo* site map od dotiฤnog sitea
^^ Datoteke
* mod_sitemap.php
* templates/sitemap.tpl
^ mod_docman_selector
Ispisuje datoteฤnu strukturu prema dobivenom REQUEST parametru i omoguฤava odabir nekog direktorija i datoteke. Osnovna svrha je bila realizirati "Browse..." moguฤnost nad dokumentima koji se nalaze u document manageru. Poziva se iz Smarty plugina `sysinc/plugins/function.docman_selector.php`.
Za generiranje stabla modul koristi relativno spor !WebFXTree library sumljive licence.
^^ Parametri
Nema.
^^ Datoteke
* mod_docman_selector.php
* templates/docman_selector.tpl
^ mod_secerror
Modul koji obraฤuje pogreลกku sigurnosti (security error) i session timeout. Pretpostavljeno je ponaลกanje obrada pogreลกke sigurnosti, za obradu session timeouta potrebno je predati modulu odgovarajuฤi parametar.
^^ Parametri
* inactivity=true - definira ponaลกanje modula tako da obraฤuje session timeout
^^ Ostalo
Duลพina neaktivnosti korisnika nakon koje dolazi do session timeouta definira se u sekundama, a nalazi se zapisana u bazi (tablica `users_preferences`, atribut `inactivity`).
^^ Datoteke
* mod_secerror.php
* templates/secerror.tpl
* templates/inactivity_error.tpl
^ mod_rss
Prikazuje jedan ili viลกe RSS feedova.
^^ Parametri
Nema.
^^ Datoteke
* mod_rss.php
* templates/rss.tpl
* templates/rss_options.tpl
* templates/rss/*.tpl
^ mod_dictionary
^ mod_dictionary_popup
^ mod_dict_global
Modul koji ima funkcionalnost rjeฤnika (veลพe pojam uz objaลกnjenje).
^^ Parametri
* kat_id=10000 - override za ID kategorije u kojoj se nalazi rjeฤnik (po defaultu kategorija rjeฤnika je ona ฤijem se layoutu rjeฤnik nalazi, no na ovaj naฤin se u jednoj kategoriji moลพe preuzeti sadrลพaj rjeฤnika iz druge kategorije)
^^ Ostalo
Rjeฤnik ima moguฤnost povezivanja pojmova koji se pojavljuju u opisima s njihovim objaลกnjenjima u istom ili drugim rjeฤnicima (npr. ukoliko se u opisu nekog pojma pojavljuje rijeฤ "raฤunalo", a dotiฤna rijeฤ ima objaลกnjenje u rjeฤniku, rijeฤ "raฤunalo" je istovremeno i link na taj opis).
Pretraลพivanje rjeฤnika i povezivanje pojmova izvodi skripta `inc/scripts/dictionary_link.php`. Kao obavezni parametar predaje joj se ime konfuguracijske datoteke u direktoriju `etc`, bez ekstenzije, npr:
$ ./dictionary_link.php organisation
^^ Datoteke
* mod_dictionary.php - glavna programska datoteka
* mod_dictionary_popup.php - ispisuje objaลกnjenje u popupu
* mod_dict_global.php - globalni rjeฤnik, agregira sve rjeฤnike unutar sitea na kojem se nalazi
* templates/dictionary.tpl
* templates/dictionary_edit.tpl
* templates/dictionary_global.tpl
* templates/dictionary_popup.tpl
* templates/dictionary_small.tpl
* tables2/dictionary.sql
* inc/scripts/dictionary_link.php
^ mod_subscribe_popup
Prlikom pretplaฤivanja ili otkazivanja postojeฤe pretplate ispisuje korisniku relevatnu poruku u popupu.
^^ Parametri
Nema.
^^ Datoteke
* mod_subscribe_popup.php
* templates/subscribe_popup.tpl
^ mod_subscribe_web
Modul za prikaz dobivenih obavijesti o promjenama sadrลพaja.
^^ Parametri
Nema.
^^ Datoteke
* mod_subscribe_web.php
* templates/subscribe_web.tpl
^ mod_subscribe_kat
Modul koji omoguฤava pretplaฤivanje na cijelu kategoriju. Ispisuje se samo ukoliko u dotiฤnoj kategoriji postoji sadrลพaj na kojeg se moลพe pretplatiti.
^^ Parametri
Nema.
^^ Datoteke
* mod_subscribe_kat.php
* templates/subscribe_kat.tpl
^ PostgreSQL
http://www.postgresql.org/
Strix radi na PostgreSQL-u 7.4 ili novijima.
^ subscribe/*
Plugini za subscribe vraฤaju naslove sadrลพaja prema proslijeฤenom ID-u. Ovo je bitno kako bi se prilikom slanja obavijesti korisnicima mogli izgenerirati smisleni naslovi sadrลพaja koji je promijenjen.
*OPREZ: OVU ISTU INFRASTRUKTURU KORISTI I CHANGELOG.*
*Razlog tome je ลกto changelog ima istu potrebu kao i subscribe (saznati naslov sadrลพaja iz njegovog ID-a), pa nije imalo smisla raditi drugu infrastrukturu za istu stvar. Nezgodno je samo ime postojeฤe infrastrukture koje po niฤemu ne govori da je i changelog koristi.*
U sluฤaju koriลกtenja infrastrukture u svrhe pretplate plugine pozivaju skripte `inc/scripts/subscribe_check.php` i `inc/scripts/subscribe_reports.php`, a u svrhe changeloga plugine poziva skripta `sysinc/changelog.php`.
Svaki modul koji koristi ovu infrastrukturu mora imati zasebnu datoteku. Imena datoteka moraju odgovarati ID-ovima ACL-a za pojedini tip sadrลพaja (tablice `acl_register` i `acl_nonregister`).
Ime funkcije unutar datoteke mora se sastojati od stringa `subscribe_` i imena datoteke. Funkcija vraฤa pripremljeni znakovni niz.
^^ Primjer
Za modul Vijesti (`mod_news`) dogovoreni identifikacijski parametar je `news`. Zato se datoteka u `inc/plugins/subscribe` zove `news.php`, a funkcija izgleda ovako:
.pre
<?php
function subscribe_news ($params) {
if (isset($params["id"])) {
$q = new SQLquery ("SELECT title FROM news WHERE id = " . $params["id"]);
$row = $q -> getNextRow();
return $row["title"];
}
}
?>
.pre
^ function.roll_link.php
Ispisuje link koji odrolava i zarolava neki sadrลพaj koji se nalazi negdje drugdje na stranici (ne odmah ispod linka, pa se iz tog razloga ne koristi `block.roll.php`)
^^ Parametri
* id - jedinstveni ID sadrzaja, najฤeลกฤe kombinacija naziva modula i brojke - *OBAVEZAN PARAMETAR*
* img - ime slike koja se ispisuje pored linka (ista slika i za odrolavanje i za zarolavanje)
* img_hide - ime slike koja se ispisuje pored linka kada je sadrลพaj skriven odnosno zarolan
* img_show - ime slike koja se ispisuje pored linka kada je sadrลพaj pokazan odnosno odrolan
* class - ime CSS klase koja se definira nad pripadajuฤim `<a>` tagom
* onclick="alert('foo');" - dodatna javascript akcija koja se izvrลกava na klik
* nocokie - override cookiea, ako se definira nocokie="true", sadrลพaji ฤe prilikom svakog uฤitavanja stranice biti odrolani ili zarolani prema default opciji (ako je navedeno "hide" bit ฤe zarolani, a ako opcija default nije navedena biti ฤe odrolani). Nenavoฤenem ove opcije iskoriลกtava se cookie za pamฤenje proลกlog stanja prilikom uฤitavanja stranice.
* action_text="foo" - tekst na kojeg ฤe se klikati za odrolavanje odnosno zarolavanje sadrลพaja
* default - pretpostavljeno stanje sadrลพaja nakon uฤitavanja stranice, npr. ako se navede default="hide" sadrลพaj ฤe biti zarolan odn. skriven. Nenavoฤenje ove opcije ฤe rezultirati odrolanim sadrลพajem po pretpostavci
^ block.roll.php
Blok funkcija (ima poฤetni i zavrลกni tag: `{roll} ... {/roll}`) koja sluลพi za omoguฤavanje odrolavanja i zarolavanja sadrลพaja izmeฤu tagova (mijenja vidljivost `<div>` taga u kojem se nalazi sadrลพaj)
^^ Parametri
* id="repoz_21" - jedinstveni ID sadrzaja, najฤeลกฤe kombinacija naziva modula i brojke - *OBAVEZAN PARAMETAR*
* action_text="foo" - tekst na kojeg ฤe se klikati za odrolavanje odnosno zarolavanje sadrลพaja - *OBAVEZAN PARAMETAR*
* html_pre="<B>" - HTML tag(ovi) koji prethodi action_text-u
* html_post="</B>" - HTML tag(ovi) koji slijedi iza action_text-a
* default - pretpostavljeno stanje sadrลพaja nakon uฤitavanja stranice, npr. ako se navede default="hide" sadrลพaj ฤe biti zarolan odn. skriven. Nenavoฤenje ove opcije ฤe rezultirati odrolanim sadrลพajem po pretpostavci.
* nolink - omoguฤava da se link ne ispisuje
* nocokie - override cookiea, ako se definira nocokie="true", sadrลพaji ฤe prilikom svakog uฤitavanja stranice biti odrolani ili zarolani prema default opciji (ako je navedeno "hide" bit ฤe zarolani, a ako opcija default nije navedena biti ฤe odrolani). Nenavoฤenem ove opcije iskoriลกtava se cookie za pamฤenje proลกlog stanja prilikom uฤitavanja stranice.
* onclick="alert('foo');" - dodatna javascript akcija koja se izvrลกava onclick na action_text
* no_img - override slike, ako je "true" ne pojavljuje se sliฤica pored linka
^ function.rich_edit.php
Zamijenjuje `<TEXTAREA>` element s rich editorom [FCKeditor http://www.fckeditor.net/]. Dotiฤni editor nalazi se instaliran u direktoriju `inc/FCKeditor/`.
^^ Parametri
* name="bar" - ime polja - *OBAVEZAN PARAMETAR*
* value="foo bar foo" - vrijednost koju treba upisati u editor
* imgdir="/foo/bar" - direktorij s bibliotekom slika koji je relativan u odnosu na direktorij `images` (u primjeru konaฤan direktorij sa slikama bio bi `/images/foo/bar`) - *OBAVEZAN PARAMETAR UKOLIKO SE ลฝELE KORISTITI SLIKE*
* width=400 - ลกirina editora u px
* height=300 - visina editora u px
^ function.rating.php
Ispisuje suฤelje za ocjenjivanje sadrลพaja.
^^ Parametri
* see_results - ID jednog korisnika ili array ID-jeva korisnika koji smiju vidjeti rezultate ocjenjivanja
* ct="foo" - ID tipa sadrลพaja (acl ID) koji se ocjenjuje - *OBAVEZAN PARAMETAR*
* cid=1 - ID konkretnog sadrลพaja koji se ocjenjuje - *OBAVEZAN PARAMETAR*
* extra_js - opcionalni javascript kod
* text="bar" - alternativni tekst koji ฤe biti ispisan (po defaultu piลกe /Rate usability/)
* style="foo" - za help link: prefix ispred imena ikone, ujedno i sufiks za ime CSS klase koja se definira nad eventualnim tekstualnim linkom
* stat="down" - statistika se ispisuje s donje strane suฤelja (defaultno ponaลกanje)
* stat="right" - statistika se ispisuje s desne strane suฤelja
^ printable/*
Svaki modul koji koristi ovu infrastrukturu mora imati zasebnu datoteku. Imena datoteka moraju odgovarati parametru `name` koji se koristi u [PluginiPrint]. Ime funkcije unutar datoteke mora se sastojati od stringa `printable_` i imena datoteke. Funkcija vraฤa pripremljeni HTML.
^^ Primjer
Za modul Vijesti (`mod_news`) dogovoreni identifikacijski parametar `name` je `news`. Zato se datoteka u `inc/plugins/printable` zove `news.php`, a funkcija izgleda ovako:
.pre
<?php
function printable_news ($params) {
$q = new SQLquery ("SELECT title, lead, content, date FROM news WHERE id = " . $params["id"]);
...
$printable = "<i>" . $row["date"] . "</i><br><br>";
...
return $printable;
}
?>
.pre
^ function.print.php
Ispisuje ikonu za printanje koja je link na popup prozor u kojem ฤe se otvoriti dotiฤni sadrลพaj formatiran u printer-fiendly formatu.
^^ Parametri
* id=1 - ID sadrลพaja kojeg treba formatirati - *OBAVEZAN PARAMETAR*
* name="bar" - ime tipa sadrลพaja kojeg treba formatirati, ovisno o nazivu internog plugina infrastrukture [PluginiPrintable] - *OBAVEZAN PARAMETAR*
* link_text="foo" - alternativan tekst koji se ispisuje kao link na popup (po defaultu "printable version")
^ function.help.php
Ispisuje ikonu za help koja je link na odreฤeno poglavlje helpa (najฤeลกฤe poฤetno).
^^ Parametri
* id=1 - ID poglavlja helpa na koje se treba uฤitati u popup nakon klika na ikonu - *OBAVEZAN PARAMETAR*
* style="foo" - prefix ispred imena ikone, ujedno i sufiks za ime CSS klase koja se definira nad eventualnim tekstualnim linkom
* text="bar" - proizvoljan tekst koji se ispisuje kod help ikone (takoฤer link)
* showtitle=true - indikator ispisuje li se naslov help poglavlja ili ne (uzima se u obzir samo kada nije definiran parametar text)
^ function.db_tabs.php
Wrapper plugin za stari plugin `tabs` (function.tabs.php). Osnovna je razlika ลกto veฤinu konfiguracijskih parametara db_tabs drลพi u bazi.
^^ Parametri
* name="bar" - ime grupe tabova koju treba prikazati (atribut `name` u tablici `tab_group`) - *OBAVEZAN PARAMETAR*
* part -
* oframe -
* active -
* disabled -
* disabled2 -
* args -
* is_print -
* onactivate -
^^ Relevantne tablice u bazi
^^^ tab
popis svih tabova
id | name | template | caption | url | hook | icon
----+------------+-------------------+---------------+-----+------+------
1 | contact | bp_contact.tpl | Kontakt | | |
2 | activities | bp_activities.tpl | O meni | | |
3 | general | bp_general.tpl | Ostalo | | |
4 | education | bp_education.tpl | Moji predmeti | | |
5 | iknow | bp_iknow.tpl | Moja znanja | | |
* id - ID taba
* name - ime taba, ujedno i akcija za update (vrijednost GET parametra `bp_update`)
* template - ime datoteke koja sluลพi kao template za ovaj tab
* caption - natpis na tabu
* url -
* hook -
* icon -
^^^ tab_group
popis svih grupa tabova
id | name | template_pre | template_post | html_pre | html_post | has_endline
----+-----------+--------------+---------------+----------+-----------+-------------
1 | uฤenik | bp_top.tpl | | | | t
2 | djelatnik | bp_top.tpl | | | | t
* id - ID grupe tabova
* name - ime grupe tabova, ovo se ime predaje prilikom poziva plugina
* template_pre - template koji se include-a iznad templatea svakog taba u ovoj grupi
* template_post - template koji se include-a ispod templatea svakog taba u ovoj grupi
* html_pre - HTML koji se include-a iznad cijele tablice
* html_post - HTML koji se include-a ispod cijele tablice
* has_endline - boolean vrijednost postoji li ispod cijele tablice traka
^^^ tab_order
vezna tablica koja povezuje tabove u grupe i odreฤuje njihov redoslijed
tab_group_id | tab_id | position
--------------+--------+----------
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
2 | 1 | 1
2 | 4 | 2
2 | 5 | 3
2 | 3 | 4
* tab_group_id - ID grupe
* tab_id - ID taba
* position - redoslijed, s lijeva na desno, dotiฤnog taba u dotiฤnoj grupi
^ function.calendar.php
Ispisuje tekstualno input polje za unos datuma i ikonu ฤijim klikom se otvara DHTML/!JavaScript kalendar preuzet s http://www.dynarch.com/projects/calendar/. Datoteke od kalendara nalaze se u direktoriju `inc/calendar/`.
^^ Parametri
* name="bar" - ime polja - *OBAVEZAN PARAMETAR*
* value="2005-10-10" - vrijednost koju treba upisati u polje
* size=10 - veliฤina polja
* onclick="document.chlog_prefs.chlog_time.checked=true;" - definicija onclick akcije
* align="Tl" - definicija na koju se stranu "otvara" kalendar
* buttonborder="true" - definira ima li gumb okvir ili ne
* time="1" - definicija treba li kanledara ispisivati i sat
* class="bar" - CSS klasa za input polje
* readonly="1" - read-only kalendar (prisiljava korisnika da za odabir datuma koristi DHTML/!JavaScript kalendar)