Index: trunk/extensions/SemanticMediaWiki/includes/SMW_Hooks.php |
— | — | @@ -14,8 +14,6 @@ |
15 | 15 | */ |
16 | 16 | function smwfParserHook(&$parser, &$text) { |
17 | 17 | global $smwgStoreAnnotations, $smwgTempStoreAnnotations, $smwgStoreActive; |
18 | | - // Init global storage for semantic data of this article. |
19 | | - SMWFactbox::initStorage($parser->getTitle()); |
20 | 18 | |
21 | 19 | // store the results if enabled (we have to parse them in any case, in order to |
22 | 20 | // clean the wiki source for further processing) |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_Factbox.php |
— | — | @@ -19,29 +19,40 @@ |
20 | 20 | * The actual container for the semantic annotations. Public, since |
21 | 21 | * it is ref-passed to others for further processing. |
22 | 22 | */ |
23 | | - static $semdata; |
| 23 | + static $semdata = NULL; |
24 | 24 | /** |
25 | 25 | * True if the respective article is newly created. This affects some |
26 | 26 | * storage operations. |
27 | 27 | */ |
28 | 28 | static protected $m_new = false; |
| 29 | + /** |
| 30 | + * True if Factbox was printed, our best attempt at reliably preventing multiple |
| 31 | + * Factboxes to appear on one page. |
| 32 | + */ |
| 33 | + static protected $m_printed = false; |
29 | 34 | |
30 | 35 | /** |
31 | 36 | * Initialisation method. Must be called before anything else happens. |
32 | 37 | */ |
33 | 38 | static function initStorage($title) { |
34 | | - SMWFactbox::$semdata = new SMWSemanticData($title); // reset data |
35 | | - ///TODO: is this (global) reset safe when cloned subparses happen? May kill unsafed data. |
| 39 | + // reset only if title is new |
| 40 | + if ( (SMWFactbox::$semdata === NULL) || |
| 41 | + (SMWFactbox::$semdata->getSubject()->getText() != $title->getText()) || |
| 42 | + (SMWFactbox::$semdata->getSubject()->getNamespace() != $title->getNamespace()) ) { |
| 43 | + SMWFactbox::$semdata = new SMWSemanticData($title); // reset data |
| 44 | + SMWFactbox::$m_printed = false; |
| 45 | + } |
36 | 46 | //SMWFactbox::$m_new = false; // do not reset, keep (order of hooks can be strange ...) |
37 | 47 | } |
38 | 48 | |
39 | 49 | /** |
40 | | - * Clear all stored data |
| 50 | + * Clear all stored data. |
41 | 51 | */ |
42 | 52 | static function clearStorage() { |
43 | 53 | global $smwgStoreActive; |
44 | 54 | if ($smwgStoreActive) { |
45 | 55 | SMWFactbox::$semdata->clear(); |
| 56 | + SMWFactbox::$m_printed = false; |
46 | 57 | } |
47 | 58 | } |
48 | 59 | |
— | — | @@ -200,7 +211,9 @@ |
201 | 212 | static function printFactbox(&$text) { |
202 | 213 | global $wgContLang, $wgServer, $smwgShowFactbox, $smwgShowFactboxEdit, $smwgStoreActive, $smwgIP, $wgRequest; |
203 | 214 | if (!$smwgStoreActive) return; |
| 215 | + if (SMWFactbox::$m_printed) return; |
204 | 216 | wfProfileIn("SMWFactbox::printFactbox (SMW)"); |
| 217 | + SMWFactbox::$m_printed = true; |
205 | 218 | |
206 | 219 | // Global settings: |
207 | 220 | if ( $wgRequest->getCheck('wpPreview') ) { |
— | — | @@ -223,13 +236,13 @@ |
224 | 237 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
225 | 238 | return; |
226 | 239 | case SMW_FACTBOX_SPECIAL: // only when there are special properties |
227 | | - if ( !SMWFactbox::$semdata->hasSpecialProperties() ) { |
| 240 | + if ( !SMWFactbox::$semdata->hasVisibleSpecialProperties() ) { |
228 | 241 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
229 | 242 | return; |
230 | 243 | } |
231 | 244 | break; |
232 | 245 | case SMW_FACTBOX_NONEMPTY: // only when non-empty |
233 | | - if ( (!SMWFactbox::$semdata->hasProperties()) && (!SMWFactbox::$semdata->hasSpecialProperties()) ) { |
| 246 | + if ( (!SMWFactbox::$semdata->hasProperties()) && (!SMWFactbox::$semdata->hasVisibleSpecialProperties()) ) { |
234 | 247 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
235 | 248 | return; |
236 | 249 | } |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_SemanticData.php |
— | — | @@ -18,6 +18,7 @@ |
19 | 19 | protected $attribtitles = array(); // text keys and title objects |
20 | 20 | protected $hasprops = false; // any normal properties yet? |
21 | 21 | protected $hasspecs = false; // any special properties yet? |
| 22 | + protected $hasvisiblespecs = false; // any displayable special properties yet? (some are internal only withot a display name) |
22 | 23 | protected $m_noduplicates; // avoid repeated values? |
23 | 24 | /// NOTE: not needing (e.g. when loading from store) can safe much time, |
24 | 25 | /// since objects can remain stubs until someone really acesses their value |
— | — | @@ -74,6 +75,14 @@ |
75 | 76 | } |
76 | 77 | |
77 | 78 | /** |
| 79 | + * Return true if there are any special properties that can |
| 80 | + * be displayed. |
| 81 | + */ |
| 82 | + public function hasVisibleSpecialProperties() { |
| 83 | + return $this->hasvisiblespecs; |
| 84 | + } |
| 85 | + |
| 86 | + /** |
78 | 87 | * Store a value for an property identified by its title object. Duplicate |
79 | 88 | * value entries are ignored. |
80 | 89 | */ |
— | — | @@ -119,6 +128,8 @@ |
120 | 129 | $property = $smwgContLang->findSpecialPropertyLabel($special); |
121 | 130 | if ($property === false) { |
122 | 131 | $property = '_' . $special; |
| 132 | + } else { |
| 133 | + $this->hasvisiblespecs = true; |
123 | 134 | } |
124 | 135 | if (!array_key_exists($property, $this->attribvals)) { |
125 | 136 | $this->attribvals[$property] = array(); |
— | — | @@ -147,6 +158,7 @@ |
148 | 159 | $this->attribtitles = array(); |
149 | 160 | $this->hasprops = false; |
150 | 161 | $this->hasspecs = false; |
| 162 | + $this->hasvisiblespecs = false; |
151 | 163 | } |
152 | 164 | |
153 | 165 | } |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_GlobalFunctions.php |
— | — | @@ -246,11 +246,16 @@ |
247 | 247 | * in general, which explains the two-level registration. |
248 | 248 | */ |
249 | 249 | function smwfRegisterInlineQueries( &$parser, &$text, &$stripstate ) { |
250 | | - $parser->setHook( 'ask', 'smwfProcessInlineQuery' ); |
251 | | - $parser->setFunctionHook( 'ask', 'smwfProcessInlineQueryParserFunction' ); |
252 | | - $parser->setFunctionHook( 'show', 'smwfProcessShowParserFunction' ); |
253 | | - $parser->setFunctionHook( 'info', 'smwfProcessInfoParserFunction' ); |
254 | | - $parser->setFunctionHook( 'concept', 'smwfProcessConceptParserFunction' ); |
| 250 | + SMWFactbox::initStorage($parser->getTitle()); |
| 251 | + |
| 252 | + $oldhook = $parser->setFunctionHook( 'ask', 'smwfProcessInlineQueryParserFunction' ); |
| 253 | + if ($oldhook != 'smwfProcessInlineQueryParserFunction') { |
| 254 | + $parser->setHook( 'ask', 'smwfProcessInlineQuery' ); |
| 255 | + $parser->setFunctionHook( 'ask', 'smwfProcessInlineQueryParserFunction' ); |
| 256 | + $parser->setFunctionHook( 'show', 'smwfProcessShowParserFunction' ); |
| 257 | + $parser->setFunctionHook( 'info', 'smwfProcessInfoParserFunction' ); |
| 258 | + $parser->setFunctionHook( 'concept', 'smwfProcessConceptParserFunction' ); |
| 259 | + } |
255 | 260 | return true; // always return true, in order not to stop MW's hook processing! |
256 | 261 | } |
257 | 262 | |
— | — | @@ -301,7 +306,7 @@ |
302 | 307 | * The {{#concept }} parser function processing part. |
303 | 308 | */ |
304 | 309 | function smwfProcessConceptParserFunction(&$parser) { |
305 | | - global $smwgQDefaultNamespaces, $smwgQMaxSize, $smwgQMaxDepth, $smwgPreviousConcept, $smwgConceptText; |
| 310 | + global $smwgQDefaultNamespaces, $smwgQMaxSize, $smwgQMaxDepth, $smwgPreviousConcept; |
306 | 311 | // The global $smwgConceptText is used to pass information to the MW hooks for storing it, |
307 | 312 | // $smwgPreviousConcept is used to detect if we already have a concept defined for this page. |
308 | 313 | $title = $parser->getTitle(); |
— | — | @@ -311,21 +316,25 @@ |
312 | 317 | return smwfEncodeMessages(array(wfMsgForContent('smw_multiple_concepts'))); |
313 | 318 | } |
314 | 319 | $smwgPreviousConcept = $title->getText(); |
| 320 | + |
| 321 | + // process input: |
315 | 322 | $params = func_get_args(); |
316 | 323 | array_shift( $params ); // we already know the $parser ... |
317 | 324 | $concept_input = array_shift( $params ); // use only first parameter, ignore rest (may get meaning later) |
318 | 325 | $query = SMWQueryProcessor::createQuery($concept_input, array('limit' => -1), SMWQueryProcessor::CONCEPT_DESC); |
319 | | - $smwgConceptText = $query->getDescription()->getQueryString(); |
| 326 | + $conceptText = $query->getDescription()->getQueryString(); |
| 327 | + $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_CONCEPT_DESC, $conceptText); |
| 328 | + SMWFactbox::$semdata->addSpecialValue(SMW_SP_CONCEPT_DESC,$dv); |
320 | 329 | |
| 330 | + // display concept box: |
321 | 331 | $qresult = smwfGetStore()->getQueryResult($query); |
322 | 332 | $printer = new SMWListResultPrinter('list',true); |
323 | 333 | $resultlink = $printer->getResult($qresult, array('searchlabel' => wfMsgForContent('smw_concept_preview')), SMW_OUTPUT_WIKI); |
324 | | - |
325 | 334 | smwfRequireHeadItem(SMW_HEADER_STYLE); |
326 | 335 | $result = '<div class="smwfact"><span class="smwfactboxhead">' . wfMsgForContent('smw_concept_description',$title->getText()) . |
327 | 336 | //(count($query->getErrors())>0?' ' . smwfEncodeMessages($query->getErrors()):'') . // errors are shown by $resultlink anyway |
328 | 337 | '</span> ' . $resultlink . '<br/>' . |
329 | | - '<pre>' . str_replace('[', '[', $smwgConceptText) . '</pre></div>'; |
| 338 | + '<pre>' . str_replace('[', '[', $conceptText) . '</pre></div>'; |
330 | 339 | return $result; |
331 | 340 | } |
332 | 341 | |
— | — | @@ -387,10 +396,9 @@ |
388 | 397 | * output. This is our preferred method of working off the required scripts, since it |
389 | 398 | * exploits parser caching. |
390 | 399 | * (2) Fetch category information from parser output. |
391 | | - * (3) Store concept descriptions for concept pages. |
392 | 400 | */ |
393 | 401 | function smwfParserAfterTidy(&$parser, &$text) { |
394 | | - global $smwgHeadItems, $smwgStoreActive, $smwgConceptText; |
| 402 | + global $smwgHeadItems, $smwgStoreActive; |
395 | 403 | // make HTML header |
396 | 404 | if (!$smwgStoreActive) return true; // avoid doing this in SMW-generated sub-parsers |
397 | 405 | foreach ($smwgHeadItems as $key => $item) { |
— | — | @@ -407,12 +415,6 @@ |
408 | 416 | SMWFactbox::$semdata->addSpecialValue(SMW_SP_SUBCLASS_OF,$dv); |
409 | 417 | } |
410 | 418 | } |
411 | | - // store concept descriptions |
412 | | - if (isset($smwgConceptText) && ($smwgConceptText != '') ) { // no check for Concept namespace here, was done earlier |
413 | | - $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_CONCEPT_DESC, $smwgConceptText); |
414 | | - SMWFactbox::$semdata->addSpecialValue(SMW_SP_CONCEPT_DESC,$dv); |
415 | | - $smwgConceptText = ''; |
416 | | - } |
417 | 419 | return true; |
418 | 420 | } |
419 | 421 | |