Skip to content

Commit

Permalink
Add (r)sort and order flags for namespace includes dokufreaks#96 doku…
Browse files Browse the repository at this point in the history
…freaks#61

This adds the following ordering criterias:
- page ID (current behavior, default)
- title
- date created
- date modified
- indexmenu sort tag metadata
- include plugin sort tag metadata (new syntax: {{include_n>[number]}})

When the rsort flag is set, the ordering will be reversed. Both flags
are available as configuration option, too.
  • Loading branch information
michitux committed Nov 28, 2012
1 parent 20d126d commit df062bd
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 5 deletions.
2 changes: 2 additions & 0 deletions conf/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@
$conf['pageexists'] = 0; // no link if page does not exist
$conf['parlink'] = 1; // paragraph around link
$conf['safeindex'] = 1; // prevent indexing of protected metadata
$conf['order'] = 'id'; // order in which the pages are included in the case of multiple pages
$conf['rsort'] = 0; // reverse sort order
$conf['depth'] = 1; // maximum depth of namespace includes, 0 for unlimited depth
//Setup VIM: ex: et ts=2 :
2 changes: 2 additions & 0 deletions conf/metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@
$meta['pageexists'] = array('onoff');
$meta['parlink'] = array('onoff');
$meta['safeindex'] = array('onoff');
$meta['order'] = array('multichoice', '_choices' => array('id', 'title', 'created', 'modified', 'indexmenu', 'custom'));
$meta['rsort'] = array('onoff');
$meta['depth'] = array('numeric', '_min' => 0);
//Setup VIM: ex: et ts=2 :
64 changes: 61 additions & 3 deletions helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ function helper_plugin_include() {
$this->defaults['pageexists'] = $this->getConf('pageexists');
$this->defaults['parlink'] = $this->getConf('parlink');
$this->defaults['inline'] = false;
$this->defaults['order'] = $this->getConf('order');
$this->defaults['rsort'] = $this->getConf('rsort');
$this->defaults['depth'] = $this->getConf('depth');
}

