r59873 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r59872‎ | r59873 | r59874 >
Date:08:55, 9 December 2009
Author:mkroetzsch
Status:deferred
Tags:
Comment:
committing updates from Fabian, addressing various feature requests and bug reports
Modified paths:
  • /trunk/extensions/SemanticResultFormats/Exhibit/SRF_Exhibit.js (modified) (history)
  • /trunk/extensions/SemanticResultFormats/Exhibit/SRF_Exhibit.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticResultFormats/Exhibit/SRF_Exhibit.js
@@ -4,11 +4,14 @@
55 * This javascript bases on the Wibbit startup procedure and was modified for the use in Semantic MediaWiki
66 * Data: We're using the HTML table importer to get the data for the exhibit.
77 */
8 -
 8+
99 window.database = Exhibit.Database.create();
1010 window.exhibit = Exhibit.create(window.database);
11 - for (var id in sources) {
12 - var source = sources[id];
 11+
 12+ if(!remote){
 13+
 14+ for (var id in ex_sources) {
 15+ var source = ex_sources[id];
1316 var dataTable = document.getElementById(source.id);
1417 //if (source.hideTable == 1) { dataTable.setAttribute("style", "display:none"); };
1518 dataTable.setAttribute("ex:type", source.type);
@@ -37,20 +40,20 @@
3841 }
3942 }
4043 Exhibit.HtmlTableImporter.loadTable(dataTable, window.database);
41 - }
 44+ }}
4245
4346 window.database.loadDataLinks(); //load JSON files in addition
4447
4548 var exhibitDiv = document.getElementById('exhibitLocation');
46 - exhibitDiv.innerHTML = "<div id='top-facets'></div><table width='100%' style='clear: both'><tr id='exhibit-content' valign='top'><td id='left-facets' width='0%'></td><td id='view-content'><div id='view'></div></td><td id='right-facets' width='0%'></td></tr></table><div id='bottom-facets'></div><div ex:role='exhibit-collection' ex:itemTypes='Item'/>";
 49+ exhibitDiv.innerHTML = "<div id='top-facets'></div><table width='100%' style='clear: both'><tr id='exhibit-content' valign='top'><td id='left-facets' width='0%'></td><td id='view-content'><div id='view'></div></td><td id='right-facets' width='0%'></td></tr></table><div id='bottom-facets'></div>";//<div ex:role='exhibit-collection' ex:itemTypes='Item'/>";
