MDL-36874 mod_book: Add text navigation.
authorDavid Balch <david.balch@conted.ox.ac.uk>
Wed, 29 Oct 2014 09:43:10 +0000 (09:43 +0000)
committerDavid Balch <david.balch@conted.ox.ac.uk>
Wed, 29 Oct 2014 09:43:10 +0000 (09:43 +0000)
Based on a patch by Matthew Cannings, this replaces Book's previous/next arrow
image links with a choice of: no links, image links, or chapter title text links.

mod/book/backup/moodle2/backup_book_stepslib.php
mod/book/db/install.xml
mod/book/db/upgrade.php
mod/book/lang/en/book.php
mod/book/lib.php
mod/book/locallib.php
mod/book/mod_form.php
mod/book/settings.php
mod/book/styles.css
mod/book/version.php
mod/book/view.php

index 27f1c89..50fbd51 100644 (file)
@@ -31,10 +31,14 @@ class backup_book_activity_structure_step extends backup_activity_structure_step
 
     protected function define_structure() {
 
-        // Define each element separated
-        $book     = new backup_nested_element('book', array('id'), array('name', 'intro', 'introformat', 'numbering', 'customtitles', 'timecreated', 'timemodified'));
+        // Define each element separated.
+        $book = new backup_nested_element('book', array('id'), array(
+            'name', 'intro', 'introformat', 'numbering', 'navstyle',
+            'customtitles', 'timecreated', 'timemodified'));
         $chapters = new backup_nested_element('chapters');
-        $chapter  = new backup_nested_element('chapter', array('id'), array('pagenum', 'subchapter', 'title', 'content', 'contentformat', 'hidden', 'timemcreated', 'timemodified', 'importsrc',));
+        $chapter = new backup_nested_element('chapter', array('id'), array(
+            'pagenum', 'subchapter', 'title', 'content', 'contentformat',
+            'hidden', 'timemcreated', 'timemodified', 'importsrc'));
 
         $book->add_child($chapters);
         $chapters->add_child($chapter);
index 546b1a2..c1b8598 100644 (file)
@@ -12,6 +12,7 @@
         <FIELD NAME="intro" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
         <FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="numbering" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="navstyle" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
         <FIELD NAME="customtitles" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="revision" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
@@ -40,4 +41,4 @@
       </KEYS>
     </TABLE>
   </TABLES>
-</XMLDB>
\ No newline at end of file
+</XMLDB>
index 744fedf..e444368 100644 (file)
@@ -203,6 +203,19 @@ function xmldb_book_upgrade($oldversion) {
 
     // Moodle v2.7.0 release upgrade line.
     // Put any upgrade step following this.
+    if ($oldversion < 2014051201) {
+        // MDL-36874 Book update.
+        $table = new xmldb_table('book');
+        $field = new xmldb_field('navstyle', XMLDB_TYPE_INTEGER, '4' , XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 1);
+
+        // Conditionally launch add field navstyle.
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        // MDL-36874 savepoint reached.
+        upgrade_mod_savepoint(true, 2014051201, 'book');
+    }
 
     return true;
 }
index 94359f8..d027a5b 100644 (file)
@@ -51,6 +51,14 @@ $string['eventchapterdeleted'] = 'Chapter deleted';
 $string['eventchapterupdated'] = 'Chapter updated';
 $string['eventchapterviewed'] = 'Chapter viewed';
 $string['subchapter'] = 'Subchapter';
+$string['navimages'] = 'Images';
+$string['navoptions'] = 'Available options for navigational links';
+$string['navoptions_desc'] = 'Options for displaying navigation on the book pages';
+$string['navstyle'] = 'Style of navigation';
+$string['navstyle_help'] = '* Images - Icons are used for navigation
+* Text - Chapter titles are used for navigation';
+$string['navtext'] = 'Text';
+$string['navtoc'] = 'TOC Only';
 $string['nocontent'] = 'No content has been added to this book yet.';
 $string['numbering'] = 'Chapter formatting';
 $string['numbering_help'] = '* None - Chapter and subchapter titles have no formatting
index 8f19e2a..6e3fabc 100644 (file)
@@ -41,6 +41,28 @@ function book_get_numbering_types() {
     );
 }
 
