From e66d3e6dfa7ba6f0cf55b58f0b00b66b52c98321 Mon Sep 17 00:00:00 2001
From: Andreas Gohr <andi@splitbrain.org>
Date: Sun, 1 Jul 2012 11:41:22 +0200
Subject: [PATCH] Improved sidebar inclusion

Template authors now can use tpl_sidebar() to include the sidebar.
Sidebars can be defined in subnamespaces as well
---
 .../tests/inc/pageutils_findnearest.test.php  | 40 +++++++++++++++++++
 _test/tests/inc/template_sidebar.test.php     | 40 +++++++++++++++++++
 inc/pageutils.php                             | 24 +++++++++++
 inc/template.php                              | 12 ++++++
 lib/tpl/dokuwiki/detail.php                   |  2 +-
 lib/tpl/dokuwiki/main.php                     |  4 +-
 6 files changed, 119 insertions(+), 3 deletions(-)
 create mode 100644 _test/tests/inc/pageutils_findnearest.test.php
 create mode 100644 _test/tests/inc/template_sidebar.test.php

diff --git a/_test/tests/inc/pageutils_findnearest.test.php b/_test/tests/inc/pageutils_findnearest.test.php
new file mode 100644
index 000000000..e129b5e58
--- /dev/null
+++ b/_test/tests/inc/pageutils_findnearest.test.php
@@ -0,0 +1,40 @@
+<?php
+
+class pageutils_findnearest_test extends DokuWikiTest {
+    function testNoSidebar() {
+        global $ID;
+
+        $ID = 'foo:bar:baz:test';
+        $sidebar = page_findnearest('sidebar');
+        $this->assertEquals(false, $sidebar);
+    }
+
+    function testExistingSidebars() {
+        global $ID;
+
+        saveWikiText('sidebar', 'topsidebar-test', '');
+
+        $ID = 'foo:bar:baz:test';
+        $sidebar = page_findnearest('sidebar');
+        $this->assertEquals('sidebar', $sidebar);
+
+        $ID = 'foo';
+        $sidebar = page_findnearest('sidebar');
+        $this->assertEquals('sidebar', $sidebar);
+
+        saveWikiText('foo:bar:sidebar', 'bottomsidebar-test', '');
+
+        $ID = 'foo:bar:baz:test';
+        $sidebar = page_findnearest('sidebar');
+        $this->assertEquals('foo:bar:sidebar', $sidebar);
+
+        $ID = 'foo:bar:test';
+        $sidebar = page_findnearest('sidebar');
+        $this->assertEquals('foo:bar:sidebar', $sidebar);
+
+        $ID = 'foo';
+        $sidebar = page_findnearest('sidebar');
+        $this->assertEquals('sidebar', $sidebar);
+    }
+
+}
diff --git a/_test/tests/inc/template_sidebar.test.php b/_test/tests/inc/template_sidebar.test.php
new file mode 100644
index 000000000..56153894a
--- /dev/null
+++ b/_test/tests/inc/template_sidebar.test.php
@@ -0,0 +1,40 @@
+<?php
+
+class template_sidebar_test extends DokuWikiTest {
+    function testNoSidebar() {
+        global $ID;
+
+        $ID = 'foo:bar:baz:test';
+        $sidebar = tpl_sidebar(false);
+        $this->assertEquals('',$sidebar);
+    }
+
+    function testExistingSidebars() {
+        global $ID;
+
+        saveWikiText('sidebar', 'topsidebar-test', '');
+
+        $ID = 'foo:bar:baz:test';
+        $sidebar = tpl_sidebar(false);
+        $this->assertTrue(strpos($sidebar, 'topsidebar-test') > 0);
+
+        $ID = 'foo';
+        $sidebar = tpl_sidebar(false);
+        $this->assertTrue(strpos($sidebar, 'topsidebar-test') > 0);
+
+        saveWikiText('foo:bar:sidebar', 'bottomsidebar-test', '');
+
+        $ID = 'foo:bar:baz:test';
+        $sidebar = tpl_sidebar(false);
+        $this->assertTrue(strpos($sidebar, 'bottomsidebar-test') > 0);
+
+        $ID = 'foo:bar:test';
+        $sidebar = tpl_sidebar(false);
+        $this->assertTrue(strpos($sidebar, 'bottomsidebar-test') > 0);
+
+        $ID = 'foo';
+        $sidebar = tpl_sidebar(false);
+        $this->assertTrue(strpos($sidebar, 'topsidebar-test') > 0);
+    }
+
+}
diff --git a/inc/pageutils.php b/inc/pageutils.php
index c94d14624..f525c44d0 100644
--- a/inc/pageutils.php
+++ b/inc/pageutils.php
@@ -622,3 +622,27 @@ function utf8_decodeFN($file){
     return urldecode($file);
 }
 