4750
4851 /*
4952 * Configuration: We're creating HTML strings that specify the configurations,
5053 * formatted in the same form as specifications in the HTML of a regular exhibit.
5154 */
52 - if (facets) {//facets
53 - for (var index in facets) {
54 - var facet = facets[index];
 55+ if (ex_facets) {//facets
 56+ for (var index in ex_facets) {
 57+ var facet = ex_facets[index];
5558 var position = facet.position;
5659 var innerHTML = "<div " + facet.innerHTML + " style='padding: 2px; float: left; width: 15em' ></div>";
5760 if (position == "top") {
@@ -74,10 +77,10 @@
7578 }
7679 }
7780
78 - if (views && (views[0] !== "")) {//views
79 - var viewHTML = '<div id="exhibit-view-panel" ex:role="viewPanel"><div ex:role="lens">'+lens+'</div>';
80 - for (var i = 0; i < views.length; i++) {
81 - viewHTML = viewHTML + '<div ' + views[i] + ' ></div>';
 81+ if (ex_views && (ex_views[0] !== "")) {//views
 82+ var viewHTML = '<div '+formats+' id="exhibit-view-panel" ex:role="viewPanel"><div ex:role="lens">'+ex_lens+'</div>';
 83+ for (var i = 0; i < ex_views.length; i++) {
 84+ viewHTML = viewHTML + '<div ' + ex_views[i] + ' ></div>';
8285 }
8386 viewHTML = viewHTML + '</div>';
8487 document.getElementById("view").innerHTML = viewHTML;
@@ -85,13 +88,19 @@
8689 document.getElementById("view").innerHTML = '<div ex:role="view"></div>';
8790 }
8891
89 - for(var i = 0; i < lenscounter; i++){ //lenses
 92+ for(var i = 0; i < ex_lenscounter; i++){ //lenses
9093 var test = document.getElementById("lenscontent"+i);
91 - test.setAttribute('ex:content','.' + test.innerHTML);
 94+ if(test.innerHTML.indexOf('|')>=0){
 95+ var commands = test.innerHTML.split('|');
 96+ test.setAttribute('ex:formats','date { template:\'' + commands[1] +'\' }');
 97+ test.innerHTML = commands[0];
 98+ }
 99+ test.setAttribute('ex:content','.' + test.innerHTML.replace(' ','_').toLowerCase());
 100+ //test.setAttribute('ex:content','.' + test.innerHTML);
92101 test.setAttribute('class',"inlines");
93102 test.innerHTML = '';
94103 }
95 - for(var i = 0; i < linkcounter; i++){ //lenses
 104+ for(var i = 0; i < ex_linkcounter; i++){ //lenses
96105 var test = document.getElementById("linkcontent"+i);
97106 var newlink = document.createElement('a');
98107 newlink.setAttribute('ex:href-subcontent',wgServer + wgScript + '?title={{.' + test.innerHTML + '}}');
@@ -99,7 +108,15 @@
100109 test.innerHTML = '';
101110 test.appendChild(newlink);
102111 }
103 -
 112+ for(var i = 0; i < ex_imagecounter; i++){ //lenses
 113+ var test = document.getElementById("imagecontent"+i);
 114+ var newimage = document.createElement('img');
 115+ newimage.setAttribute('ex:src-content','.' + test.innerHTML);
 116+ newimage.setAttribute('height','100');
 117+ test.innerHTML = '';
 118+ test.appendChild(newimage);
 119+ }
 120+
104121 window.exhibit.configureFromDOM();
105122 }
106123
Index: trunk/extensions/SemanticResultFormats/Exhibit/SRF_Exhibit.php
@@ -26,7 +26,7 @@
2727
2828 ///function aligns the format of SMW's property names to Exhibit's format
2929 protected function encodePropertyName($property){
30 - return strtolower(str_replace(" ","_",$property));
 30+ return strtolower(str_replace(" ","_",trim($property)));
3131 }
3232
3333 ///implements an algorithm for automatic determination of a suitable intervall for numeric facets
@@ -35,7 +35,7 @@
3636 while($row = $res->getNext()){
3737 $tmp = clone $row[$fieldcounter];
3838 $object = $tmp->getNextObject();
39 - if($object instanceof SMWNumberValue) $valuestack[] = $object->getNumericValue();
 39+ if($object instanceof SMWNumberValue) $valuestack[] = $object->getNumericValue();
4040 }
4141 if(sizeof($valuestack) > 0){
4242 $average = (int)((max($valuestack) - min($valuestack))/2);
@@ -43,7 +43,7 @@
4444 }
4545 else $retval = 0;
4646 return $retval;
47 - }
 47+ }
4848
4949 protected function determineNamespace($res){
5050 $row = $res->getNext();
@@ -58,7 +58,7 @@
5959 }
6060 }
6161 return "";
62 - }
 62+ }
6363 }
6464
6565 protected function getResultText($res, $outputmode) {
@@ -67,6 +67,57 @@
6868
6969 wfLoadExtensionMessages('SemanticMediaWiki');
7070
 71+
 72+ ////////////////////////////////
 73+ /////////REMOTE STUFF///////////
 74+ ////////////////////////////////
 75+
 76+ $remote=false;
 77+
 78+ //in case the remote parameter is set, a link to the JSON export of the remote wiki is included in the header as data source for Exhibit
 79+ //this section creates the link
 80+ if(array_key_exists('remote', $this->m_params) && srfgExhibitRemote==true){
 81+
 82+ $remote=true;
 83+
 84+ //fetch interwiki link
 85+ $list = array();
 86+ $dbr = &wfGetDB(DB_SLAVE);
 87+ $cl = $dbr->tableName('interwiki');
 88+ $dbres = $dbr->select($cl, 'iw_url', "iw_prefix='". $this->m_params['remote']."'", __METHOD__, array());
 89+ $row = $dbr->fetchRow($dbres);
 90+ $extlinkpattern = $row[iw_url];
 91+ $dbr->freeResult($dbres);
 92+
 93+ $newheader = '<link rel="exhibit/data" type="application/jsonp" href="';
 94+ $link = $res->getQueryLink('JSON Link');
 95+ $link->setParameter('json','format');
 96+
 97+ if(array_key_exists('callback', $this->m_params)){ //check if a special name for the callback function is set, if not stick with 'callback'
 98+ $callbackfunc = $this->m_params['callback'];
 99+ } else {
 100+ $callbackfunc = 'callback';
 101+ }
 102+
 103+ if(array_key_exists('limit', $this->m_params)){
 104+ $link->setParameter($this->m_params['limit'],'limit');
 105+ }
 106+
 107+ $link->setParameter($callbackfunc,'callback');
 108+ $link = $link->getText(2,$this->mLinker);
 109+
 110+ list($link, $trash) = explode('|',$link);
 111+ $link = str_replace('[[:','',$link);
 112+
 113+ $newheader .= str_replace('$1',$link, $extlinkpattern);
 114+ $newheader .='" ex:jsonp-callback="'.$callbackfunc.'"';
 115+ $newheader .= '/>';
 116+
 117+ SMWOutputs::requireHeadItem('REMOTE', $newheader);
 118+ }
 119+
 120+
 121+
71122 //the following variables indicate the use of special views
72123 //the variable's values define the way Exhibit is called
73124 $timeline = false;
@@ -83,15 +134,15 @@
84135 }
85136 array_shift($colstack);
86137 array_unshift($colstack, 'label');
87 -
 138+