+/**
+ * Returns list of available navigation link types.
+ * @return array
+ */
+function book_get_nav_types() {
+    require_once(dirname(__FILE__).'/locallib.php');
+
+    return array (
+        BOOK_LINK_TOCONLY   => get_string('navtoc', 'mod_book'),
+        BOOK_LINK_IMAGE     => get_string('navimages', 'mod_book'),
+        BOOK_LINK_TEXT      => get_string('navtext', 'mod_book'),
+    );
+}
+
+/**
+ * Returns list of available navigation link CSS classes.
+ * @return array
+ */
+function book_get_nav_classes() {
+    return array ('navtoc', 'navimages', 'navtext');
+}
+
 /**
  * Returns all other caps used in module
  * @return array
index 0bc9061..e9c6d5f 100644 (file)
@@ -39,6 +39,16 @@ define('BOOK_NUM_NUMBERS',  '1');
 define('BOOK_NUM_BULLETS',  '2');
 define('BOOK_NUM_INDENTED', '3');
 
+/**
+ * The following defines are used to define the navigation style used within a book.
+ * BOOK_LINK_TOCONLY    Only the table of contents is shown, in a side region.
+ * BOOK_LINK_IMAGE      Arrows link to previous/next/exit pages, in addition to the TOC.
+ * BOOK_LINK_TEXT       Page names and arrows link to previous/next/exit pages, in addition to the TOC.
+ */
+define ('BOOK_LINK_TOCONLY', '0');
+define ('BOOK_LINK_IMAGE', '1');
+define ('BOOK_LINK_TEXT', '2');
+
 /**
  * Preload book chapters and fix toc structure if necessary.
  *
index 40d9f72..e2ac096 100644 (file)
@@ -70,6 +70,25 @@ class mod_book_mod_form extends moodleform_mod {
         $mform->addHelpButton('numbering', 'numbering', 'mod_book');
         $mform->setDefault('numbering', $config->numbering);
 
+        $alloptions = book_get_nav_types();
+        $allowed = explode(',', $config->navoptions);
+        $options = array();
+        foreach ($allowed as $type) {
+            if (isset($alloptions[$type])) {
+                $options[$type] = $alloptions[$type];
+            }
+        }
+        if ($this->current->instance) {
+            if (!isset($options[$this->current->navstyle])) {
+                if (isset($alloptions[$this->current->navstyle])) {
+                    $options[$this->current->navstyle] = $alloptions[$this->current->navstyle];
+                }
+            }
+        }
+        $mform->addElement('select', 'navstyle', get_string('navstyle', 'book'), $options);
+        $mform->addHelpButton('navstyle', 'navstyle', 'mod_book');
+        $mform->setDefault('navstyle', $config->navstyle);
+
         $mform->addElement('checkbox', 'customtitles', get_string('customtitles', 'book'));
         $mform->addHelpButton('customtitles', 'customtitles', 'mod_book');
         $mform->setDefault('customtitles', 0);
index 11420ae..d759e39 100644 (file)
@@ -38,12 +38,20 @@ if ($ADMIN->fulltree) {
         get_string('numberingoptions', 'mod_book'), get_string('numberingoptions_desc', 'mod_book'),
         array_keys($options), $options));
 
+    $navoptions = book_get_nav_types();
+    $settings->add(new admin_setting_configmultiselect('book/navoptions',
+        get_string('navoptions', 'mod_book'), get_string('navoptions_desc', 'mod_book'),
+        array_keys($navoptions), $navoptions));
 
     // Modedit defaults.
 
-    $settings->add(new admin_setting_heading('bookmodeditdefaults', get_string('modeditdefaults', 'admin'), get_string('condifmodeditdefaults', 'admin')));
+    $settings->add(new admin_setting_heading('bookmodeditdefaults',
+        get_string('modeditdefaults', 'admin'), get_string('condifmodeditdefaults', 'admin')));
 
     $settings->add(new admin_setting_configselect('book/numbering',
         get_string('numbering', 'mod_book'), '', BOOK_NUM_NUMBERS, $options));
 
+    $settings->add(new admin_setting_configselect('book/navstyle',
+        get_string('navstyle', 'mod_book'), '', BOOK_LINK_IMAGE, $navoptions));
+
 }
index 4e2daa4..4a60767 100644 (file)
@@ -19,6 +19,9 @@
 .path-mod-book .navtop {
     margin-bottom: 0.5em;
 }
+.path-mod-book .navbottom {
+    margin-top: 0.5em;
+}
 
 /* == Fake toc block == */
 
 .path-mod-book .book_toc_indented li li {
     list-style: none;
 }
