MDL-51698 navigationlib: Add crumb trail meta data
authorBrendan Heywood <brendan@catalyst-au.net>
Mon, 12 Oct 2015 06:11:28 +0000 (17:11 +1100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 8 Dec 2015 23:50:16 +0000 (00:50 +0100)
lib/navigationlib.php
lib/outputrenderers.php

index 9385451..b3b79cc 100644 (file)
@@ -3084,13 +3084,15 @@ class navbar extends navigation_node {
     public $children = array();
     /** @var bool A switch for whether we want to include the root node in the navbar */
     public $includesettingsbase = false;
-    /** @var navigation_node[] $prependchildren */
+    /** @var breadcrumb_navigation_node[] $prependchildren */
     protected $prependchildren = array();
     /**
      * The almighty constructor
      *
      * @param moodle_page $page
      */
+
+
     public function __construct(moodle_page $page) {
         global $CFG;
         if (during_initial_install()) {
@@ -3141,8 +3143,8 @@ class navbar extends navigation_node {
      * Gets a navigation node
      *
      * @param string|int $key for referencing the navbar nodes
-     * @param int $type navigation_node::TYPE_*
-     * @return navigation_node|bool
+     * @param int $type breadcrumb_navigation_node::TYPE_*
+     * @return breadcrumb_navigation_node|bool
      */
     public function get($key, $type = null) {
         foreach ($this->children as &$child) {
@@ -3158,7 +3160,7 @@ class navbar extends navigation_node {
         return false;
     }
     /**
-     * Returns an array of navigation_node's that make up the navbar.
+     * Returns an array of breadcrumb_navigation_nodes that make up the navbar.
      *
      * @return array
      */
@@ -3190,7 +3192,7 @@ class navbar extends navigation_node {
                 // Parse a combined navigation tree
                 while ($settingsactivenode && $settingsactivenode->parent !== null) {
                     if (!$settingsactivenode->mainnavonly) {
-                        $items[] = $settingsactivenode;
+                        $items[] = new breadcrumb_navigation_node($settingsactivenode);
                     }
                     $settingsactivenode = $settingsactivenode->parent;
                 }
@@ -3200,12 +3202,14 @@ class navbar extends navigation_node {
                 }
                 while ($navigationactivenode && $navigationactivenode->parent !== null) {
                     if (!$navigationactivenode->mainnavonly) {
-                        $items[] = $navigationactivenode;
+                        $items[] = new breadcrumb_navigation_node($navigationactivenode);
                     }
                     if (!empty($CFG->navshowcategories) &&
                             $navigationactivenode->type === self::TYPE_COURSE &&
                             $navigationactivenode->parent->key === 'currentcourse') {
-                        $items = array_merge($items, $this->get_course_categories());
+                        foreach ($this->get_course_categories() as $item) {
+                            $items[] = new breadcrumb_navigation_node($item);
+                        }
                     }
                     $navigationactivenode = $navigationactivenode->parent;
                 }
@@ -3213,12 +3217,14 @@ class navbar extends navigation_node {
                 // Parse the navigation tree to get the active node
                 while ($navigationactivenode && $navigationactivenode->parent !== null) {
                     if (!$navigationactivenode->mainnavonly) {
-                        $items[] = $navigationactivenode;
+                        $items[] = new breadcrumb_navigation_node($navigationactivenode);
                     }
                     if (!empty($CFG->navshowcategories) &&
                             $navigationactivenode->type === self::TYPE_COURSE &&
                             $navigationactivenode->parent->key === 'currentcourse') {
-                        $items = array_merge($items, $this->get_course_categories());
+                        foreach ($this->get_course_categories() as $item) {
+                            $items[] = new breadcrumb_navigation_node($item);
+                        }
                     }
                     $navigationactivenode = $navigationactivenode->parent;
                 }
@@ -3226,18 +3232,18 @@ class navbar extends navigation_node {
                 // Parse the settings navigation to get the active node
                 while ($settingsactivenode && $settingsactivenode->parent !== null) {
                     if (!$settingsactivenode->mainnavonly) {
-                        $items[] = $settingsactivenode;
+                        $items[] = new breadcrumb_navigation_node($settingsactivenode);
                     }
                     $settingsactivenode = $settingsactivenode->parent;
                 }
             }
         }
 
-        $items[] = new navigation_node(array(
-            'text'=>$this->page->navigation->text,
-            'shorttext'=>$this->page->navigation->shorttext,
-            'key'=>$this->page->navigation->key,
-            'action'=>$this->page->navigation->action
+        $items[] = new breadcrumb_navigation_node(array(
+            'text' => $this->page->navigation->text,
+            'shorttext' => $this->page->navigation->shorttext,
+            'key' => $this->page->navigation->key,
+            'action' => $this->page->navigation->action
         ));
 
         if (count($this->prependchildren) > 0) {
@@ -3274,7 +3280,7 @@ class navbar extends navigation_node {
                 }
                 $url = new moodle_url('/course/index.php', array('categoryid' => $category->id));
                 $name = format_string($category->name, true, array('context' => context_coursecat::instance($category->id)));
-                $categorynode = navigation_node::create($name, $url, self::TYPE_CATEGORY, null, $category->id);
+                $categorynode = breadcrumb_navigation_node::create($name, $url, self::TYPE_CATEGORY, null, $category->id);
                 if (!$category->visible) {
                     $categorynode->hidden = true;
                 }
@@ -3287,7 +3293,7 @@ class navbar extends navigation_node {
             $courses = $this->page->navigation->get('courses');
             if (!$courses) {
                 // Courses node may not be present.
-                $courses = navigation_node::create(
+                $courses = breadcrumb_navigation_node::create(
                     get_string('courses'),
                     new moodle_url('/course/index.php'),
                     self::TYPE_CONTAINER
@@ -3300,9 +3306,9 @@ class navbar extends navigation_node {
     }
 
     /**
-     * Add a new navigation_node to the navbar, overrides parent::add
+     * Add a new breadcrumb_navigation_node to the navbar, overrides parent::add
      *
-     * This function overrides {@link navigation_node::add()} so that we can change
+     * This function overrides {@link breadcrumb_navigation_node::add()} so that we can change
      * the way nodes get added to allow us to simply call add and have the node added to the
      * end of the navbar
      *
@@ -3345,7 +3351,7 @@ class navbar extends navigation_node {
         // Set the parent to this node
         $itemarray['parent'] = $this;
         // Add the child using the navigation_node_collections add method
-        $this->children[] = new navigation_node($itemarray);
+        $this->children[] = new breadcrumb_navigation_node($itemarray);
         return $this;
     }
 
@@ -3390,11 +3396,44 @@ class navbar extends navigation_node {
         // Set the parent to this node.
         $itemarray['parent'] = $this;
         // Add the child node to the prepend list.
-        $this->prependchildren[] = new navigation_node($itemarray);
+        $this->prependchildren[] = new breadcrumb_navigation_node($itemarray);
         return $this;
     }
 }
 
+/**
+ * Subclass of navigation_node allowing different rendering for the breadcrumbs
+ * in particular adding extra metadata for search engine robots to leverage.
+ *
+ * @package   core
+ * @category  navigation
+ * @copyright 2015 Brendan Heywood
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class breadcrumb_navigation_node extends navigation_node {
+
+    /**
+     * A proxy constructor
+     *
+     * @param mixed $navnode A navigation_node or an array
+     */
+    public function __construct($navnode) {
+        if (is_array($navnode)) {
+            parent::__construct($navnode);
+        } else if ($navnode instanceof navigation_node) {
+
+            // Just clone everything.
+            $objvalues = get_object_vars($navnode);
+            foreach ($objvalues as $key => $value) {
+                 $this->$key = $value;
+            }
+        } else {
+            throw coding_exception('Not a valid breadcrumb_navigation_node');
+        }
+    }
+
+}
+
 /**
  * Class used to manage the settings option for the current page
  *
index 99f4cb2..35fba72 100644 (file)
@@ -3340,6 +3340,39 @@ EOD;
         return $navbarcontent;
     }
 
+    /**
+     * Renders a breadcrumb navigation node object.
+     *
+     * @param breadcrumb_navigation_node $item The navigation node to render.
+     * @return string HTML fragment
+     */
+    protected function render_breadcrumb_navigation_node(breadcrumb_navigation_node $item) {
+
+        if ($item->action instanceof moodle_url) {
+            $content = $item->get_content();
+            $title = $item->get_title();
+            $attributes = array();
+            $attributes['itemprop'] = 'url';
+            if ($title !== '') {
+                $attributes['title'] = $title;
+            }
+            if ($item->hidden) {
+                $attributes['class'] = 'dimmed_text';
+            }
+            $content = html_writer::tag('span', $content, array('itemprop' => 'title'));
+            $content = html_writer::link($item->action, $content, $attributes);
+
+            $attributes = array();
+            $attributes['itemscope'] = '';
+            $attributes['itemtype'] = 'http://data-vocabulary.org/Breadcrumb';
+            $content = html_writer::tag('span', $content, $attributes);
+
+        } else {
+            $content = $this->render_navigation_node($item);
+        }
+        return $content;
+    }
+
     /**
      * Renders a navigation node object.
      *