88139 if(SRFExhibit::$exhibitRunningNumber == 0){
89 - $sourcesrc = "var sources = { source".($smwgIQRunningNumber-1).": { id: 'querytable".$smwgIQRunningNumber."' , columns: '".implode(',',$colstack)."'.split(','), hideTable: '1', type: 'Item', label: 'Item', pluralLabel: 'Items' } };";
 140+ $sourcesrc = "var ex_sources = { source".($smwgIQRunningNumber-1).": { id: 'querytable".$smwgIQRunningNumber."' , columns: '".implode(',',$colstack)."'.split(','), hideTable: '1', type: 'Item', label: 'Item', pluralLabel: 'Items' } };";
90141 }
91142 else{
92143 $sourcesrc = "sources.source".$smwgIQRunningNumber." = { id: 'querytable".$smwgIQRunningNumber."' , columns: '".implode(',',$colstack)."'.split(','), hideTable: '1', type: 'Item', label: 'Item', pluralLabel: 'Items' };";
93144 }
94145 $sourcesrc = "<script type=\"text/javascript\">".$sourcesrc."</script>";
95 -
 146+
96147 //prepare facets
97148 $facetcounter = 0;
98149 if(array_key_exists('facets', $this->m_params)){
@@ -110,10 +161,10 @@
111162 switch($pr->getTypeID()){
112163 case '_num':
113164 $intervall = $this->determineSuitableInterval(clone $res,$facet,$fieldcounter);
114 - $facetstack[] = ' facet'.$facetcounter++.': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" ex:facetClass="NumericRange" ex:interval="'.$intervall.'" '.implode(" ",$facparams).' ex:expression=".'.$this->encodePropertyName($facet).'"\'}';
 165+ $facetstack[] = ' facet'.$facetcounter++.': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" ex:facetClass="NumericRange" ex:interval="'.$intervall.'" '.implode(" ",$facparams).' ex:expression=".'.$this->encodePropertyName($facet).'"\'}';
115166 break;
116167 default:
117 - $facetstack[] = ' facet'.$facetcounter++.': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" '.implode(" ",$facparams).' ex:expression=".'.$this->encodePropertyName($facet).'"\'}';
 168+ $facetstack[] = ' facet'.$facetcounter++.': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" '.implode(" ",$facparams).' ex:expression=".'.$this->encodePropertyName($facet).'" ex:facetLabel="'.$this->encodePropertyName($facet).'"\'}';
118169 }
119170 break;
120171 }
@@ -123,7 +174,7 @@
124175 $facetstring = implode(',',$facetstack);
125176 }
126177 else $facetstring = '';
127 - $facetsrc = "var facets = {".$facetstring." };";
 178+ $facetsrc = "var ex_facets = {".$facetstring." };";