+
+/* Text style links */
+.navtop.navtext .chaptername,
+.navbottom.navtext .chaptername {
+    font-weight: bolder;
+}
+.navtop.navtext a,
+.navbottom.navtext a {
+    display: inline-block;
+    max-width: 45%;
+}
+.navtop.navtext a.bookprev,
+.navbottom.navtext a.bookprev {
+    float: left;
+    text-align: left;
+}
+.dir-rtl .navtop.navtext a.bookprev,
+.dir-rtl .navbottom.navtext a.bookprev {
+    float: right;
+    text-align: right;
+}
+
+@media (max-width: 480px) {
+    .path-mod-book .navbottom,
+    .path-mod-book .navtop,
+    .dir-rtl.path-mod-book .navbottom,
+    .dir-rtl.path-mod-book .navtop {
+        text-align: center;
+    }
+    .navtop.navtext a,
+    .navbottom.navtext a {
+        display: block;
+        max-width: 100%;
+        margin: auto;
+    }
+    .navtop.navtext a.bookprev,
+    .navbottom.navtext a.bookprev,
+    .dir-rtl .navtop.navtext a.bookprev,
+    .dir-rtl .navbottom.navtext a.bookprev {
+        float: none;
+    }
+}
index 155c636..c5d5c8b 100644 (file)
@@ -25,6 +25,6 @@
 defined('MOODLE_INTERNAL') || die;
 
 $plugin->component = 'mod_book'; // Full name of the plugin (used for diagnostics)
-$plugin->version   = 2014051200; // The current module version (Date: YYYYMMDDXX)
+$plugin->version   = 2014051201; // The current module version (Date: YYYYMMDDXX)
 $plugin->requires  = 2014050800; // Requires this Moodle version
 $plugin->cron      = 0;          // Period for cron to check this module (secs)
index 3fd9b45..f2a6398 100644 (file)
@@ -127,7 +127,9 @@ book_add_fake_block($chapters, $chapter, $book, $cm, $edit);
 
 // prepare chapter navigation icons
 $previd = null;
+$prevtitle = null;
 $nextid = null;