Expand Down Expand Up @@ -173,6 +175,15 @@ function get_flags($setflags) {
case 'noparlink':
$flags['parlink'] = 0;
break;
case 'order':
$flags['order'] = $value;
break;
case 'sort':
$flags['rsort'] = 0;
break;
case 'rsort':
$flags['rsort'] = 1;
break;
case 'depth':
$flags['depth'] = $value;
break;
Expand Down Expand Up @@ -328,6 +339,8 @@ function _convert_instructions(&$ins, $lvl, $page, $sect, $flags, $root_id) {
case 'linkback': // skip linkbacks
case 'data_entry': // skip data plugin
case 'meta': // skip meta plugin
case 'indexmenu_tag': // skip indexmenu sort tag
case 'include_sorttag': // skip include plugin sort tag
unset($ins[$i]);
break;
// adapt indentation level of nested includes
Expand Down Expand Up @@ -576,8 +589,11 @@ function _get_included_pages($mode, $page, $sect, $parent_id, $flags) {
$pages = array();
switch($mode) {
case 'namespace':
$ns = str_replace(':', '/', cleanID($page));
search($pagearrays, $conf['datadir'], 'search_allpages', array('depth' => $flags['depth']), $ns);
$page = cleanID($page);
$ns = utf8_encodeFN(str_replace(':', '/', $page));
// depth is absolute depth, not relative depth, but 0 has a special meaning.
$depth = $flags['depth'] ? $flags['depth'] + substr_count($page, ':') + ($page ? 1 : 0) : 0;
search($pagearrays, $conf['datadir'], 'search_allpages', array('depth' => $depth), $ns);
if (is_array($pagearrays)) {
foreach ($pagearrays as $pagearray) {
if (!isHiddenPage($pagearray['id'])) // skip hidden pages
Expand Down Expand Up @@ -606,7 +622,49 @@ function _get_included_pages($mode, $page, $sect, $parent_id, $flags) {
$pages[] = $page;
}

sort($pages);
if (count($pages) > 1) {
if ($flags['order'] === 'id') {
if ($flags['rsort']) {
rsort($pages);
} else {
sort($pages);
}
} else {
$ordered_pages = array();
foreach ($pages as $page) {
$key = '';
switch ($flags['order']) {
case 'title':
$key = p_get_first_heading($page);
break;
case 'created':
$key = p_get_metadata($page, 'date created', METADATA_DONT_RENDER);
break;
case 'modified':
$key = p_get_metadata($page, 'date modified', METADATA_DONT_RENDER);
break;
case 'indexmenu':
$key = p_get_metadata($page, 'indexmenu_n', METADATA_RENDER_USING_SIMPLE_CACHE);
if ($key === null)
$key = '';
break;
case 'custom':
$key = p_get_metadata($page, 'include_n', METADATA_RENDER_USING_SIMPLE_CACHE);
if ($key === null)
$key = '';
break;
}
$key .= '_'.$page;
$ordered_pages[$key] = $page;
}
if ($flags['rsort']) {
krsort($ordered_pages);
} else {
ksort($ordered_pages);
}
$pages = $ordered_pages;
}
}

$result = array();
foreach ($pages as $page) {
Expand Down
8 changes: 8 additions & 0 deletions lang/en/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,13 @@
$lang['pageexists'] = 'do not display a link if the page does not exist (only affects linkonly mode)';
$lang['parlink'] = 'put a paragraph around the link (only affects linkonly mode)';
$lang['safeindex'] = 'prevent indexing of metadata from non-public included pages';
$lang['order'] = 'ordering criteria of includes with multiple pages';
$lang['order_o_id'] = 'page ID';
$lang['order_o_title'] = 'title';
$lang['order_o_created'] = 'creation date';
$lang['order_o_modified'] = 'modification date';
$lang['order_o_indexmenu'] = 'custom order with indexmenu syntax';
$lang['order_o_custom'] = 'custom order with include syntax';
$lang['rsort'] = 'reverse the sort order of the included pages';
$lang['depth'] = 'maximum depth of namespace includes, 0 for unlimited depth';
//Setup VIM: ex: et ts=2 :
4 changes: 2 additions & 2 deletions syntax/include.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ function handle($match, $state, $pos, &$handler) {

// break the pattern up into its parts
list($mode, $page, $sect) = preg_split('/>|#/u', $match, 3);
$check = null;
$check = false;
if (isset($sect)) $sect = sectionID($sect, $check);
return array($mode, $page, $sect, explode('&', $flags));
}
Expand All @@ -87,7 +87,7 @@ function handle($match, $state, $pos, &$handler) {
* @author Michael Hamann <[email protected]>
*/
function render($format, &$renderer, $data) {
global $ID, $conf;
global $ID;

// static stack that records all ancestors of the child pages
static $page_stack = array();
Expand Down
62 changes: 62 additions & 0 deletions syntax/sorttag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

if(!defined('DOKU_INC')) die();

/**
* Include plugin sort order tag, idea and parts of the code copied from the indexmenu plugin.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Samuele Tognini <[email protected]>
* @author Michael Hamann <[email protected]>
*
*/
class syntax_plugin_include_sorttag extends DokuWiki_Syntax_Plugin {

/**
* What kind of syntax are we?
*/
public function getType(){
return 'substition';
}

/**
* The paragraph type - block, we don't need paragraph tags
*
* @return string The paragraph type
*/
public function getPType() {
return 'block';
}

/**
* Where to sort in?
*/
public function getSort(){
return 139;
}

/**
* Connect pattern to lexer
*/
public function connectTo($mode) {
$this->Lexer->addSpecialPattern('{{include_n>.+?}}',$mode,'plugin_include_sorttag');
}

/**
* Handle the match
*/
public function handle($match, $state, $pos, &$handler){
$match = substr($match,12,-2);
return array($match);
}

/**
* Render output
*/
public function render($mode, &$renderer, $data) {
if ($mode === 'metadata') {
/** @var Doku_Renderer_metadata $renderer */
$renderer->meta['include_n'] = $data[0];
}
}
}

0 comments on commit df062bd

Please sign in to comment.