+/**
+ * Find a page in the current namespace (determined from $ID) or any
+ * higher namespace
+ *
+ * Used for sidebars, but can be used other stuff as well
+ *
+ * @todo   add event hook
+ * @param  string $page the pagename you're looking for
+ * @return string|false the full page id of the found page, false if any
+ */
+function page_findnearest($page){
+    global $ID;
+
+    $ns = $ID;
+    do {
+        $ns = getNS($ns);
+        $pageid = ltrim("$ns:$page",':');
+        if(page_exists($pageid)){
+            return $pageid;
+        }
+    } while($ns);
+
+    return false;
+}
diff --git a/inc/template.php b/inc/template.php
index a18d7151f..c9e899034 100644
--- a/inc/template.php
+++ b/inc/template.php
@@ -1394,6 +1394,18 @@ function tpl_include_page($pageid,$print=true){
 
     if(!$print) return $html;
     echo $html;
+    return $html;
+}
+
+/**
+ * Include the sidebar, will check current namespaces first
+ */
+function tpl_sidebar($print=true){
+    global $conf;
+
+    $sidebar = page_findnearest($conf['sidebar']);
+    if($sidebar) return tpl_include_page($sidebar, $print);
+    return '';
 }
 
 /**
diff --git a/lib/tpl/dokuwiki/detail.php b/lib/tpl/dokuwiki/detail.php
index a3516a7ed..5fe1a1ad7 100644
--- a/lib/tpl/dokuwiki/detail.php
+++ b/lib/tpl/dokuwiki/detail.php
@@ -10,7 +10,7 @@
 // must be run from within DokuWiki
 if (!defined('DOKU_INC')) die();
 
-$showSidebar = $conf['sidebar'] && page_exists($conf['sidebar']) && ($ACT=='show');
+$showSidebar = page_findnearest($conf['sidebar']) && ($ACT=='show');
 ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>"
diff --git a/lib/tpl/dokuwiki/main.php b/lib/tpl/dokuwiki/main.php
index d8e85850f..e0b046574 100644
--- a/lib/tpl/dokuwiki/main.php
+++ b/lib/tpl/dokuwiki/main.php
@@ -10,7 +10,7 @@
 
 if (!defined('DOKU_INC')) die(); /* must be run from within DokuWiki */
 
-$showSidebar = $conf['sidebar'] && page_exists($conf['sidebar']) && ($ACT=='show');
+$showSidebar = page_findnearest($conf['sidebar']) && ($ACT=='show');
 ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang'] ?>"
@@ -41,7 +41,7 @@ $showSidebar = $conf['sidebar'] && page_exists($conf['sidebar']) && ($ACT=='show
                     <div class="content">
                         <?php tpl_flush() ?>
                         <?php tpl_includeFile('sidebarheader.html') ?>
-                        <?php tpl_include_page($conf['sidebar']) ?>
+                        <?php tpl_sidebar() ?>
                         <?php tpl_includeFile('sidebarfooter.html') ?>
                     </div>
                 </div></div><!-- /aside -->
-- 
GitLab