+$nexttitle = null;
 $last = null;
 foreach ($chapters as $ch) {
     if (!$edit and $ch->hidden) {
@@ -135,37 +137,68 @@ foreach ($chapters as $ch) {
     }
     if ($last == $chapter->id) {
         $nextid = $ch->id;
+        $nexttitle = book_get_chapter_title($ch->id, $chapters, $book, $context);
         break;
     }
     if ($ch->id != $chapter->id) {
         $previd = $ch->id;
+        $prevtitle = book_get_chapter_title($ch->id, $chapters, $book, $context);
     }
     $last = $ch->id;
 }
 
-$navprevicon = right_to_left() ? 'nav_next' : 'nav_prev';
-$navnexticon = right_to_left() ? 'nav_prev' : 'nav_next';
-$navprevdisicon = right_to_left() ? 'nav_next_dis' : 'nav_prev_dis';
 
-$chnavigation = '';
-if ($previd) {
-    $chnavigation .= '<a title="'.get_string('navprev', 'book').'" href="view.php?id='.$cm->id.
-            '&amp;chapterid='.$previd.'"><img src="'.$OUTPUT->pix_url($navprevicon, 'mod_book').'" class="icon" alt="'.get_string('navprev', 'book').'"/></a>';
-} else {
-    $chnavigation .= '<img src="'.$OUTPUT->pix_url($navprevdisicon, 'mod_book').'" class="icon" alt="" />';
-}
-if ($nextid) {
-    $chnavigation .= '<a title="'.get_string('navnext', 'book').'" href="view.php?id='.$cm->id.
-            '&amp;chapterid='.$nextid.'"><img src="'.$OUTPUT->pix_url($navnexticon, 'mod_book').'" class="icon" alt="'.get_string('navnext', 'book').'" /></a>';
-} else {
-    $sec = $DB->get_field('course_sections', 'section', array('id' => $cm->section));
-    $returnurl = course_get_url($course, $sec);
-    $chnavigation .= '<a title="'.get_string('navexit', 'book').'" href="'.$returnurl.'"><img src="'.$OUTPUT->pix_url('nav_exit', 'mod_book').
-            '" class="icon" alt="'.get_string('navexit', 'book').'" /></a>';
-
-    // we are cheating a bit here, viewing the last page means user has viewed the whole book
-    $completion = new completion_info($course);
-    $completion->set_module_viewed($cm);
+if ($book->navstyle) {
+    $navprevicon = right_to_left() ? 'nav_next' : 'nav_prev';
+    $navnexticon = right_to_left() ? 'nav_prev' : 'nav_next';
+    $navprevdisicon = right_to_left() ? 'nav_next_dis' : 'nav_prev_dis';
+
+    $chnavigation = '';
+    if ($previd) {
+        $navprev = get_string('navprev', 'book');
+        if ($book->navstyle == 1) {
+            $chnavigation .= '<a title="' . $navprev . '" class="bookprev" href="view.php?id=' .
+                $cm->id . '&amp;chapterid=' . $previd .  '">' .
+                '<img src="' . $OUTPUT->pix_url($navprevicon, 'mod_book') . '" class="icon" alt="' . $navprev . '"/></a>';
+        } else {
+            $chnavigation .= '<a title="' . $navprev . '" class="bookprev" href="view.php?id=' .
+                $cm->id . '&amp;chapterid=' . $previd . '">' .
+                '<span class="chaptername"><span class="arrow">' . $OUTPUT->larrow() . '&nbsp;</span></span>' .
+                $navprev . ':&nbsp;<span class="chaptername">' . $prevtitle . '</span></a>';
+        }
+    } else {
+        if ($book->navstyle == 1) {
+            $chnavigation .= '<img src="' . $OUTPUT->pix_url($navprevdisicon, 'mod_book') . '" class="icon" alt="" />';
+        }
+    }
+    if ($nextid) {
+        $navnext = get_string('navnext', 'book');
+        if ($book->navstyle == 1) {
+            $chnavigation .= '<a title="' . $navnext . '" class="booknext" href="view.php?id=' .
+                $cm->id . '&amp;chapterid='.$nextid.'">' .
+                '<img src="' . $OUTPUT->pix_url($navnexticon, 'mod_book').'" class="icon" alt="' . $navnext . '" /></a>';
+        } else {
+            $chnavigation .= ' <a title="' . $navnext . '" class="booknext" href="view.php?id=' .
+                $cm->id . '&amp;chapterid='.$nextid.'">' .
+                $navnext . ':<span class="chaptername">&nbsp;' . $nexttitle.
+                '<span class="arrow">&nbsp;' . $OUTPUT->rarrow() . '</span></span></a>';
+        }
+    } else {
+        $navexit = get_string('navexit', 'book');
+        $sec = $DB->get_field('course_sections', 'section', array('id' => $cm->section));
+        $returnurl = course_get_url($course, $sec);
+        if ($book->navstyle == 1) {
+            $chnavigation .= '<a title="' . $navexit . '" class="bookexit"  href="'.$returnurl.'">' .
+                '<img src="' . $OUTPUT->pix_url('nav_exit', 'mod_book') . '" class="icon" alt="' . $navexit . '" /></a>';
+        } else {
+            $chnavigation .= ' <a title="' . $navexit . '" class="bookexit"  href="'.$returnurl.'">' .
+                '<span class="chaptername">' . $navexit . '&nbsp;' . $OUTPUT->uarrow() . '</span></a>';
+        }
+
+        // We cheat a bit here in assuming that viewing the last page means the user viewed the whole book.
+        $completion = new completion_info($course);
+        $completion->set_module_viewed($cm);
+    }
 }
 
 // =====================================================
@@ -175,10 +208,14 @@ if ($nextid) {
 echo $OUTPUT->header();
 echo $OUTPUT->heading($book->name);
 
-// upper nav
-echo '<div class="navtop">'.$chnavigation.'</div>';
+$navclasses = book_get_nav_classes();
+
+if ($book->navstyle) {
+    // Upper navigation.
+    echo '<div class="navtop clearfix ' . $navclasses[$book->navstyle] . '">' . $chnavigation . '</div>';
+}
 
-// chapter itself
+// The chapter itself.
 $hidden = $chapter->hidden ? ' dimmed_text' : null;
 echo $OUTPUT->box_start('generalbox book_content' . $hidden);
 
@@ -198,7 +235,9 @@ echo format_text($chaptertext, $chapter->contentformat, array('noclean'=>true, '
 
 echo $OUTPUT->box_end();
 
-// lower navigation
-echo '<div class="navbottom">'.$chnavigation.'</div>';
+if ($book->navstyle) {
+    // Lower navigation.
+    echo '<div class="navbottom clearfix ' . $navclasses[$book->navstyle] . '">' . $chnavigation . '</div>';
+}
 
 echo $OUTPUT->footer();