128179
129180
130181 //prepare views
@@ -133,7 +184,7 @@
134185 else $views[] = 'tiles';
135186
136187 foreach( $views as $view ){
137 - switch( $view ){
 188+ switch( trim($view) ){
138189 case 'tabular'://table view (the columns are automatically defined by the selected properties)
139190 $thstack = array();
140191 foreach ($res->getPrintRequests() as $pr){
@@ -197,26 +248,46 @@
198249 }
199250 break;
200251 default:case 'tiles'://tile view
201 - $viewstack[] = 'ex:role=\'view\' ex:showSummary=\'false\'';
 252+ if(array_key_exists('sort', $this->m_params)){
 253+ $sortfields = explode(",",$this->m_params['sort']);
 254+ foreach($sortfields as $field){
 255+ $sortkeys[] = ".".$this->encodePropertyName($field);
 256+ }
 257+ $sortstring = 'ex:orders=\''.implode(",", $sortkeys).'\' ';
 258+ if(array_key_exists('order', $this->m_params)) $sortstring.=' ex:directions=\''.$this->encodePropertyName($this->m_params['order']).'\'';
 259+ if(array_key_exists('grouped', $this->m_params)) $sortstring.=' ex:grouped=\''.$this->encodePropertyName($this->m_params['grouped']).'\'';
 260+ }
 261+ $viewstack[] = 'ex:role=\'view\' ex:showSummary=\'false\' '.$sortstring;
202262 break;
203263 }
204264 }
205265
206 - $viewsrc = 'var views = "'.implode("/", $viewstack).'".split(\'/\');;';
207 -
208 -
 266+ $viewsrc = 'var ex_views = "'.implode("/", $viewstack).'".split(\'/\');;';
209267
 268+
 269+
210270 //prepare automatic lenses
211271
212272 global $wgParser;
213273 $lenscounter = 0;
214274 $linkcounter = 0;
 275+ $imagecounter = 0;
215276
216277 if(array_key_exists('lens', $this->m_params)){//a customized lens is specified via the lens parameter within the query
217278 $lenstitle = Title::newFromText("Template:".$this->m_params['lens']);
218279 $lensarticle = new Article($lenstitle);
219280 $lenswikitext = $lensarticle->getContent();
220281
 282+ if(preg_match_all("/[\[][\[][Ii][m][a][g][e][:][{][{][{][1-9A-z\-[:space:]]*[}][}][}][\]][\]]/u",$lenswikitext,$matches)){
 283+ foreach($matches as $match){
 284+ foreach($match as $value){
 285+ $strippedvalue = trim(substr($value,8),"[[{}]]");
 286+ $lenswikitext = str_replace($value,'<div class="inlines" id="imagecontent'.$imagecounter.'">'.$this->encodePropertyName(strtolower(str_replace("\n","",$strippedvalue))).'</div>',$lenswikitext);
 287+ $imagecounter++;
 288+ }
 289+ }
 290+ }
 291+
221292 if(preg_match_all("/[\[][\[][{][{][{][1-9A-z\-[:space:]]*[}][}][}][\]][\]]/u",$lenswikitext,$matches)){
222293 foreach($matches as $match){
223294 foreach($match as $value){
@@ -226,8 +297,8 @@
227298 }
228299 }
229300 }
230 -
231 - if (preg_match_all("/[{][{][{][1-9A-z\-[:space:]]*[}][}][}]/u",$lenswikitext,$matches)) {
 301+
 302+ if (preg_match_all("/[{][{][{][1-9A-z\:\|\/\=\-[:space:]]*[}][}][}]/u",$lenswikitext,$matches)) {
232303 foreach($matches as $match){
233304 foreach($match as $value){
234305 $strippedvalue = trim($value,"{}");
@@ -236,44 +307,76 @@
237308 }
238309 }
239310 }
240 -
 311+
241312 $lenshtml = $wgParser->internalParse($lenswikitext);//$wgParser->parse($lenswikitext, $lenstitle, new ParserOptions(), true, true)->getText();
242313
243 - $lenssrc = "var lens = '".str_replace("\n","",$lenshtml)."';lenscounter =".$lenscounter.";linkcounter=".$linkcounter.";";
 314+ $lenssrc = "var ex_lens = '".str_replace("\n","",$lenshtml)."';ex_lenscounter =".$lenscounter.";ex_linkcounter=".$linkcounter.";ex_imagecounter=".$imagecounter.";";
244315 } else {//generic lens (creates links to further content (property-pages, pages about values)
245316 foreach ($res->getPrintRequests() as $pr){
 317+ if($remote){
 318+ $wikiurl=str_replace("$1","",$extlinkpattern);
 319+ } else {
 320+ $wikiurl=$wgScriptPath."/index.php?title=";
 321+ }
246322 if($pr->getTypeID() == '_wpg') {
247323 $prefix='';
248324 if($pr->getLabel()=='Category') $prefix = "Category:";
249 - $lensstack[] = '<tr ex:if-exists=".'.$this->encodePropertyName($pr->getLabel()).'"><td width="20%">'.$pr->getText(0, $this->mLinker).'</td><td width="80%" ex:content=".'.$this->encodePropertyName($pr->getLabel()).'"><a ex:href-subcontent="'.$wgScriptPath.'/index.php?title='.$prefix.'{{value}}"><div ex:content="value" class="name"></div></a></td></tr>';
 325+ $lensstack[] = '<tr ex:if-exists=".'.$this->encodePropertyName($pr->getLabel()).'"><td width="20%">'.$pr->getText(0, $this->mLinker).'</td><td width="80%" ex:content=".'.$this->encodePropertyName($pr->getLabel()).'"><a ex:href-subcontent="'.$wikiurl.$prefix.'{{value}}"><div ex:content="value" class="name"></div></a></td></tr>';
250326 }
251327 else{
252328 $lensstack[] = '<tr ex:if-exists=".'.$this->encodePropertyName($pr->getLabel()).'"><td width="20%">'.$pr->getText(0, $this->mLinker).'</td><td width="80%"><div ex:content=".'.$this->encodePropertyName($pr->getLabel()).'" class="name"></div></td></tr>';
253329 }
254330 }
255331 array_shift($lensstack);
256 - $lenssrc = 'var lens = \'<table width=100% cellpadding=3><tr><th class="head" align=left bgcolor="#DDDDDD"><a ex:href-subcontent="'.$wgScriptPath.'/index.php?title='.$this->determineNamespace(clone $res).'{{.label}}" class="linkhead"><div ex:content=".label" class="name"></div></a></th></tr></table><table width="100%" cellpadding=3>'.implode("", $lensstack).'</table>\'; lenscounter = 0; linkcounter=0;';
 332+ $lenssrc = 'var ex_lens = \'<table width=100% cellpadding=3><tr><th class="head" align=left bgcolor="#DDDDDD"><a ex:href-subcontent="'.$wikiurl.$this->determineNamespace(clone $res).'{{.label}}" class="linkhead"><div ex:content=".label" class="name"></div></a></th></tr></table><table width="100%" cellpadding=3>'.implode("", $lensstack).'</table>\'; ex_lenscounter = 0; ex_linkcounter=0; ex_imagecounter=0;';
257333 }
258334
259 -
 335+ if($remote){
 336+ $varremote = 'true';
 337+ } else {
 338+ $varremote = 'false';
 339+ }
 340+
 341+ //Handling special formats like date
 342+ $formatssrc = 'var formats =\'\'';
 343+ if(array_key_exists('date', $this->m_params)) $formatssrc = 'var formats = \'ex:formats="date { mode:'.$this->m_params['date'].'; show:date }"\';';
 344+
 345+ //create a URL pointing to the corresponding JSON feed
 346+
 347+ $JSONlink = $res->getQueryLink($label);
 348+ if ($this->getSearchLabel(SMW_OUTPUT_WIKI) != '') { // used as a file name
 349+ $link->setParameter($this->getSearchLabel(SMW_OUTPUT_WIKI),'searchlabel');
 350+ }
 351+ if(array_key_exists('limit', $this->m_params)) {
 352+ $JSONlink->setParameter(htmlspecialchars($this->m_params['limit']),'limit');
 353+ }
 354+ $JSONlink->setParameter('json','format');
 355+ $stringtoedit = explode("|", $JSONlink->getText($outputmode,$this->mLinker));
 356+ $stringtoedit = substr($stringtoedit[0],3);
 357+ $JSONlinksrc = "var JSONlink = '".$stringtoedit."';";
 358+
260359 //create script header with variables containing the Exhibit markup
261 - $headervars = "<script type='text/javascript'>\n\t\t\t".$facetsrc."\n\t\t\t".$viewsrc."\n\t\t\t".$lenssrc."\n\t\t\t".$stylesrc."\n</script>";
 360+ $headervars = "<script type='text/javascript'>\n\t\t\t".$facetsrc."\n\t\t\t".$viewsrc."\n\t\t\t".$lenssrc."\n\t\t\t".$stylesrc."\n\t\t\t".$formatssrc."\n\t\t\t".$JSONlinksrc."\n\t\t\t var remote=".$varremote.";</script>";
262361
263362
264363 //To run Exhibit some links to the scripts of the API need to be included in the header
265 - $ExhibitScriptSrc1 = '<script type="text/javascript" src="'.$srfgScriptPath.'/Exhibit/includes/src/webapp/api/exhibit-api.js?autoCreate=false&safe=true'; //former: auto create = remote
 364+
 365+ $ExhibitScriptSrc1 = '<script type="text/javascript" src="'.$srfgScriptPath.'/Exhibit/includes/src/webapp/api/exhibit-api.js?autoCreate=false&safe=true&bundle=false'; //former: auto create = remote
266366 if($timeline) $ExhibitScriptSrc1 .= '&views=timeline';
267367 if($map) $ExhibitScriptSrc1 .= '&gmapkey='.$wgGoogleMapsKey;
268368 $ExhibitScriptSrc1 .= '"></script>';
269369 $ExhibitScriptSrc2 = '<script type="text/javascript" src="'.$srfgScriptPath.'/Exhibit/SRF_Exhibit.js"></script>';
270370 $CSSSrc = '<link rel="stylesheet" type="text/css" href="'.$srfgScriptPath.'/Exhibit/SRF_Exhibit.css"></link>';
271 -
 371+
272372 SMWOutputs::requireHeadItem('CSS', $CSSSrc); //include CSS
273373 SMWOutputs::requireHeadItem('EXHIBIT1', $ExhibitScriptSrc1); //include Exhibit API
274374 SMWOutputs::requireHeadItem('EXHIBIT2', $ExhibitScriptSrc2); //includes javascript overwriting the Exhibit start-up functions
275375 SMWOutputs::requireHeadItem('SOURCES'.$smwgIQRunningNumber, $sourcesrc);//include sources variable
276376 SMWOutputs::requireHeadItem('VIEWSFACETS', $headervars);//include views and facets variable
277 -
 377+
 378+
 379+ if(!$remote){
 380+
278381 //print input table
279382 // print header
280383 if ('broadtable' == $this->mFormat) $widthpara = ' width="100%"';
@@ -282,7 +385,9 @@
283386 if ($this->mShowHeaders) { // building headers
284387 $result .= "\t<tr>\n";
285388 foreach ($res->getPrintRequests() as $pr) {
286 - $result .= "\t\t<th>" .$pr->getText($outputmode,$this->getLinker(0)). "</th>\n";
 389+ if($pr->getText($outputmode,$this->getLinker(0)) == '') $headerlabel = "Item Name";
 390+ else $headerlabel = $pr->getText($outputmode,$this->getLinker(0));
 391+ $result .= "\t\t<th>" .$headerlabel. "</th>\n";
287392 }
288393 $result .= "\t</tr>\n";
289394 }
@@ -329,9 +434,9 @@
330435 else $result .= "</td>\n";
331436 }
332437 $result .= "\t</tr>\n";
333 - }
334 - $result .= "</table>\n";
335 -
 438+ }
 439+ $result .= "</table>\n";}
 440+
336441 if (SRFExhibit::$exhibitRunningNumber == 0) $result .= "<div id=\"exhibitLocation\"></div>"; // print placeholder (just print it one time)
337442 $this->isHTML = ($outputmode == SMW_OUTPUT_HTML); // yes, our code can be viewed as HTML if requested, no more parsing needed
338443 SRFExhibit::$exhibitRunningNumber++;

Status & tagging log