summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchris <chris@jalakai.co.uk>2006-11-26 16:21:44 +0100
committerchris <chris@jalakai.co.uk>2006-11-26 16:21:44 +0100
commit0a7e3bce2e0ca81b6f8c4e52f78b1ffe443f7ade (patch)
treeae4bc7e54007a1e94221b038b87ea35fea4e8b2f
parent7f2f59eaec2b62a61925a8ce2b4390b192827d8d (diff)
downloadrpg-0a7e3bce2e0ca81b6f8c4e52f78b1ffe443f7ade.tar.gz
rpg-0a7e3bce2e0ca81b6f8c4e52f78b1ffe443f7ade.tar.bz2
metadata update to support both persistent and non-persistent metadata
Key changes: - metadata stored on disk in two arrays, 'current' & 'persistent' - p_set_metadata has an additional parameter, $persistent, which defaults to true - metadata set within the renderer defaults to non-persistent - new event hook, PARSER_METADATA_RENDER, which wraps around metadata rendering process. For full details of this event refer to the event list documentation at splitbrain. The patch includes automatic conversion of metadata in current form to the new format For more details also see http://www.freelists.org/archives/dokuwiki/11-2006/msg00221.html and any follow-up messages. darcs-hash:20061126152144-9b6ab-a4e40c221e0274b13da07dc2fc1d2100f5f3a50e.gz
-rw-r--r--inc/init.php1
-rw-r--r--inc/parser/metadata.php11
-rw-r--r--inc/parserutils.php160
-rw-r--r--lib/plugins/syntax.php2
4 files changed, 123 insertions, 51 deletions
diff --git a/inc/init.php b/inc/init.php
index c097cd5bd..bde17e798 100644
--- a/inc/init.php
+++ b/inc/init.php
@@ -28,6 +28,7 @@
global $cache_wikifn; $cache_wikifn = array();
global $cache_cleanid; $cache_cleanid = array();
global $cache_authname; $cache_authname = array();
+ global $cache_metadata; $cache_metadata = array();
//prepare config array()
global $conf;
diff --git a/inc/parser/metadata.php b/inc/parser/metadata.php
index be5897231..37122bdb1 100644
--- a/inc/parser/metadata.php
+++ b/inc/parser/metadata.php
@@ -26,20 +26,15 @@ class Doku_Renderer_metadata extends Doku_Renderer {
var $doc = '';
var $meta = array();
+ var $persistent = array();
var $headers = array();
var $capture = true;
var $store = '';
function document_start(){
- //reset some variables
- $this->meta['title'] = '';
- $this->meta['description']['abstract'] = '';
- $this->meta['description']['tableofcontents'] = array();
- $this->meta['relation']['haspart'] = array();
- $this->meta['relation']['references'] = array();
- $this->meta['date']['valid'] = array();
- $this->headers = array();
+ // reset metadata to persistent values
+ $this->meta = $this->persistent;
}
function document_end(){
diff --git a/inc/parserutils.php b/inc/parserutils.php
index 061704cb3..f219696d5 100644
--- a/inc/parserutils.php
+++ b/inc/parserutils.php
@@ -222,31 +222,33 @@ function p_get_instructions($text){
* @author Esther Brunner <esther@kaffeehaus.ch>
*/
function p_get_metadata($id, $key=false, $render=false){
- global $INFO;
-
- if ($id == $INFO['id'] && !empty($INFO['meta'])) {
- $meta = $INFO['meta'];
- } else {
- $file = metaFN($id, '.meta');
-
- if (@file_exists($file)) $meta = unserialize(io_readFile($file, false));
- else $meta = array();
-
- // metadata has never been rendered before - do it!
- if ($render && !$meta['description']['abstract']){
- $meta = p_render_metadata($id, $meta);
- io_saveFile($file, serialize($meta));
- }
+ global $ID, $INFO, $cache_metadata;
+
+ // cache the current page
+ // Benchmarking shows the current page's metadata is generally the only page metadata
+ // accessed several times. This may catch a few other pages, but that shouldn't be an issue.
+ $cache = ($ID == $id);
+ $meta = p_read_metadata($id, $cache);
+
+ // metadata has never been rendered before - do it!
+ if ($render && !$meta['description']['abstract']){
+ $meta = p_render_metadata($id, $meta);
+ io_saveFile($file, serialize($meta));
+
+ // sync cached copies, including $INFO metadata
+ if (!empty($cache_metadata[$id])) $cache_metadata[$id] = $meta;
+ if (!empty($INFO) && ($id == $INFO['id'])) { $INFO['meta'] = $meta['current']; }
}
// filter by $key
if ($key){
list($key, $subkey) = explode(' ', $key, 2);
- if (trim($subkey)) return $meta[$key][$subkey];
- else return $meta[$key];
+ if (trim($subkey)) return $meta['current'][$key][$subkey];
+
+ return $meta['current'][$key];
}
- return $meta;
+ return $meta['current'];
}
/**
@@ -254,14 +256,17 @@ function p_get_metadata($id, $key=false, $render=false){
*
* @author Esther Brunner <esther@kaffeehaus.ch>
*/
-function p_set_metadata($id, $data, $render=false){
+function p_set_metadata($id, $data, $render=false, $persistent=true){
if (!is_array($data)) return false;
- $orig = p_get_metadata($id);
+ global $ID;
+
+ // cache the current page
+ $cache = ($ID == $id);
+ $orig = p_read_metadata($id, $cache);
// render metadata first?
- if ($render) $meta = p_render_metadata($id, $orig);
- else $meta = $orig;
+ $meta = $render ? p_render_metadata($id, $orig) : $orig;
// now add the passed metadata
$protected = array('description', 'date', 'contributor');
@@ -269,58 +274,129 @@ function p_set_metadata($id, $data, $render=false){
// be careful with sub-arrays of $meta['relation']
if ($key == 'relation'){
+
foreach ($value as $subkey => $subvalue){
- $meta[$key][$subkey] = array_merge($meta[$key][$subkey], $subvalue);
+ $meta['current'][$key][$subkey] = array_merge($meta['current'][$key][$subkey], $subvalue);
+ if ($persistent)
+ $meta['persistent'][$key][$subkey] = array_merge($meta['persistent'][$key][$subkey], $subvalue);
}
// be careful with some senisitive arrays of $meta
} elseif (in_array($key, $protected)){
+
if (is_array($value)){
#FIXME not sure if this is the intended thing:
- if(!is_array($meta[$key])) $meta[$key] = array($meta[$key]);
- $meta[$key] = array_merge($meta[$key], $value);
+ if(!is_array($meta['current'][$key])) $meta['current'][$key] = array($meta['current'][$key]);
+ $meta['current'][$key] = array_merge($meta['current'][$key], $value);
+
+ if ($persistent) {
+ if(!is_array($meta['persistent'][$key])) $meta['persistent'][$key] = array($meta['persistent'][$key]);
+ $meta['persistent'][$key] = array_merge($meta['persistent'][$key], $value);
+ }
}
// no special treatment for the rest
} else {
- $meta[$key] = $value;
+ $meta['current'][$key] = $value;
+ if ($persistent) $meta['persistent'][$key] = $value;
}
}
// save only if metadata changed
if ($meta == $orig) return true;
- // check if current page metadata has been altered - if so sync the changes
- global $INFO;
- if ($id == $INFO['id'] && isset($INFO['meta'])) {
- $INFO['meta'] = $meta;
- }
+ // sync cached copies, including $INFO metadata
+ global $cache_metadata, $INFO;
+
+ if (!empty($cache_metadata[$id])) $cache_metadata[$id] = $meta;
+ if (!empty($INFO) && ($id == $INFO['id'])) { $INFO['meta'] = $meta['current']; }
return io_saveFile(metaFN($id, '.meta'), serialize($meta));
}
/**
+ * read the metadata from source/cache for $id
+ * (internal use only - called by p_get_metadata & p_set_metadata)
+ *
+ * this function also converts the metadata from the original format to
+ * the current format ('current' & 'persistent' arrays)
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ *
+ * @param string $id absolute wiki page id
+ * @param bool $cache whether or not to cache metadata in memory
+ * (only use for metadata likely to be accessed several times)
+ *
+ * @return array metadata
+ */
+function p_read_metadata($id,$cache=false) {
+ global $cache_metadata;
+
+ if (isset($cache_metadata[$id])) return $cache_metadata[$id];
+
+ $file = metaFN($id, '.meta');
+ $meta = @file_exists($file) ? unserialize(io_readFile($file, false)) : array('current'=>array(),'persistent'=>array());
+
+ // convert $meta from old format to new (current+persistent) format
+ if (!isset($meta['current'])) {
+ $meta = array('current'=>$meta,'persistent'=>$meta);
+
+ // remove non-persistent keys
+ unset($meta['persistent']['title']);
+ unset($meta['persistent']['description']['abstract']);
+ unset($meta['persistent']['description']['tableofcontents']);
+ unset($meta['persistent']['relation']['haspart']);
+ unset($meta['persistent']['relation']['references']);
+ unset($meta['persistent']['date']['valid']);
+
+ if (empty($meta['persistent']['description'])) unset($meta['persistent']['description']);
+ if (empty($meta['persistent']['relation'])) unset($meta['persistent']['relation']);
+ if (empty($meta['persistent']['date'])) unset($meta['persistent']['date']);
+
+ // save converted metadata
+ io_saveFile($file, serialize($meta));
+ }
+
+ if ($cache) {
+ $cache_metadata[$id] = $meta;
+ }
+
+ return $meta;
+}
+
+/**
* renders the metadata of a page
*
* @author Esther Brunner <esther@kaffeehaus.ch>
*/
function p_render_metadata($id, $orig){
- require_once DOKU_INC."inc/parser/metadata.php";
- // get instructions
- $instructions = p_cached_instructions(wikiFN($id),false,$id);
+ // add an extra key for the event - to tell event handlers the page whose metadata this is
+ $orig['page'] = $id;
+ $evt = new Doku_Event('PARSER_METADATA_RENDER', $orig);
+ if ($evt->advise_before()) {
- // set up the renderer
- $renderer = & new Doku_Renderer_metadata();
- $renderer->meta = $orig;
+ require_once DOKU_INC."inc/parser/metadata.php";
+
+ // get instructions
+ $instructions = p_cached_instructions(wikiFN($id),false,$id);
+
+ // set up the renderer
+ $renderer = & new Doku_Renderer_metadata();
+ $renderer->meta = $orig['current'];
+ $renderer->persistent = $orig['persistent'];
+
+ // loop through the instructions
+ foreach ($instructions as $instruction){
+ // execute the callback against the renderer
+ call_user_func_array(array(&$renderer, $instruction[0]), $instruction[1]);
+ }
- // loop through the instructions
- foreach ($instructions as $instruction){
- // execute the callback against the renderer
- call_user_func_array(array(&$renderer, $instruction[0]), $instruction[1]);
+ $evt->result = array('current'=>$renderer->meta,'persistent'=>$renderer->persistent);
}
+ $evt->advise_after();
- return $renderer->meta;
+ return $evt->result;
}
/**
diff --git a/lib/plugins/syntax.php b/lib/plugins/syntax.php
index ccf657720..770356c3a 100644
--- a/lib/plugins/syntax.php
+++ b/lib/plugins/syntax.php
@@ -111,7 +111,7 @@ class DokuWiki_Syntax_Plugin extends Doku_Parser_Mode {
* The contents of the $data array depends on what the handler() function above
* created
*
- * @param $format string output format to being Rendered
+ * @param $format string output format being rendered
* @param $renderer ref reference to the current renderer object
* @param $data array data created by handler()
* @return boolean rendered correctly?