From f431561b688e97f8f1eb49edf8c82151e62a1795 Mon Sep 17 00:00:00 2001
From: Sam Hemelryk <sam@moodle.com>
Date: Thu, 9 Dec 2010 16:13:05 +0800
Subject: [PATCH] Initial commit of course format output refactoring.
 This commit introduces the generic format renderer (core_course_generic_format_renderer)
 which contains primarily conversion of print_ functions from course/lib.php as well as
 the functions generated from the absraction of display routines common in both the
 weeks and topics formats.
 It also implements the conversion of weeks and topics formats to their own rendeers
 which extend the generic renderer.

---
 blocks/site_main_menu/block_site_main_menu.php     |    5 +-
 .../social_activities/block_social_activities.php  |    5 +-
 course/format/topics/format.php                    |  189 +----
 course/format/topics/renderer.php                  |  133 ++++
 course/format/weeks/format.php                     |  189 ++----
 course/format/weeks/renderer.php                   |  120 +++
 course/lib.php                                     |  635 ++--------------
 course/renderer.php                                |  818 +++++++++++++++++++-
 index.php                                          |    5 +-
 lib/outputlib.php                                  |    2 +-
 10 files changed, 1215 insertions(+), 886 deletions(-)
 create mode 100644 course/format/topics/renderer.php
 create mode 100644 course/format/weeks/renderer.php

diff --git a/blocks/site_main_menu/block_site_main_menu.php b/blocks/site_main_menu/block_site_main_menu.php
index 3e139ac..1211730 100644
--- a/blocks/site_main_menu/block_site_main_menu.php
+++ b/blocks/site_main_menu/block_site_main_menu.php
@@ -64,6 +64,7 @@ class block_site_main_menu extends block_list {
 /// slow & hacky editing mode
         $ismoving = ismoving($course->id);
         $section  = get_course_section(0, $course->id);
+        $renderer = $this->page->get_renderer('core_course', 'generic_format');
 
         get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
 
@@ -101,7 +102,7 @@ class block_site_main_menu extends block_list {
                     } else {
                         $mod->groupmode = false;
                     }
-                    $editbuttons = '<div class="buttons">'.make_editing_buttons($mod, true, true).'</div>';
+                    $editbuttons = '<div class="buttons">'.$renderer->section_module_controls($mod, true).'</div>';
                 } else {
                     $editbuttons = '';
                 }
@@ -148,7 +149,7 @@ class block_site_main_menu extends block_list {
         }
 
         if (!empty($modnames)) {
-            $this->content->footer = print_section_add_menus($course, 0, $modnames, true, true);
+            $this->content->footer = $renderer->section_add_menus($course, 0, $modnames, array('vertical'=>true));
         } else {
             $this->content->footer = '';
         }
diff --git a/blocks/social_activities/block_social_activities.php b/blocks/social_activities/block_social_activities.php
index bcf7d7b..fd8bbca 100644
--- a/blocks/social_activities/block_social_activities.php
+++ b/blocks/social_activities/block_social_activities.php
@@ -67,6 +67,7 @@ class block_social_activities extends block_list {
 /// slow & hacky editing mode
         $ismoving = ismoving($course->id);
         $sections = get_all_sections($course->id);
+        $renderer = $this->page->get_renderer('core_course', 'generic_format');
 
         if(!empty($sections) && isset($sections[0])) {
             $section = $sections[0];
@@ -110,7 +111,7 @@ class block_social_activities extends block_list {
                     } else {
                         $mod->groupmode = false;
                     }
-                    $editbuttons = '<br />'.make_editing_buttons($mod, true, true);
+                    $editbuttons = '<br />'.$renderer->section_module_controls($mod, true);
                 } else {
                     $editbuttons = '';
                 }
@@ -157,7 +158,7 @@ class block_social_activities extends block_list {
         }
 
         if ($modnames) {
-            $this->content->footer = print_section_add_menus($course, 0, $modnames, true, true);
+            $this->content->footer = $renderer->section_add_menus($course, 0, $modnames, array('vertical'=>true));
         } else {
             $this->content->footer = '';
         }
diff --git a/course/format/topics/format.php b/course/format/topics/format.php
index 12611df..b022d67 100644
--- a/course/format/topics/format.php
+++ b/course/format/topics/format.php
@@ -49,23 +49,8 @@ if (($marker >=0) && has_capability('moodle/course:setcurrentsection', $context)
     $DB->set_field("course", "marker", $marker, array("id"=>$course->id));
 }
 
-$streditsummary  = get_string('editsummary');
-$stradd          = get_string('add');
-$stractivities   = get_string('activities');
-$strshowalltopics = get_string('showalltopics');
-$strtopic         = get_string('topic');
-$strgroups       = get_string('groups');
-$strgroupmy      = get_string('groupmy');
-$editing         = $PAGE->user_is_editing();
-
-if ($editing) {
-    $strtopichide = get_string('hidetopicfromothers');
-    $strtopicshow = get_string('showtopicfromothers');
-    $strmarkthistopic = get_string('markthistopic');
-    $strmarkedthistopic = get_string('markedthistopic');
-    $strmoveup   = get_string('moveup');
-    $strmovedown = get_string('movedown');
-}
+$isediting  = $PAGE->user_is_editing();
+$renderer   = $PAGE->get_renderer('format_topics');
 
 // Print the Your progress icon if the track completion is enabled
 $completioninfo = new completion_info($course);
@@ -74,15 +59,16 @@ $completioninfo->print_help_icon();
 echo $OUTPUT->heading(get_string('topicoutline'), 2, 'headingblock header outline');
 
 // Note, an ordered list would confuse - "1" could be the clipboard or summary.
-echo "<ul class='topics'>\n";
+echo html_writer::start_tag('ul', array('class'=>'topics'));
 
 /// If currently moving a file then show the current clipboard
 if (ismoving($course->id)) {
     $stractivityclipboard = strip_tags(get_string('activityclipboard', '', $USER->activitycopyname));
     $strcancel= get_string('cancel');
-    echo '<li class="clipboard">';
+    
+    echo html_writer::start_tag('li', array('class'=>'clipboard'));
     echo $stractivityclipboard.'&nbsp;&nbsp;(<a href="mod.php?cancelcopy=true&amp;sesskey='.sesskey().'">'.$strcancel.'</a>)';
-    echo "</li>\n";
+    echo html_writer::end_tag('li');
 }
 
 /// Print Section 0 with general activities
@@ -91,44 +77,10 @@ $section = 0;
 $thissection = $sections[$section];
 unset($sections[0]);
 
-if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) {
-
-    // Note, no need for a 'left side' cell or DIV.
-    // Note, 'right side' is BEFORE content.
-    echo '<li id="section-0" class="section main clearfix" >';
-    echo '<div class="left side">&nbsp;</div>';
-    echo '<div class="right side" >&nbsp;</div>';
-    echo '<div class="content">';
-    if (!is_null($thissection->name)) {
-        echo $OUTPUT->heading($thissection->name, 3, 'sectionname');
-    }
-    echo '<div class="summary">';
-
-    $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-    $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
-    $summaryformatoptions = new stdClass();
-    $summaryformatoptions->noclean = true;
-    $summaryformatoptions->overflowdiv = true;
-    echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
-
-    if ($PAGE->user_is_editing() && has_capability('moodle/course:update', $coursecontext)) {
-        echo '<a title="'.$streditsummary.'" '.
-             ' href="editsection.php?id='.$thissection->id.'"><img src="'.$OUTPUT->pix_url('t/edit') . '" '.
-             ' class="icon edit" alt="'.$streditsummary.'" /></a>';
-    }
-    echo '</div>';
-
-    print_section($course, $thissection, $mods, $modnamesused);
-
-    if ($PAGE->user_is_editing()) {
-        print_section_add_menus($course, $section, $modnames);
+if ($thissection->summary or $thissection->sequence or $isediting) {
+    echo $renderer->initial_section($course, $thissection, $mods, $modnames);
     }
 
-    echo '</div>';
-    echo "</li>\n";
-}
-
-
 /// Now all the normal modules by topic
 /// Everything below uses "section" terminology - each "section" is a topic.
 
@@ -136,6 +88,9 @@ $timenow = time();
 $section = 1;
 $sectionmenu = array();
 
+$canviewhiddensections = has_capability('moodle/course:viewhiddensections', $context);
+$canupdatecourse = has_capability('moodle/course:update', $context);
+
 while ($section <= $course->numsections) {
 
     if (!empty($sections[$section])) {
@@ -152,7 +107,7 @@ while ($section <= $course->numsections) {
         $thissection->id = $DB->insert_record('course_sections', $thissection);
     }
 
-    $showsection = (has_capability('moodle/course:viewhiddensections', $context) or $thissection->visible or !$course->hiddensections);
+    $showsection = ($canviewhiddensections or $thissection->visible or !$course->hiddensections);
 
     if (!empty($displaysection) and $displaysection != $section) {  // Check this topic is visible
         if ($showsection) {
@@ -164,101 +119,48 @@ while ($section <= $course->numsections) {
 
     if ($showsection) {
 
+        $content = '';
+        $leftside = '';
+        $rightside = '';
+        $attributes = array('id'=>'section-'.$section, 'class' => 'section main clearfix');
+
         $currenttopic = ($course->marker == $section);
 
         $currenttext = '';
         if (!$thissection->visible) {
-            $sectionstyle = ' hidden';
+            $attributes['class'] .= ' hidden';
         } else if ($currenttopic) {
-            $sectionstyle = ' current';
+            $attributes['class'] .= ' current';
             $currenttext = get_accesshide(get_string('currenttopic','access'));
-        } else {
-            $sectionstyle = '';
         }
+        $leftside .= $currenttext.$section;
 
-        echo '<li id="section-'.$section.'" class="section main clearfix'.$sectionstyle.'" >'; //'<div class="left side">&nbsp;</div>';
-
-            echo '<div class="left side">'.$currenttext.$section.'</div>';
-        // Note, 'right side' is BEFORE content.
-        echo '<div class="right side">';
-
-        if ($displaysection == $section) {    // Show the zoom boxes
-            echo '<a href="view.php?id='.$course->id.'&amp;topic=0#section-'.$section.'" title="'.$strshowalltopics.'">'.
-                 '<img src="'.$OUTPUT->pix_url('i/all') . '" class="icon" alt="'.$strshowalltopics.'" /></a><br />';
-        } else {
-            $strshowonlytopic = get_string("showonlytopic", "", $section);
-            echo '<a href="view.php?id='.$course->id.'&amp;topic='.$section.'" title="'.$strshowonlytopic.'">'.
-                 '<img src="'.$OUTPUT->pix_url('i/one') . '" class="icon" alt="'.$strshowonlytopic.'" /></a><br />';
+        $rightside .= $renderer->section_zoom_link($course, $section, $displaysection);
+        if ($isediting && $canupdatecourse) {
+            $rightside .= $renderer->section_editing_controls($course, $thissection, $section);
         }
 
-        if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
-
-            if ($course->marker == $section) {  // Show the "light globe" on/off
-                echo '<a href="view.php?id='.$course->id.'&amp;marker=0&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strmarkedthistopic.'">'.'<img src="'.$OUTPUT->pix_url('i/marked') . '" alt="'.$strmarkedthistopic.'" /></a><br />';
+        if (!$canviewhiddensections and !$thissection->visible) {   // Hidden for students
+            $content .= get_string('notavailable');
             } else {
-                echo '<a href="view.php?id='.$course->id.'&amp;marker='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strmarkthistopic.'">'.'<img src="'.$OUTPUT->pix_url('i/marker') . '" alt="'.$strmarkthistopic.'" /></a><br />';
-            }
-
-            if ($thissection->visible) {        // Show the hide/show eye
-                echo '<a href="view.php?id='.$course->id.'&amp;hide='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strtopichide.'">'.
-                     '<img src="'.$OUTPUT->pix_url('i/hide') . '" class="icon hide" alt="'.$strtopichide.'" /></a><br />';
-            } else {
-                echo '<a href="view.php?id='.$course->id.'&amp;show='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strtopicshow.'">'.
-                     '<img src="'.$OUTPUT->pix_url('i/show') . '" class="icon hide" alt="'.$strtopicshow.'" /></a><br />';
-            }
-            if ($section > 1) {                       // Add a arrow to move section up
-                echo '<a href="view.php?id='.$course->id.'&amp;random='.rand(1,10000).'&amp;section='.$section.'&amp;move=-1&amp;sesskey='.sesskey().'#section-'.($section-1).'" title="'.$strmoveup.'">'.
-                     '<img src="'.$OUTPUT->pix_url('t/up') . '" class="icon up" alt="'.$strmoveup.'" /></a><br />';
-            }
-
-            if ($section < $course->numsections) {    // Add a arrow to move section down
-                echo '<a href="view.php?id='.$course->id.'&amp;random='.rand(1,10000).'&amp;section='.$section.'&amp;move=1&amp;sesskey='.sesskey().'#section-'.($section+1).'" title="'.$strmovedown.'">'.
-                     '<img src="'.$OUTPUT->pix_url('t/down') . '" class="icon down" alt="'.$strmovedown.'" /></a><br />';
-            }
-        }
-        echo '</div>';
-
-        echo '<div class="content">';
-        if (!has_capability('moodle/course:viewhiddensections', $context) and !$thissection->visible) {   // Hidden for students
-            echo get_string('notavailable');
-        } else {
             if (!is_null($thissection->name)) {
-                echo $OUTPUT->heading($thissection->name, 3, 'sectionname');
+                $content .= $OUTPUT->heading($thissection->name, 3, 'sectionname');
             }
-            echo '<div class="summary">';
-            if ($thissection->summary) {
-                $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
-                $summaryformatoptions = new stdClass();
-                $summaryformatoptions->noclean = true;
-                $summaryformatoptions->overflowdiv = true;
-                echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
-            } else {
-               echo '&nbsp;';
+            $content .= $renderer->section_summary($thissection, $context);
+            $content .= $renderer->section($course, $thissection, $mods);
+            if ($isediting) {
+                $content .= $renderer->section_add_menus($course, $section, $modnames);
             }
-
-            if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                echo ' <a title="'.$streditsummary.'" href="editsection.php?id='.$thissection->id.'">'.
-                     '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="icon edit" alt="'.$streditsummary.'" /></a><br /><br />';
             }
-            echo '</div>';
 
-            print_section($course, $thissection, $mods, $modnamesused);
-            echo '<br />';
-            if ($PAGE->user_is_editing()) {
-                print_section_add_menus($course, $section, $modnames);
+        echo $renderer->section_structure($content, $leftside, $rightside, $attributes);
             }
-        }
-
-        echo '</div>';
-        echo "</li>\n";
-    }
 
     unset($sections[$section]);
     $section++;
 }
 
-if (!$displaysection and $PAGE->user_is_editing() and has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
+if (!$displaysection and $isediting and $canupdatecourse) {
     // print stealth sections if present
     $modinfo = get_fast_modinfo($course);
     foreach ($sections as $section=>$thissection) {
@@ -266,28 +168,17 @@ if (!$displaysection and $PAGE->user_is_editing() and has_capability('moodle/cou
             continue;
         }
 
-        echo '<li id="section-'.$section.'" class="section main clearfix orphaned hidden">'; //'<div class="left side">&nbsp;</div>';
-
-        echo '<div class="left side">';
-        echo '</div>';
-        // Note, 'right side' is BEFORE content.
-        echo '<div class="right side">';
-        echo '</div>';
-        echo '<div class="content">';
-        echo $OUTPUT->heading(get_string('orphanedactivities'), 3, 'sectionname');
-        print_section($course, $thissection, $mods, $modnamesused);
-        echo '</div>';
-        echo "</li>\n";
+        $content  = $OUTPUT->heading(get_string('orphanedactivities'), 3, 'sectionname');
+        $content .= $renderer->section($course, $thissection, $mods);
+        $leftside = '';
+        $rightside = '';
+        $attributes = array('id'=>'section-'.$section, 'class'=>'section main clearfix stealth hidden');
+        echo $renderer->section_structure($content, $leftside, $rightside, $attributes);
     }
 }
 
-
-echo "</ul>\n";
+echo html_writer::end_tag('ul'); // .topics
 
 if (!empty($sectionmenu)) {
-    $select = new single_select(new moodle_url('/course/view.php', array('id'=>$course->id)), 'topic', $sectionmenu);
-    $select->label = get_string('jumpto');
-    $select->class = 'jumpmenu';
-    $select->formid = 'sectionmenu';
-    echo $OUTPUT->render($select);
+    echo $renderer->section_jumpto_menu($course->id, $sectionmenu, 'topics');
 }
diff --git a/course/format/topics/renderer.php b/course/format/topics/renderer.php
new file mode 100644
index 0000000..600f4db
--- /dev/null
+++ b/course/format/topics/renderer.php
@@ -0,0 +1,133 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This is the renderer for the topics course format.
+ * 
+ * It extends and builds upon the generic format renderer.
+ *
+ * @package   moodlecore
+ * @copyright 2010 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Make sure we have included the generic format renderer.
+ */
+require_once($CFG->dirroot.'/course/renderer.php');
+
+/**
+ * The renderer for the topics course format
+ */
+class format_topics_renderer extends core_course_generic_format_renderer {
+    
+    /**
+     * Generates the controls for editing a section.
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The current section
+     * @param int $sectionnum The literal number of the section, the first section being 0
+     * @return string
+     */
+    public function section_editing_controls($course, $section, $sectionnum) {
+
+        $baseurl = new moodle_url('/course/view.php', array('id'=>$course->id, 'sesskey'=>sesskey()));
+        $baseurl->set_anchor('section-'.$sectionnum);
+
+        $strtopichide = get_string('hidetopicfromothers');
+        $strtopicshow = get_string('showtopicfromothers');
+        $strmarkthistopic = get_string('markthistopic');
+        $strmarkedthistopic = get_string('markedthistopic');
+        $strmoveup   = get_string('moveup');
+        $strmovedown = get_string('movedown');
+
+        $output = '';
+
+        // Show the "light globe" on/off
+        if ($course->marker == $sectionnum) {
+            $url = new moodle_url($baseurl, array('marker'=>0));
+            $icon = new pix_icon('i/marked', $strmarkedthistopic, 'moodle', array('class'=>'icon'));
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon), array('class'=>'sectioncommand'));
+        } else {
+            $url = new moodle_url($baseurl, array('marker'=>$sectionnum));
+            $icon = new pix_icon('i/marker', $strmarkthistopic, 'moodle', array('class'=>'icon'));
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon), array('class'=>'sectioncommand'));
+        }
+
+        // Show the hide/show eye
+        if ($section->visible) {
+            $url = new moodle_url($baseurl, array('hide'=>$sectionnum));
+            $icon = new pix_icon('i/hide', $strtopichide, 'moodle', array('class'=>'icon hide'));
+            $attributes = array('title'=>$strtopichide);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        } else {
+            $url = new moodle_url($baseurl, array('show'=>$sectionnum));
+            $icon = new pix_icon('i/show', $strtopicshow, 'moodle', array('class'=>'icon show'));
+            $attributes = array('title'=>$strtopicshow);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        }
+
+        // Add a arrow to move section up
+        if ($sectionnum > 1) {
+            $url = new moodle_url($baseurl, array('section'=>$sectionnum, 'move'=>'-1', 'random'=>rand(1,10000)));
+            $url->set_anchor('section-'.($sectionnum-1));
+            $icon = new pix_icon('t/up', $strmoveup, 'moodle', array('class'=>'icon up'));
+            $attributes = array('title'=>$strmoveup);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        }
+
+        // Add a arrow to move section down
+        if ($sectionnum < $course->numsections) {
+            $url = new moodle_url($baseurl, array('section'=>$sectionnum, 'move'=>'1', 'random'=>rand(1,10000)));
+            $url->set_anchor('section-'.($sectionnum+1));
+            $icon = new pix_icon('t/down', $strmovedown, 'moodle', array('class'=>'icon down'));
+            $attributes = array('title'=>$strmovedown);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        }
+
+        return $output;
+    }
+    
+    /**
+     * Gets HTML to display zoom in or zoom out for the section.
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The current section
+     * @param int $currentsection The literal number of the section, the first section being 0
+     * @return type 
+     */
+    public function section_zoom_link($course, $section, $currentsection) {
+        $output = '';
+        if ($currentsection == $section) {    // Show the zoom boxes
+            $strshowalltopics = get_string('showalltopics');
+            
+            $url = new moodle_url('/course/view.php', array('id'=>$course->id, 'topic'=>'0'));
+            $url->set_anchor('section-'.($section));
+            $icon = new pix_icon('i/all', $strshowalltopics, 'moodle', array('class'=>'icon'));
+            $attributes = array('title'=>$strshowalltopics);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand zoom'));
+        } else {
+            $strshowonlytopic = get_string("showonlytopic", "", $section);
+            
+            $url = new moodle_url('/course/view.php', array('id'=>$course->id, 'topic'=>$section));
+            $icon = new pix_icon('i/one', $strshowonlytopic, 'moodle', array('class'=>'icon'));
+            $attributes = array('title'=>$strshowonlytopic);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand zoom'));
+        }
+        return $output;
+    }
+
+}
\ No newline at end of file
diff --git a/course/format/weeks/format.php b/course/format/weeks/format.php
index 9b9886a..665d246 100644
--- a/course/format/weeks/format.php
+++ b/course/format/weeks/format.php
@@ -41,21 +41,8 @@ defined('MOODLE_INTERNAL') || die();
         }
     }
 
-    $streditsummary  = get_string('editsummary');
-    $stradd          = get_string('add');
-    $stractivities   = get_string('activities');
-    $strshowallweeks = get_string('showallweeks');
-    $strweek         = get_string('week');
-    $strgroups       = get_string('groups');
-    $strgroupmy      = get_string('groupmy');
-    $editing         = $PAGE->user_is_editing();
-
-    if ($editing) {
-        $strweekhide = get_string('hideweekfromothers');
-        $strweekshow = get_string('showweekfromothers');
-        $strmoveup   = get_string('moveup');
-        $strmovedown = get_string('movedown');
-    }
+$isediting  = $PAGE->user_is_editing();
+$renderer   = $PAGE->get_renderer('format_weeks');
 
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
@@ -65,17 +52,17 @@ defined('MOODLE_INTERNAL') || die();
 
     echo $OUTPUT->heading(get_string('weeklyoutline'), 2, 'headingblock header outline');
 
-    echo "<span id='maincontent'></span>";
     // Note, an ordered list would confuse - "1" could be the clipboard or summary.
-    echo "<ul class='weeks'>\n";
+echo html_writer::start_tag('ul', array('class'=>'weeks'));
 
 /// If currently moving a file then show the current clipboard
     if (ismoving($course->id)) {
         $stractivityclipboard = strip_tags(get_string('activityclipboard', '', $USER->activitycopyname));
         $strcancel= get_string('cancel');
-        echo '<li class="clipboard">';
+    
+    echo html_writer::start_tag('li', array('class'=>'clipboard'));
         echo $stractivityclipboard.'&nbsp;&nbsp;(<a href="mod.php?cancelcopy=true&amp;sesskey='.sesskey().'">'.$strcancel.'</a>)';
-        echo "</li>\n";
+    echo html_writer::end_tag('li');
     }
 
 /// Print Section 0 with general activities
@@ -84,47 +71,12 @@ defined('MOODLE_INTERNAL') || die();
     $thissection = $sections[$section];
     unset($sections[0]);
 
-    if ($thissection->summary or $thissection->sequence or $PAGE->user_is_editing()) {
-
-        // Note, 'right side' is BEFORE content.
-        echo '<li id="section-0" class="section main clearfix" >';
-        echo '<div class="left side">&nbsp;</div>';
-        echo '<div class="right side" >&nbsp;</div>';
-        echo '<div class="content">';
-
-        if (!empty($thissection->name)) {
-            echo $OUTPUT->heading($thissection->name, 3, 'sectionname');
-        }
-
-        echo '<div class="summary">';
-
-        $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-        $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
-        $summaryformatoptions = new stdClass;
-        $summaryformatoptions->noclean = true;
-        $summaryformatoptions->overflowdiv = true;
-        echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
-
-        if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
-            echo '<p><a title="'.$streditsummary.'" '.
-                 ' href="editsection.php?id='.$thissection->id.'"><img src="'.$OUTPUT->pix_url('t/edit') . '" '.
-                 ' class="icon edit" alt="'.$streditsummary.'" /></a></p>';
+if ($thissection->summary or $thissection->sequence or $isediting) {
+    echo $renderer->initial_section($course, $thissection, $mods, $modnames);
         }
-        echo '</div>';
-
-        print_section($course, $thissection, $mods, $modnamesused);
-
-        if ($PAGE->user_is_editing()) {
-            print_section_add_menus($course, $section, $modnames);
-        }
-
-        echo '</div>';
-        echo "</li>\n";
-    }
-
 
-/// Now all the normal modules by week
-/// Everything below uses "section" terminology - each "section" is a week.
+// Now all the normal modules by week
+// Everything below uses "section" terminology - each "section" is a week.
 
     $timenow = time();
     $weekdate = $course->startdate;    // this should be 0:00 Monday of that week
@@ -136,6 +88,9 @@ defined('MOODLE_INTERNAL') || die();
 
     $strftimedateshort = ' '.get_string('strftimedateshort');
 
+$canviewhiddensections = has_capability('moodle/course:viewhiddensections', $context);
+$canupdatecourse = has_capability('moodle/course:update', $context);
+
     while ($weekdate < $course->enddate) {
 
         $nextweekdate = $weekdate + ($weekofseconds);
@@ -156,7 +111,7 @@ defined('MOODLE_INTERNAL') || die();
             $thissection->id = $DB->insert_record('course_sections', $thissection);
         }
 
-        $showsection = (has_capability('moodle/course:viewhiddensections', $context) or $thissection->visible or !$course->hiddensections);
+    $showsection = ($canviewhiddensections or $thissection->visible or !$course->hiddensections);
 
         if (!empty($displaysection) and $displaysection != $section) {  // Check this week is visible
             if ($showsection) {
@@ -169,89 +124,48 @@ defined('MOODLE_INTERNAL') || die();
 
         if ($showsection) {
 
-            $currentweek = (($weekdate <= $timenow) && ($timenow < $nextweekdate));
+        $content = '';
+        $leftside = '';
+        $rightside = '';
+        $attributes = array('id'=>'section-'.$section, 'class'=>'section main clearfix');
 
+        $currentweek = (($weekdate <= $timenow) && ($timenow < $nextweekdate));
+        $weekperiod = $weekday.' - '.$endweekday;
             $currenttext = '';
+        
             if (!$thissection->visible) {
-                $sectionstyle = ' hidden';
+            $attributes['class'] .= ' hidden';
             } else if ($currentweek) {
-                $sectionstyle = ' current';
+            $attributes['class'] .= ' current';
                 $currenttext = get_accesshide(get_string('currentweek','access'));
-            } else {
-                $sectionstyle = '';
             }
 
-            echo '<li id="section-'.$section.'" class="section main clearfix'.$sectionstyle.'" >';
-
-            echo '<div class="left side">&nbsp;'.$currenttext.'</div>';
+        $leftside .= '&nbsp;'.$currenttext;
 
-            // Note, 'right side' is BEFORE content.
-            echo '<div class="right side">';
-
-            if ($displaysection == $section) {
-                echo '<a href="view.php?id='.$course->id.'&amp;week=0#section-'.$section.'" title="'.$strshowallweeks.'">'.
-                     '<img src="'.$OUTPUT->pix_url('i/all') . '" class="icon wkall" alt="'.$strshowallweeks.'" /></a><br />';
-            } else {
-                $strshowonlyweek = get_string("showonlyweek", "", $section);
-                echo '<a href="view.php?id='.$course->id.'&amp;week='.$section.'" title="'.$strshowonlyweek.'">'.
-                     '<img src="'.$OUTPUT->pix_url('i/one') . '" class="icon wkone" alt="'.$strshowonlyweek.'" /></a><br />';
+        $rightside .= $renderer->section_zoom_link($course, $section, $displaysection);
+        if ($isediting && $canupdatecourse) {
+            $rightside .= $renderer->section_editing_controls($course, $thissection, $section);
             }
 
-            if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                if ($thissection->visible) {        // Show the hide/show eye
-                    echo '<a href="view.php?id='.$course->id.'&amp;hide='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strweekhide.'">'.
-                         '<img src="'.$OUTPUT->pix_url('i/hide') . '" class="icon hide" alt="'.$strweekhide.'" /></a><br />';
+        if (!$canviewhiddensections and !$thissection->visible) {   // Hidden for students
+            $content .= $OUTPUT->heading($currenttext.$weekperiod.' ('.get_string('notavailable').')', 3, 'weekdates');
                 } else {
-                    echo '<a href="view.php?id='.$course->id.'&amp;show='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strweekshow.'">'.
-                         '<img src="'.$OUTPUT->pix_url('i/show') . '" class="icon hide" alt="'.$strweekshow.'" /></a><br />';
-                }
-                if ($section > 1) {                       // Add a arrow to move section up
-                    echo '<a href="view.php?id='.$course->id.'&amp;random='.rand(1,10000).'&amp;section='.$section.'&amp;move=-1&amp;sesskey='.sesskey().'#section-'.($section-1).'" title="'.$strmoveup.'">'.
-                         '<img src="'.$OUTPUT->pix_url('t/up') . '" class="icon up" alt="'.$strmoveup.'" /></a><br />';
-                }
-
-                if ($section < $course->numsections) {    // Add a arrow to move section down
-                    echo '<a href="view.php?id='.$course->id.'&amp;random='.rand(1,10000).'&amp;section='.$section.'&amp;move=1&amp;sesskey='.sesskey().'#section-'.($section+1).'" title="'.$strmovedown.'">'.
-                         '<img src="'.$OUTPUT->pix_url('t/down') . '" class="icon down" alt="'.$strmovedown.'" /></a><br />';
-                }
-            }
-            echo '</div>';
-
-            $weekperiod = $weekday.' - '.$endweekday;
-
-            echo '<div class="content">';
-            if (!has_capability('moodle/course:viewhiddensections', $context) and !$thissection->visible) {   // Hidden for students
-                echo $OUTPUT->heading($currenttext.$weekperiod.' ('.get_string('notavailable').')', 3, 'weekdates');
-
-            } else {
                 if (isset($thissection->name) && ($thissection->name !== NULL)) {  // empty string is ok
-                    echo $OUTPUT->heading($thissection->name, 3, 'weekdates');
+                $content .= $OUTPUT->heading($thissection->name, 3, 'weekdates');
                 } else {
-                    echo $OUTPUT->heading($currenttext.$weekperiod, 3, 'weekdates');
-                }
-                echo '<div class="summary">';
-                $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-                $summarytext = file_rewrite_pluginfile_urls($thissection->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $thissection->id);
-                $summaryformatoptions = new stdClass;
-                $summaryformatoptions->noclean = true;
-                $summaryformatoptions->overflowdiv = true;
-                echo format_text($summarytext, $thissection->summaryformat, $summaryformatoptions);
-
-                if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                    echo ' <a title="'.$streditsummary.'" href="editsection.php?id='.$thissection->id.'">'.
-                         '<img src="'.$OUTPUT->pix_url('t/edit') . '" class="icon edit" alt="'.$streditsummary.'" /></a><br /><br />';
+                $content .= $OUTPUT->heading($currenttext.$weekperiod, 3, 'weekdates');
                 }
-                echo '</div>';
 
-                print_section($course, $thissection, $mods, $modnamesused);
+            $content .= $renderer->section_summary($thissection, $context);
+            $content .= $renderer->section($course, $thissection, $mods);
 
-                if ($PAGE->user_is_editing()) {
-                    print_section_add_menus($course, $section, $modnames);
+            if ($isediting) {
+                $content .= $renderer->section_add_menus($course, $section, $modnames);
                 }
             }
 
-            echo '</div>';
-            echo "</li>\n";
+        
+        echo $renderer->section_structure($content, $leftside, $rightside, $attributes);
         }
 
         unset($sections[$section]);
@@ -259,7 +173,7 @@ defined('MOODLE_INTERNAL') || die();
         $weekdate = $nextweekdate;
     }
 
-    if (!$displaysection and $PAGE->user_is_editing() and has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
+if (!$displaysection and $isediting and $canupdatecourse) {
         // print stealth sections if present
         $modinfo = get_fast_modinfo($course);
         foreach ($sections as $section=>$thissection) {
@@ -267,27 +181,18 @@ defined('MOODLE_INTERNAL') || die();
                 continue;
             }
 
-            echo '<li id="section-'.$section.'" class="section main clearfix stealth hidden">'; //'<div class="left side">&nbsp;</div>';
-
-            echo '<div class="left side">';
-            echo '</div>';
-            // Note, 'right side' is BEFORE content.
-            echo '<div class="right side">';
-            echo '</div>';
-            echo '<div class="content">';
-            echo $OUTPUT->heading(get_string('orphanedactivities'), 3, 'sectionname');
-            print_section($course, $thissection, $mods, $modnamesused);
-            echo '</div>';
-            echo "</li>\n";
+        $content  = $OUTPUT->heading(get_string('orphanedactivities'), 3, 'sectionname');
+        $content .= $renderer->section($course, $thissection, $mods);
+        $leftside = '';
+        $rightside = '';
+        $attributes = array('id'=>'section-'.$section, 'class'=>'section main clearfix stealth hidden');
+
+        echo $renderer->section_structure($content, $leftside, $rightside, $attributes);
         }
     }
 
-    echo "</ul>\n";
+echo html_writer::end_tag('ul'); // .weeks
 
     if (!empty($sectionmenu)) {
-        $select = new single_select(new moodle_url('/course/view.php', array('id'=>$course->id)), 'week', $sectionmenu);
-        $select->label = get_string('jumpto');
-        $select->class = 'jumpmenu';
-        $select->formid = 'sectionmenu';
-        echo $OUTPUT->render($select);
+    echo $renderer->section_jumpto_menu($course->id, $sectionmenu, 'weeks');
     }
diff --git a/course/format/weeks/renderer.php b/course/format/weeks/renderer.php
new file mode 100644
index 0000000..db4319a
--- /dev/null
+++ b/course/format/weeks/renderer.php
@@ -0,0 +1,120 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This is the renderer for the weeks course format.
+ * 
+ * It extends and builds upon the generic format renderer.
+ *
+ * @package   moodlecore
+ * @copyright 2010 Sam Hemelryk
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Make sure we have included the generic format renderer.
+ */
+require_once($CFG->dirroot.'/course/renderer.php');
+
+/**
+ * The renderer for the weeks course format.
+ */
+class format_weeks_renderer extends core_course_generic_format_renderer {
+
+    /**
+     * Generates the controls for editing a section.
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The current section
+     * @param int $sectionnum The literal number of the section, the first section being 0
+     * @return string
+     */
+    public function section_editing_controls($course, $section, $sectionnum) {
+
+        $baseurl = new moodle_url('/course/view.php', array('id'=>$course->id, 'sesskey'=>sesskey()));
+        $baseurl->set_anchor('section-'.$sectionnum);
+
+        $strweekhide = get_string('hideweekfromothers');
+        $strweekshow = get_string('showweekfromothers');
+        $strmoveup   = get_string('moveup');
+        $strmovedown = get_string('movedown');
+
+        $output = '';
+
+        // Show the hide/show eye
+        if ($section->visible) {
+            $url = new moodle_url($baseurl, array('hide'=>$sectionnum));
+            $icon = new pix_icon('i/hide', $strweekhide, 'moodle', array('class'=>'icon hide'));
+            $attributes = array('title'=>$strweekhide);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        } else {
+            $url = new moodle_url($baseurl, array('show'=>$sectionnum));
+            $icon = new pix_icon('i/show', $strweekshow, 'moodle', array('class'=>'icon show'));
+            $attributes = array('title'=>$strweekshow);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        }
+
+        // Add a arrow to move section up
+        if ($sectionnum > 1) {
+            $url = new moodle_url($baseurl, array('section'=>$sectionnum, 'move'=>'-1', 'random'=>rand(1,10000)));
+            $url->set_anchor('section-'.($sectionnum-1));
+            $icon = new pix_icon('t/up', $strmoveup, 'moodle', array('class'=>'icon up'));
+            $attributes = array('title'=>$strmoveup);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        }
+
+        // Add a arrow to move section down
+        if ($sectionnum < $course->numsections) {
+            $url = new moodle_url($baseurl, array('section'=>$sectionnum, 'move'=>'1', 'random'=>rand(1,10000)));
+            $url->set_anchor('section-'.($sectionnum+1));
+            $icon = new pix_icon('t/down', $strmovedown, 'moodle', array('class'=>'icon down'));
+            $attributes = array('title'=>$strmovedown);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand'));
+        }
+
+        return $output;
+    }
+    
+    /**
+     * Gets HTML to display zoom in or zoom out for the section.
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The current section
+     * @param int $currentsection The literal number of the section, the first section being 0
+     * @return type 
+     */
+    public function section_zoom_link($course, $section, $currentsection) {
+        $output = '';
+        if ($currentsection == $section) {    // Show the zoom boxes
+            $strshowallweeks = get_string('showallweeks');
+            
+            $url = new moodle_url('/course/view.php', array('id'=>$course->id, 'week'=>'0'));
+            $url->set_anchor('section-'.($section));
+            $icon = new pix_icon('i/all', $strshowallweeks, 'moodle', array('class'=>'icon'));
+            $attributes = array('title'=>$strshowallweeks);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand zoom'));
+        } else {
+            $strshowonlyweek = get_string("showonlyweek", "", $section);
+            
+            $url = new moodle_url('/course/view.php', array('id'=>$course->id, 'week'=>$section));
+            $icon = new pix_icon('i/one', $strshowonlyweek, 'moodle', array('class'=>'icon'));
+            $attributes = array('title'=>$strshowonlyweek);
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, $attributes), array('class'=>'sectioncommand zoom'));
+        }
+        return $output;
+    }
+
+}
\ No newline at end of file
diff --git a/course/lib.php b/course/lib.php
index a28be6d..89f4882 100644
--- a/course/lib.php
+++ b/course/lib.php
@@ -1252,460 +1252,53 @@ function set_section_visible($courseid, $sectionnumber, $visibility) {
 
 /**
  * Prints a section full of activity modules
+ * 
+ * @deprecated since 2.0
+ *
+ * @global moodle_page $PAGE
+ * @param stdClass $course
+ * @param stdClass $section
+ * @param array $mods
+ * @param array $modnamesused No longer needed
+ * @param bool $absolute No longer used
+ * @param int $width No longer used
+ * @param bool $hidecompletion 
  */
 function print_section($course, $section, $mods, $modnamesused, $absolute=false, $width="100%", $hidecompletion=false) {
-    global $CFG, $USER, $DB, $PAGE, $OUTPUT;
-
-    static $initialised;
+    global $PAGE;
 
-    static $groupbuttons;
-    static $groupbuttonslink;
-    static $isediting;
-    static $ismoving;
-    static $strmovehere;
-    static $strmovefull;
-    static $strunreadpostsone;
-    static $usetracking;
-    static $groupings;
+    $options = new stdClass;
+    $options->absolute = $absolute;
+    $options->hidecompletion = $hidecompletion;
+    $options->modnamesused = $modnamesused;
 
-    if (!isset($initialised)) {
-        $groupbuttons     = ($course->groupmode or (!$course->groupmodeforce));
-        $groupbuttonslink = (!$course->groupmodeforce);
-        $isediting        = $PAGE->user_is_editing();
-        $ismoving         = $isediting && ismoving($course->id);
-        if ($ismoving) {
-            $strmovehere  = get_string("movehere");
-            $strmovefull  = strip_tags(get_string("movefull", "", "'$USER->activitycopyname'"));
-        }
-        include_once($CFG->dirroot.'/mod/forum/lib.php');
-        if ($usetracking = forum_tp_can_track_forums()) {
-            $strunreadpostsone = get_string('unreadpostsone', 'forum');
+    $renderer = $PAGE->get_renderer('core_course', 'generic_format');
+    echo $renderer->section($course, $section, $mods, $options);
         }
-        $initialised = true;
-    }
-
-    $labelformatoptions = new stdClass();
-    $labelformatoptions->noclean = true;
-    $labelformatoptions->overflowdiv = true;
-
-/// Casting $course->modinfo to string prevents one notice when the field is null
-    $modinfo = get_fast_modinfo($course);
-    $completioninfo = new completion_info($course);
-
-    //Accessibility: replace table with list <ul>, but don't output empty list.
-    if (!empty($section->sequence)) {
-
-        // Fix bug #5027, don't want style=\"width:$width\".
-        echo "<ul class=\"section img-text\">\n";
-        $sectionmods = explode(",", $section->sequence);
-
-        foreach ($sectionmods as $modnumber) {
-            if (empty($mods[$modnumber])) {
-                continue;
-            }
-
-            $mod = $mods[$modnumber];
-
-            if ($ismoving and $mod->id == $USER->activitycopy) {
-                // do not display moving mod
-                continue;
-            }
-
-            if (isset($modinfo->cms[$modnumber])) {
-                // We can continue (because it will not be displayed at all)
-                // if:
-                // 1) The activity is not visible to users
-                // and
-                // 2a) The 'showavailability' option is not set (if that is set,
-                //     we need to display the activity so we can show
-                //     availability info)
-                // or
-                // 2b) The 'availableinfo' is empty, i.e. the activity was
-                //     hidden in a way that leaves no info, such as using the
-                //     eye icon.
-                if (!$modinfo->cms[$modnumber]->uservisible &&
-                    (empty($modinfo->cms[$modnumber]->showavailability) ||
-                      empty($modinfo->cms[$modnumber]->availableinfo))) {
-                    // visibility shortcut
-                    continue;
-                }
-            } else {
-                if (!file_exists("$CFG->dirroot/mod/$mod->modname/lib.php")) {
-                    // module not installed
-                    continue;
-                }
-                if (!coursemodule_visible_for_user($mod) &&
-                    empty($mod->showavailability)) {
-                    // full visibility check
-                    continue;
-                }
-            }
-
-            // In some cases the activity is visible to user, but it is
-            // dimmed. This is done if viewhiddenactivities is true and if:
-            // 1. the activity is not visible, or
-            // 2. the activity has dates set which do not include current, or
-            // 3. the activity has any other conditions set (regardless of whether
-            //    current user meets them)
-            $canviewhidden = has_capability(
-                'moodle/course:viewhiddenactivities',
-                get_context_instance(CONTEXT_MODULE, $mod->id));
-            $accessiblebutdim = false;
-            if ($canviewhidden) {
-                $accessiblebutdim = !$mod->visible;
-                if (!empty($CFG->enableavailability)) {
-                    $accessiblebutdim = $accessiblebutdim ||
-                        $mod->availablefrom > time() ||
-                        ($mod->availableuntil && $mod->availableuntil < time()) ||
-                        count($mod->conditionsgrade) > 0 ||
-                        count($mod->conditionscompletion) > 0;
-                }
-            }
-
-            $liclasses = array();
-            $liclasses[] = 'activity';
-            $liclasses[] = $mod->modname;
-            $liclasses[] = 'modtype_'.$mod->modname;
-            echo html_writer::start_tag('li', array('class'=>join(' ', $liclasses), 'id'=>'module-'.$modnumber));
-            if ($ismoving) {
-                echo '<a title="'.$strmovefull.'"'.
-                     ' href="'.$CFG->wwwroot.'/course/mod.php?moveto='.$mod->id.'&amp;sesskey='.sesskey().'">'.
-                     '<img class="movetarget" src="'.$OUTPUT->pix_url('movehere') . '" '.
-                     ' alt="'.$strmovehere.'" /></a><br />
-                     ';
-            }
-
-            $classes = array('mod-indent');
-            if (!empty($mod->indent)) {
-                $classes[] = 'mod-indent-'.$mod->indent;
-                if ($mod->indent > 15) {
-                    $classes[] = 'mod-indent-huge';
-                }
-            }
-            echo html_writer::start_tag('div', array('class'=>join(' ', $classes)));
-
-            $extra = '';
-            if (!empty($modinfo->cms[$modnumber]->extra)) {
-                $extra = $modinfo->cms[$modnumber]->extra;
-            }
-
-            if ($mod->modname == "label") {
-                if ($accessiblebutdim || !$mod->uservisible) {
-                    echo '<div class="dimmed_text"><span class="accesshide">'.
-                        get_string('hiddenfromstudents').'</span>';
-                } else {
-                    echo '<div>';
-                }
-                echo format_text($extra, FORMAT_HTML, $labelformatoptions);
-                echo "</div>";
-                if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                    if (!isset($groupings)) {
-                        $groupings = groups_get_all_groupings($course->id);
-                    }
-                    echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
-                }
-
-            } else { // Normal activity
-                $instancename = format_string($modinfo->cms[$modnumber]->name, true,  $course->id);
-
-                $customicon = $modinfo->cms[$modnumber]->icon;
-                if (!empty($customicon)) {
-                    if (substr($customicon, 0, 4) === 'mod/') {
-                        list($modname, $iconname) = explode('/', substr($customicon, 4), 2);
-                        $icon = $OUTPUT->pix_url($iconname, $modname);
-                    } else {
-                        $icon = $OUTPUT->pix_url($customicon);
-                    }
-                } else {
-                    $icon = $OUTPUT->pix_url('icon', $mod->modname);
-                }
-
-                //Accessibility: for files get description via icon, this is very ugly hack!
-                $altname = '';
-                $altname = $mod->modfullname;
-                if (!empty($customicon)) {
-                    $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
-                    if ($archetype == MOD_ARCHETYPE_RESOURCE) {
-                        $mimetype = mimeinfo_from_icon('type', $customicon);
-                        $altname = get_mimetype_description($mimetype);
-                    }
-                }
-                // Avoid unnecessary duplication.
-                if (false !== stripos($instancename, $altname)) {
-                    $altname = '';
-                }
-                // File type after name, for alphabetic lists (screen reader).
-                if ($altname) {
-                    $altname = get_accesshide(' '.$altname);
-                }
-
-                // We may be displaying this just in order to show information
-                // about visibility, without the actual link
-                if ($mod->uservisible) {
-                    // Display normal module link
-                    if (!$accessiblebutdim) {
-                        $linkcss = '';
-                        $accesstext  ='';
-                    } else {
-                        $linkcss = ' class="dimmed" ';
-                        $accesstext = '<span class="accesshide">'.
-                            get_string('hiddenfromstudents').': </span>';
-                    }
-
-                    echo '<a '.$linkcss.' '.$extra.
-                         ' href="'.$CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$mod->id.'">'.
-                         '<img src="'.$icon.'" class="activityicon" alt="'.get_string('modulename',$mod->modname).'" /> '.
-                         $accesstext.'<span class="instancename">'.$instancename.$altname.'</span></a>';
-
-                    if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
-                        if (!isset($groupings)) {
-                            $groupings = groups_get_all_groupings($course->id);
-                        }
-                        echo " <span class=\"groupinglabel\">(".format_string($groupings[$mod->groupingid]->name).')</span>';
-                    }
-                } else {
-                    // Display greyed-out text of link
-                    echo '<span class="dimmed_text" '.$extra.' ><span class="accesshide">'.
-                        get_string('notavailableyet','condition').': </span>'.
-                        '<img src="'.$icon.'" class="activityicon" alt="'.get_string('modulename', $mod->modname).'" /> <span>'.
-                        $instancename.$altname.'</span></span>';
-                }
-            }
-            if ($usetracking && $mod->modname == 'forum') {
-                if ($unread = forum_tp_count_forum_unread_posts($mod, $course)) {
-                    echo '<span class="unread"> <a href="'.$CFG->wwwroot.'/mod/forum/view.php?id='.$mod->id.'">';
-                    if ($unread == 1) {
-                        echo $strunreadpostsone;
-                    } else {
-                        print_string('unreadpostsnumber', 'forum', $unread);
-                    }
-                    echo '</a></span>';
-                }
-            }
-
-            if ($isediting) {
-                if ($groupbuttons and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
-                    if (! $mod->groupmodelink = $groupbuttonslink) {
-                        $mod->groupmode = $course->groupmode;
-                    }
-
-                } else {
-                    $mod->groupmode = false;
-                }
-                echo '&nbsp;&nbsp;';
-                echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section);
-            }
-
-            // Completion
-            $completion = $hidecompletion
-                ? COMPLETION_TRACKING_NONE
-                : $completioninfo->is_enabled($mod);
-            if ($completion!=COMPLETION_TRACKING_NONE && isloggedin() &&
-                !isguestuser() && $mod->uservisible) {
-                $completiondata = $completioninfo->get_data($mod,true);
-                $completionicon = '';
-                if ($isediting) {
-                    switch ($completion) {
-                        case COMPLETION_TRACKING_MANUAL :
-                            $completionicon = 'manual-enabled'; break;
-                        case COMPLETION_TRACKING_AUTOMATIC :
-                            $completionicon = 'auto-enabled'; break;
-                        default: // wtf
-                    }
-                } else if ($completion==COMPLETION_TRACKING_MANUAL) {
-                    switch($completiondata->completionstate) {
-                        case COMPLETION_INCOMPLETE:
-                            $completionicon = 'manual-n'; break;
-                        case COMPLETION_COMPLETE:
-                            $completionicon = 'manual-y'; break;
-                    }
-                } else { // Automatic
-                    switch($completiondata->completionstate) {
-                        case COMPLETION_INCOMPLETE:
-                            $completionicon = 'auto-n'; break;
-                        case COMPLETION_COMPLETE:
-                            $completionicon = 'auto-y'; break;
-                        case COMPLETION_COMPLETE_PASS:
-                            $completionicon = 'auto-pass'; break;
-                        case COMPLETION_COMPLETE_FAIL:
-                            $completionicon = 'auto-fail'; break;
-                    }
-                }
-                if ($completionicon) {
-                    $imgsrc = $OUTPUT->pix_url('i/completion-'.$completionicon);
-                    $imgalt = s(get_string('completion-alt-'.$completionicon, 'completion'));
-                    if ($completion == COMPLETION_TRACKING_MANUAL && !$isediting) {
-                        $imgtitle = s(get_string('completion-title-'.$completionicon, 'completion'));
-                        $newstate =
-                            $completiondata->completionstate==COMPLETION_COMPLETE
-                            ? COMPLETION_INCOMPLETE
-                            : COMPLETION_COMPLETE;
-                        // In manual mode the icon is a toggle form...
-
-                        // If this completion state is used by the
-                        // conditional activities system, we need to turn
-                        // off the JS.
-                        if (!empty($CFG->enableavailability) &&
-                            condition_info::completion_value_used_as_condition($course, $mod)) {
-                            $extraclass = ' preventjs';
-                        } else {
-                            $extraclass = '';
-                        }
-                        echo "
-<form class='togglecompletion$extraclass' method='post' action='togglecompletion.php'><div>
-<input type='hidden' name='id' value='{$mod->id}' />
-<input type='hidden' name='sesskey' value='".sesskey()."' />
-<input type='hidden' name='completionstate' value='$newstate' />
-<input type='image' src='$imgsrc' alt='$imgalt' title='$imgtitle' />
-</div></form>";
-                    } else {
-                        // In auto mode, or when editing, the icon is just an image
-                        echo "<span class='autocompletion'>";
-                        echo "<img src='$imgsrc' alt='$imgalt' title='$imgalt' /></span>";
-                    }
-                }
-            }
-
-            // Show availability information (for someone who isn't allowed to
-            // see the activity itself, or for staff)
-            if (!$mod->uservisible) {
-                echo '<div class="availabilityinfo">'.$mod->availableinfo.'</div>';
-            } else if ($canviewhidden && !empty($CFG->enableavailability)) {
-                $ci = new condition_info($mod);
-                $fullinfo = $ci->get_full_information();
-                if($fullinfo) {
-                    echo '<div class="availabilityinfo">'.get_string($mod->showavailability
-                        ? 'userrestriction_visible'
-                        : 'userrestriction_hidden','condition',
-                        $fullinfo).'</div>';
-                }
-            }
-
-            echo html_writer::end_tag('div');
-            echo html_writer::end_tag('li')."\n";
-        }
-
-    } elseif ($ismoving) {
-        echo "<ul class=\"section\">\n";
-    }
-
-    if ($ismoving) {
-        echo '<li><a title="'.$strmovefull.'"'.
-             ' href="'.$CFG->wwwroot.'/course/mod.php?movetosection='.$section->id.'&amp;sesskey='.sesskey().'">'.
-             '<img class="movetarget" src="'.$OUTPUT->pix_url('movehere') . '" '.
-             ' alt="'.$strmovehere.'" /></a></li>
-             ';
-    }
-    if (!empty($section->sequence) || $ismoving) {
-        echo "</ul><!--class='section'-->\n\n";
-    }
-}
 
 /**
  * Prints the menus to add activities and resources.
+ * 
+ * @deprecated since 2.0
+ *
+ * @global moodle_page $PAGE
+ * @param stdClass $course
+ * @param stdClass $section
+ * @param array $modnames
+ * @param bool $vertical
+ * @param bool $return No longer used
+ * @return string 
  */
 function print_section_add_menus($course, $section, $modnames, $vertical=false, $return=false) {
-    global $CFG, $OUTPUT;
-
-    // check to see if user can add menus
-    if (!has_capability('moodle/course:manageactivities', get_context_instance(CONTEXT_COURSE, $course->id))) {
-        return false;
-    }
-
-    $urlbase = "/course/mod.php?id=$course->id&section=$section&sesskey=".sesskey().'&add=';
-
-    $resources = array();
-    $activities = array();
-
-    foreach($modnames as $modname=>$modnamestr) {
-        if (!course_allowed_module($course, $modname)) {
-            continue;
-        }
-
-        $libfile = "$CFG->dirroot/mod/$modname/lib.php";
-        if (!file_exists($libfile)) {
-            continue;
-        }
-        include_once($libfile);
-        $gettypesfunc =  $modname.'_get_types';
-        if (function_exists($gettypesfunc)) {
-            // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
-            if ($types = $gettypesfunc()) {
-                $menu = array();
-                $atype = null;
-                $groupname = null;
-                foreach($types as $type) {
-                    if ($type->typestr === '--') {
-                        continue;
-                    }
-                    if (strpos($type->typestr, '--') === 0) {
-                        $groupname = str_replace('--', '', $type->typestr);
-                        continue;
-                    }
-                    $type->type = str_replace('&amp;', '&', $type->type);
-                    if ($type->modclass == MOD_CLASS_RESOURCE) {
-                        $atype = MOD_CLASS_RESOURCE;
-                    }
-                    $menu[$urlbase.$type->type] = $type->typestr;
-                }
-                if (!is_null($groupname)) {
-                    if ($atype == MOD_CLASS_RESOURCE) {
-                        $resources[] = array($groupname=>$menu);
-                    } else {
-                        $activities[] = array($groupname=>$menu);
-                    }
-                } else {
-                    if ($atype == MOD_CLASS_RESOURCE) {
-                        $resources = array_merge($resources, $menu);
-                    } else {
-                        $activities = array_merge($activities, $menu);
-                    }
-                }
-            }
-        } else {
-            $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
-            if ($archetype == MOD_ARCHETYPE_RESOURCE) {
-                $resources[$urlbase.$modname] = $modnamestr;
-            } else {
-                // all other archetypes are considered activity
-                $activities[$urlbase.$modname] = $modnamestr;
-            }
-        }
-    }
-
-    $straddactivity = get_string('addactivity');
-    $straddresource = get_string('addresource');
-
-    $output  = '<div class="section_add_menus">';
-
-    if (!$vertical) {
-        $output .= '<div class="horizontal">';
-    }
-
-    if (!empty($resources)) {
-        $select = new url_select($resources, '', array(''=>$straddresource), "ressection$section");
-        $select->set_help_icon('resources');
-        $output .= $OUTPUT->render($select);
-    }
-
-    if (!empty($activities)) {
-        $select = new url_select($activities, '', array(''=>$straddactivity), "section$section");
-        $select->set_help_icon('activities');
-        $output .= $OUTPUT->render($select);
-    }
-
-    if (!$vertical) {
-        $output .= '</div>';
-    }
-
-    $output .= '</div>';
+    global $PAGE;
 
+    $renderer = $PAGE->get_renderer('core_course', 'generic_format');
+    $output = $renderer->section_add_menus($course, $section, $modnames, array('vertical'=>$vertical));
     if ($return) {
         return $output;
-    } else {
+    }
         echo $output;
     }
-}
 
 /**
  * Return the course category context for the category with id $categoryid, except
@@ -2907,158 +2500,26 @@ function moveto_module($mod, $section, $beforemod=NULL) {
     return true;
 }
 
+/**
+ * Generates controls to edit a module.
+ * 
+ * @deprecated since 2.0
+ *
+ * @global moodle_page $PAGE
+ * @param stdClass $mod
+ * @param bool $absolute
+ * @param int $moveselect
+ * @param int $indent
+ * @param int $section
+ * @return string
+ */
 function make_editing_buttons($mod, $absolute=false, $moveselect=true, $indent=-1, $section=-1) {
-    global $CFG, $USER, $DB, $OUTPUT;
-
-    static $str;
-    static $sesskey;
-
-    $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
-    // no permission to edit
-    if (!has_capability('moodle/course:manageactivities', $modcontext)) {
-        return false;
-    }
-
-    if (!isset($str)) {
-        $str->assign         = get_string("assignroles", 'role');
-        $str->delete         = get_string("delete");
-        $str->move           = get_string("move");
-        $str->moveup         = get_string("moveup");
-        $str->movedown       = get_string("movedown");
-        $str->moveright      = get_string("moveright");
-        $str->moveleft       = get_string("moveleft");
-        $str->update         = get_string("update");
-        $str->duplicate      = get_string("duplicate");
-        $str->hide           = get_string("hide");
-        $str->show           = get_string("show");
-        $str->clicktochange  = get_string("clicktochange");
-        $str->forcedmode     = get_string("forcedmode");
-        $str->groupsnone     = get_string("groupsnone");
-        $str->groupsseparate = get_string("groupsseparate");
-        $str->groupsvisible  = get_string("groupsvisible");
-        $sesskey = sesskey();
-    }
-
-    if ($section >= 0) {
-        $section = '&amp;sr='.$section;   // Section return
-    } else {
-        $section = '';
-    }
-
-    if ($absolute) {
-        $path = $CFG->wwwroot.'/course';
-    } else {
-        $path = '.';
-    }
-    if (has_capability('moodle/course:activityvisibility', $modcontext)) {
-        if ($mod->visible) {
-            $hideshow = '<a class="editing_hide" title="'.$str->hide.'" href="'.$path.'/mod.php?hide='.$mod->id.
-                        '&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" '.
-                        ' alt="'.$str->hide.'" /></a>'."\n";
-        } else {
-            $hideshow = '<a class="editing_show" title="'.$str->show.'" href="'.$path.'/mod.php?show='.$mod->id.
-                        '&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" '.
-                        ' alt="'.$str->show.'" /></a>'."\n";
-        }
-    } else {
-        $hideshow = '';
-    }
-
-    if ($mod->groupmode !== false) {
-        if ($mod->groupmode == SEPARATEGROUPS) {
-            $grouptitle = $str->groupsseparate;
-            $groupclass = 'editing_groupsseparate';
-            $groupimage = $OUTPUT->pix_url('t/groups') . '';
-            $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=0&amp;sesskey='.$sesskey;
-        } else if ($mod->groupmode == VISIBLEGROUPS) {
-            $grouptitle = $str->groupsvisible;
-            $groupclass = 'editing_groupsvisible';
-            $groupimage = $OUTPUT->pix_url('t/groupv') . '';
-            $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=1&amp;sesskey='.$sesskey;
-        } else {
-            $grouptitle = $str->groupsnone;
-            $groupclass = 'editing_groupsnone';
-            $groupimage = $OUTPUT->pix_url('t/groupn') . '';
-            $grouplink  = $path.'/mod.php?id='.$mod->id.'&amp;groupmode=2&amp;sesskey='.$sesskey;
-        }
-        if ($mod->groupmodelink) {
-            $groupmode = '<a class="'.$groupclass.'" title="'.$grouptitle.' ('.$str->clicktochange.')" href="'.$grouplink.'">'.
-                         '<img src="'.$groupimage.'" class="iconsmall" '.
-                         'alt="'.$grouptitle.'" /></a>';
-        } else {
-            $groupmode = '<img title="'.$grouptitle.' ('.$str->forcedmode.')" '.
-                         ' src="'.$groupimage.'" class="iconsmall" '.
-                         'alt="'.$grouptitle.'" />';
-        }
-    } else {
-        $groupmode = "";
-    }
-
-    if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
-        if ($moveselect) {
-            $move =     '<a class="editing_move" title="'.$str->move.'" href="'.$path.'/mod.php?copy='.$mod->id.
-                        '&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/move') . '" class="iconsmall" '.
-                        ' alt="'.$str->move.'" /></a>'."\n";
-        } else {
-            $move =     '<a class="editing_moveup" title="'.$str->moveup.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;move=-1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/up') . '" class="iconsmall" '.
-                        ' alt="'.$str->moveup.'" /></a>'."\n".
-                        '<a class="editing_movedown" title="'.$str->movedown.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;move=1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url('t/down') . '" class="iconsmall" '.
-                        ' alt="'.$str->movedown.'" /></a>'."\n";
-        }
-    } else {
-        $move = '';
-    }
+    global $PAGE;
 
-    $leftright = '';
-    if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
-
-        if (right_to_left()) {   // Exchange arrows on RTL
-            $rightarrow = 't/left';
-            $leftarrow  = 't/right';
-        } else {
-            $rightarrow = 't/right';
-            $leftarrow  = 't/left';
-        }
-
-        if ($indent > 0) {
-            $leftright .= '<a class="editing_moveleft" title="'.$str->moveleft.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;indent=-1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url($leftarrow).'" class="iconsmall" '.
-                        ' alt="'.$str->moveleft.'" /></a>'."\n";
-        }
-        if ($indent >= 0) {
-            $leftright .= '<a class="editing_moveright" title="'.$str->moveright.'" href="'.$path.'/mod.php?id='.$mod->id.
-                        '&amp;indent=1&amp;sesskey='.$sesskey.$section.'"><img'.
-                        ' src="'.$OUTPUT->pix_url($rightarrow).'" class="iconsmall" '.
-                        ' alt="'.$str->moveright.'" /></a>'."\n";
-        }
-    }
-    if (has_capability('moodle/course:managegroups', $modcontext)){
-        $context = get_context_instance(CONTEXT_MODULE, $mod->id);
-        $assign = '<a class="editing_assign" title="'.$str->assign.'" href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.
-            $context->id.'"><img src="'.$OUTPUT->pix_url('i/roles') . '" alt="'.$str->assign.'" class="iconsmall"/></a>';
-    } else {
-        $assign = '';
+    $renderer = $PAGE->get_renderer('core_course', 'generic_format');
+    return $renderer->section_module_controls($mod, $moveselect, $indent, $section);
     }
 
-    return '<span class="commands">'."\n".$leftright.$move.
-           '<a class="editing_update" title="'.$str->update.'" href="'.$path.'/mod.php?update='.$mod->id.
-           '&amp;sesskey='.$sesskey.$section.'"><img'.
-           ' src="'.$OUTPUT->pix_url('t/edit') . '" class="iconsmall" '.
-           ' alt="'.$str->update.'" /></a>'."\n".
-           '<a class="editing_delete" title="'.$str->delete.'" href="'.$path.'/mod.php?delete='.$mod->id.
-           '&amp;sesskey='.$sesskey.$section.'"><img'.
-           ' src="'.$OUTPUT->pix_url('t/delete') . '" class="iconsmall" '.
-           ' alt="'.$str->delete.'" /></a>'."\n".$hideshow.$groupmode."\n".$assign.'</span>';
-}
-
 /**
  * given a course object with shortname & fullname, this function will
  * truncate the the number of chars allowed and add ... if it was too long
diff --git a/course/renderer.php b/course/renderer.php
index c3d303d..4399c11 100644
--- a/course/renderer.php
+++ b/course/renderer.php
@@ -152,4 +152,820 @@ class core_course_renderer extends plugin_renderer_base {
         $content .= html_writer::end_tag('div');
         return $content;
     }
-}
\ No newline at end of file
+}
+
+/**
+ * The generic course format renderer.
+ * 
+ * This renderer is a special renderer that can be used to prepare generic elements
+ * of a course format.
+ * It can also be overridden by course format renderers so that they can customise
+ * and control the entire look of a course's frontpage.
+ * 
+ * You can instantiate this renderer with the following:
+ * $renderer = $PAGE->get_renderer('core_course', 'generic_format');
+ */
+class core_course_generic_format_renderer extends plugin_renderer_base {
+
+    /**
+     * A lifetime cache.
+     */
+    protected $courseresources = array();
+    
+    /**
+     * Generate a summary edit icon for given section
+     *
+     * @param int $sectionid The section to get an edit icon for.
+     * @param string $title The string to use as the title.
+     * @return string
+     */
+    public function section_summary_edit_icon($sectionid, $title = null) {
+        
+        if ($title == null) {
+            $title = get_string('editsummary');
+        }
+        
+        $output  = html_writer::start_tag('p');
+        $output .= html_writer::start_tag('a', array('title'=>$title, 'href'=>new moodle_url('/course/editsection.php', array('id'=>$sectionid))));
+        $output .= $this->output->pix_icon('t/edit', $title, 'moodle', array('class'=>'icon edit'));
+        $output .= html_writer::end_tag('a');
+        $output .= html_writer::end_tag('p');
+
+        return $output;
+    }
+    
+    /**
+     * Creates a jumpto menu that allows the user to jump between sections.
+     * Particually useful when zoomed in on a section.
+     *
+     * @param int $courseid The current courseid
+     * @param array $sectionoptions An array of sections to show in the menu
+     * @param mixed $format
+     * @return string
+     */
+    public function section_jumpto_menu($courseid, $sectionoptions, $format) {
+        $select = new single_select(new moodle_url('/course/view.php', array('id'=>$courseid)), $format, $sectionoptions);
+        $select->label = get_string('jumpto');
+        $select->class = 'jumpmenu';
+        $select->formid = 'sectionmenu';
+
+        return $this->output->render($select);
+    }
+    
+    /**
+     * Displays the initial section (section ) for a course.
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The section to display (section 0)
+     * @param array $mods An array of possibel modules.
+     * @param array $modnames An array of module names.
+     * @param array $options An array of rendering options
+     * @return string 
+     */
+    public function initial_section($course, $section, $mods, $modnames, array $options = array()) {
+        
+        $context = get_context_instance(CONTEXT_COURSE, $course->id);
+        $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $context->id, 'course', 'section', $section->id);
+        $formatoptions = new stdClass;
+        $formatoptions->noclean = true;
+        $formatoptions->overflowdiv = true;
+        $isediting = $this->page->user_is_editing();
+        
+        $output  = '';
+        if (!empty($section->name)) {
+            $output .= $this->output->heading($section->name, 3, 'sectionname');
+        }
+        $output .= html_writer::start_tag('div', array('class'=>'summary'));
+        $output .= format_text($summarytext, $section->summaryformat, $formatoptions);
+        if ($isediting && has_capability('moodle/course:update', $context)) {
+            $output .= $this->section_summary_edit_icon($section->id, get_string('editsummary'));
+        }
+        $output .= html_writer::end_tag('div'); // .summary
+        $output .= $this->section($course, $section, $mods, $options);
+        if ($isediting) {
+            $output .= $this->section_add_menus($course, $section->id, $modnames, $options);
+        }
+        
+        return $this->section_structure($output, null, null, array('id'=>'section-0'));
+    }
+    
+    /**
+     * This function produces HTML to display the layout of a course section.
+     *
+     * @param string $content The main content.
+     * @param string $leftside The left side content.
+     * @param string $rightside The right side content.
+     * @param array $attributes An array of attributes.
+     * @return string
+     */
+    public function section_structure($content, $leftside = null, $rightside = null, array $attributes = array()) {
+        
+        if (empty($leftside)) {
+            $leftside = '&nbsp;';
+        }
+        if (empty($rightside)) {
+            $rightside = '&nbsp;';
+        }
+        if (empty($attributes['class'])) {
+            $attributes['class'] = 'section main clearfix';
+        }
+        
+        $output  = html_writer::start_tag('li', $attributes);
+        $output .= html_writer::tag('div', $leftside, array('class'=>'left side'));
+        $output .= html_writer::tag('div', $rightside, array('class'=>'right side'));
+        $output .= html_writer::tag('div', $content, array('class'=>'content'));
+        $output .= html_writer::end_tag('li');
+        return $output;
+    }
+    
+    /**
+     * Displays a course section
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The section to display
+     * @param array $mods An array of modules
+     * @param array $options An array of rendering options.
+     * @return string
+     */
+    public function section($course, $section, $mods, array $options = array()) {
+        global $CFG, $USER;
+        
+        require_once($CFG->dirroot.'/mod/forum/lib.php');
+
+        $options = (array)$options;
+        $options['hidecompletion'] = (!empty($options['hidecompletion']));
+        if (empty($options['modnamesused'])) {
+            $options['modnamesused'] = null;
+        }
+        if (empty($options['usetracking'])) {
+            $options['usetracking'] = forum_tp_can_track_forums();
+        }
+
+        $ismoving = $this->page->user_is_editing() && ismoving($course->id);
+
+        $output = '';
+
+        if (!empty($section->sequence)) {
+            $sectionmods = explode(",", $section->sequence);
+            $modinfo            = get_fast_modinfo($course);
+
+            $output .= html_writer::start_tag('ul', array('class'=>'section img-text'));
+
+            foreach ($sectionmods as $modnumber) {
+                if (empty($mods[$modnumber])) {
+                    continue;
+                }
+                $mod = $mods[$modnumber];
+                if ($ismoving and $mod->id == $USER->activitycopy) {
+                    // do not display moving mod
+                    continue;
+                }
+                $cm = false;
+                if (isset($modinfo->cms[$modnumber])) {
+                    $cm = $modinfo->cms[$modnumber];
+                }
+
+                if ($cm) {
+                    // We can continue (because it will not be displayed at all)
+                    // if:
+                    // 1) The activity is not visible to users
+                    // and
+                    // 2a) The 'showavailability' option is not set (if that is set,
+                    //     we need to display the activity so we can show
+                    //     availability info)
+                    // or
+                    // 2b) The 'availableinfo' is empty, i.e. the activity was
+                    //     hidden in a way that leaves no info, such as using the
+                    //     eye icon.
+                    if (!$cm->uservisible && (empty($cm->showavailability) || empty($cm->availableinfo))) {
+                        // visibility shortcut
+                        continue;
+                    }
+                } else {
+                    if (!file_exists("$CFG->dirroot/mod/$mod->modname/lib.php")) {
+                        // module not installed
+                        continue;
+                    }
+                    if (!coursemodule_visible_for_user($mod) && empty($mod->showavailability)) {
+                        // full visibility check
+                        continue;
+                    }
+                }
+                $output .= $this->section_module($course, $section, $mod, $options);
+            }
+
+        } else if ($ismoving) {
+            $output .= html_writer::start_tag('ul', array('class'=>'section'));
+        }
+
+        if ($ismoving) {
+            $url = new moodle_url('/course/mod.php', array('movetosection'=>$section->id, 'sesskey'=>sesskey()));
+            
+            $output .= html_writer::start_tag('li');
+            $output .= html_writer::start_tag('a', array('title'=>strip_tags(get_string("movefull", "", "'$USER->activitycopyname'")), 'href'=>$url));
+            $output .= $this->output->pix_icon('movehere', '', 'moodle', array('class'=>'movetarget'));
+            $output .= html_writer::end_tag('a');
+            $output .= html_writer::end_tag('li')."\n";
+        }
+        
+        if (!empty($section->sequence) || $ismoving) {
+            $output .=  html_writer::end_tag('ul'); // .section
+        }
+        
+        return $output;
+    }
+
+    /**
+     * Displays a module that belongs to a section
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $section The section the module is within
+     * @param stdClass $mod The module to display
+     * @param array $options An array of rendering options.
+     * @return string 
+     */
+    public function section_module($course, $section, $mod, $options) {
+        global $CFG;
+
+        $options['hidecompletion'] = (!empty($options['hidecompletion']));
+        $options['usetracking'] = (!empty($options['usetracking']));
+        
+        $context            = get_context_instance(CONTEXT_COURSE, $course->id);
+        $isediting          = $this->page->user_is_editing();
+        $ismoving           = $isediting && ismoving($course->id);
+        $canmanagegroups    = has_capability('moodle/course:managegroups', $context);
+        $groupbuttons       = ($course->groupmode or (!$course->groupmodeforce));
+        $labelformatoptions = new stdClass;
+        $labelformatoptions->noclean = true;
+        $labelformatoptions->overflowdiv = true;
+        
+        if ($canmanagegroups) {
+            if (empty($this->courseresources[$course->id])) {
+                $this->courseresources[$course->id] = array();
+            }
+            if (empty($this->courseresources[$course->id]['groupings'])) {
+                $this->courseresources[$course->id]['groupings'] = groups_get_all_groupings($course->id);
+            }
+            $groupings = $this->courseresources[$course->id]['groupings'];
+        } else {
+            $groupings = false;
+        }
+        
+        // In some cases the activity is visible to user, but it is
+        // dimmed. This is done if viewhiddenactivities is true and if:
+        // 1. the activity is not visible, or
+        // 2. the activity has dates set which do not include current, or
+        // 3. the activity has any other conditions set (regardless of whether
+        //    current user meets them)
+        $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
+        $canviewhidden = has_capability('moodle/course:viewhiddenactivities', $modcontext);
+        $accessiblebutdim = false;
+        if ($canviewhidden) {
+            $accessiblebutdim = !$mod->visible;
+            if (!empty($CFG->enableavailability)) {
+                $accessiblebutdim = $accessiblebutdim || 
+                                    $mod->availablefrom > time() ||
+                                    ($mod->availableuntil && $mod->availableuntil < time()) ||
+                                    count($mod->conditionsgrade) > 0 ||
+                                    count($mod->conditionscompletion) > 0;
+            }
+        }
+        
+        $output = '';
+
+        $classes = array('activity', $mod->modname, 'modtype_'.$mod->modname);
+        $output .= html_writer::start_tag('li', array('class'=>join(' ', $classes), 'id'=>'module-'.$mod->id));
+        if ($ismoving) {
+            $url = new moodle_url('/course/mod.php', array('moveto'=>$mod->id, 'sesskey'=>sesskey()));
+            $output .= html_writer::start_tag('a', array('title'=>$strfullmove, 'href'=>$url));
+            $output .= $this->output->pix_icon('movehere', get_string("movehere"), 'moodle', array('class'=>'movetarget'));
+            $output .= html_writer::end_tag('a');
+            $output .= html_writer::empty_tag('br');
+        }
+
+        $classes = array('mod-indent');
+        if (!empty($mod->indent)) {
+            $classes[] = 'mod-indent-'.$mod->indent;
+            if ($mod->indent > 15) {
+                $classes[] = 'mod-indent-huge';
+            }
+        }
+        $output .= html_writer::start_tag('div', array('class'=>join(' ', $classes)));
+
+        $extra = '';
+        if (!empty($mod->extra)) {
+            $extra = $mod->extra;
+        }
+
+        if ($mod->modname == "label") {
+            // Label
+
+            $content = format_text($extra, FORMAT_HTML, $labelformatoptions);
+            $classes = array();
+            if ($accessiblebutdim || !$mod->uservisible) {
+                $classes[] = 'dimmed_text';
+                $content = html_writer::tag('span', get_string('hiddenfromstudents'), array('class'=>'accesshide')).$content;
+            }
+            $output .= html_writer::tag('div', $content, array('class'=>join(' ', $classes)));
+
+            if ($canmanagegroups && $groupings && !empty($mod->groupingid)) {
+                $output .= html_writer::tag('span', '('.format_string($groupings[$mod->groupingid]->name).')', array('class'=>'groupinglabel'));
+            }
+
+        } else { 
+            // Normal activity
+
+            $instancename = format_string($mod->name, true,  $course->id);
+
+            $altname = $mod->modfullname;
+            $customicon = $mod->icon;
+            if (!empty($customicon)) {
+                if (substr($customicon, 0, 4) === 'mod/') {
+                    list($modname, $iconname) = explode('/', substr($customicon, 4), 2);
+                    $icon = $this->output->pix_url($iconname, $modname);
+                } else {
+                    $icon = $this->output->pix_url($customicon);
+                }
+                //Accessibility: for files get description via icon, this is very ugly hack!
+                $archetype = plugin_supports('mod', $mod->modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
+                if ($archetype == MOD_ARCHETYPE_RESOURCE) {
+                    $mimetype = mimeinfo_from_icon('type', $customicon);
+                    $altname = get_mimetype_description($mimetype);
+                }
+            } else {
+                $icon = $this->output->pix_url('icon', $mod->modname);
+            }
+            $icon = html_writer::empty_tag('img', array('src'=>$icon, 'class'=>'activityicon', 'alt'=>get_string('modulename',$mod->modname)));
+
+
+            // Avoid unnecessary duplication.
+            if (stripos($instancename, $altname) !== false) {
+                $altname = '';
+            }
+
+            // File type after name, for alphabetic lists (screen reader).
+            if ($altname) {
+                $altname = get_accesshide(' '.$altname);
+            }
+
+            // We may be displaying this just in order to show information
+            // about visibility, without the actual link
+            if ($mod->uservisible) {
+                // Display normal module link
+                $class = '';
+                $accesstext  ='';
+                if ($accessiblebutdim) {
+                    $class = 'class="dimmed"';
+                    $accesstext = html_writer::tag('span', get_string('hiddenfromstudents'), array('class'=>'accesshide'));
+                }
+                $url = new moodle_url('/mod/'.$mod->modname.'/view.php', array('id'=>$mod->id));
+                $content = html_writer::tag('span', $instancename.$altname, array('class'=>'instancename'));
+                $output .= "<a {$class} {$extra} href='{$url}'>{$icon} {$accesstext}{$content}</a>";
+
+                if ($canmanagegroups && $groupings && !empty($mod->groupingid)) {
+                    $output .= ' '.html_writer::tag('span', '('.format_string($groupings[$mod->groupingid]->name).')', array('class'=>'groupinglabel'));
+                }
+            } else {
+                // Display greyed-out text of link
+                $output .= '<span class="dimmed_text" '.$extra.' >';
+                $output .= html_writer::tag('span', get_string('notavailableyet','condition').': ', array('class'=>'accesshide'));
+                $output .= $icon;
+                $output .= html_writer::tag('span', $instancename.$altname);
+                $output .= '</span>';
+            }
+        }
+
+        if ($options['usetracking'] && $mod->modname == 'forum') {
+            if ($unread = forum_tp_count_forum_unread_posts($mod, $course)) {
+                if ($unread == 1) {
+                    $content = get_string('unreadpostsone', 'forum');
+                } else {
+                    $content = get_string('unreadpostsnumber', 'forum', $unread);
+                }
+                $output .= html_writer::start_tag('span', array('class'=>'unread'));
+                $output .= html_writer::link(new moodle_url('/mod/'.$mod->modname.'/view.php', array('id'=>$mod->id)), $content);
+                $output .= html_writer::end_tag('span');
+            }
+        }
+
+        if ($isediting) {
+            if ($groupbuttons and plugin_supports('mod', $mod->modname, FEATURE_GROUPS, 0)) {
+                if (! $mod->groupmodelink = (!$course->groupmodeforce)) {
+                    $mod->groupmode = $course->groupmode;
+                }
+
+            } else {
+                $mod->groupmode = false;
+            }
+            $output .= '&nbsp;&nbsp;';
+            $output .= $this->section_module_controls($mod, true, $mod->indent, $section->section);
+        }
+
+        // Completion
+        if (!$options['hidecompletion'] && isloggedin() && !isguestuser() && $mod->uservisible) {
+            $this->section_module_completion_info($course, $mod);
+        }
+
+        // Show availability information (for someone who isn't allowed to
+        // see the activity itself, or for staff)
+        $content = false;
+        if (!$mod->uservisible) {
+            $content = $mod->availableinfo;
+        } else if ($canviewhidden && !empty($CFG->enableavailability)) {
+            $ci = new condition_info($mod);
+            $fullinfo = $ci->get_full_information();
+            if ($fullinfo) {
+                if ($mod->showavailability) { 
+                    $content = get_string('userrestriction_visible', 'condition', $fullinfo);
+                } else {
+                    $content = get_string('userrestriction_hidden', 'condition', $fullinfo);
+                }
+            }
+        }
+        if ($content) {
+            $output .=  html_writer::tag('div', $content, array('class'=>'availabilityinfo'));
+        }
+
+        $output .=  html_writer::end_tag('div');
+        $output .=  html_writer::end_tag('li')."\n";
+        
+        return $output;
+    }
+    
+    /**
+     * Displays module completion information
+     *
+     * @param stdClass $course The current course
+     * @param stdClass $mod The module to display information for
+     * @return string 
+     */
+    public function section_module_completion_info($course, $mod) {
+
+        if (empty($this->courseresources[$course->id])) {
+            $this->courseresources[$course->id] = array();
+        }
+        if (empty($this->courseresources[$course->id]['completioninfo'])) {
+            $this->courseresources[$course->id]['completioninfo'] = new completion_info($course);
+        }
+        $completioninfo = $this->courseresources[$course->id]['completioninfo'];
+
+        $isediting = $this->page->user_is_editing();
+        $completion = $completioninfo->is_enabled($mod);
+        $completiondata = $completioninfo->get_data($mod,true);
+        $completionicon = '';
+        if ($isediting) {
+            switch ($completion) {
+                case COMPLETION_TRACKING_MANUAL :
+                    $completionicon = 'manual-enabled'; break;
+                case COMPLETION_TRACKING_AUTOMATIC :
+                    $completionicon = 'auto-enabled'; break;
+                default: // wtf
+            }
+        } else if ($completion==COMPLETION_TRACKING_MANUAL) {
+            switch($completiondata->completionstate) {
+                case COMPLETION_INCOMPLETE:
+                    $completionicon = 'manual-n'; break;
+                case COMPLETION_COMPLETE:
+                    $completionicon = 'manual-y'; break;
+            }
+        } else { // Automatic
+            switch($completiondata->completionstate) {
+                case COMPLETION_INCOMPLETE:
+                    $completionicon = 'auto-n'; break;
+                case COMPLETION_COMPLETE:
+                    $completionicon = 'auto-y'; break;
+                case COMPLETION_COMPLETE_PASS:
+                    $completionicon = 'auto-pass'; break;
+                case COMPLETION_COMPLETE_FAIL:
+                    $completionicon = 'auto-fail'; break;
+            }
+        }
+        $output = '';
+        if ($completionicon) {
+            $imgsrc = $this->output->pix_url('i/completion-'.$completionicon);
+            $imgalt = s(get_string('completion-alt-'.$completionicon, 'completion'));
+            if ($completion == COMPLETION_TRACKING_MANUAL && !$isediting) {
+                $imgtitle = s(get_string('completion-title-'.$completionicon, 'completion'));
+
+                if ($completiondata->completionstate == COMPLETION_COMPLETE) {
+                    $newstate = COMPLETION_INCOMPLETE;
+                } else {
+                    $newstate = COMPLETION_COMPLETE;
+                }
+
+                // In manual mode the icon is a toggle form...
+                // If this completion state is used by the
+                // conditional activities system, we need to turn
+                // off the JS.
+                $classes = array('togglecompletion');
+                if (!empty($CFG->enableavailability) && condition_info::completion_value_used_as_condition($course, $mod)) {
+                    $classes[] = 'preventjs';
+                }
+
+                $output .= html_writer::start_tag('form', array('class'=>join(' ', $classes), 'method'=>'post', 'action'=>'togglecompletion.php'));
+                $output .= html_writer::start_tag('div');
+                $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'id', 'value'=>$mod->id));
+                $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
+                $output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'completionstate', 'value'=>$newstate));
+                $output .= html_writer::empty_tag('input', array('type'=>'image', 'src'=>$imgsrc, 'alt'=>$imgalt, 'title'=>$imgtitle));
+                $output .= html_writer::end_tag('div');
+                $output .= html_writer::end_tag('form');
+            } else {
+                // In auto mode, or when editing, the icon is just an image
+                $output .= html_writer::start_tag('span', array('class'=>'autocompletion'));
+                $output .= html_writer::empty_tag('img', array('src'=>$imgsrc, 'alt'=>$imgalt, 'title'=>$imgalt));
+                $output .= html_writer::end_tag('span');
+            }
+        }
+        return $output;
+    }
+    
+    /**
+     * Generates the menus to add modules and plugins to a course section.
+     *
+     * @param stdClass $course
+     * @param int $sectionid
+     * @param array $modnames
+     * @param array $options
+     * @return string
+     */
+    public function section_add_menus($course, $sectionid, $modnames, array $options = array()) {
+        global $CFG;
+
+        $options['vertical'] = (!empty($options['vertical']));
+
+        // check to see if user can add menus
+        if (!has_capability('moodle/course:manageactivities', get_context_instance(CONTEXT_COURSE, $course->id))) {
+            return false;
+        }
+
+        $url = new moodle_url('/course/mod.php', array('id'=>$course->id, 'section'=>$sectionid, 'sesskey'=>sesskey()));
+
+        $resources = array();
+        $activities = array();
+
+        foreach($modnames as $modname=>$modnamestr) {
+            if (!course_allowed_module($course, $modname)) {
+                continue;
+            }
+
+            $libfile = "$CFG->dirroot/mod/$modname/lib.php";
+            if (!file_exists($libfile)) {
+                continue;
+            }
+            require_once($libfile);
+            $gettypesfunc =  $modname.'_get_types';
+            if (function_exists($gettypesfunc)) {
+                // NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
+                if ($types = $gettypesfunc()) {
+                    $menu = array();
+                    $atype = null;
+                    $groupname = null;
+                    foreach($types as $type) {
+                        if ($type->typestr === '--') {
+                            continue;
+                        }
+                        if (strpos($type->typestr, '--') === 0) {
+                            $groupname = str_replace('--', '', $type->typestr);
+                            continue;
+                        }
+                        $type->type = str_replace('&amp;', '&', $type->type);
+                        if ($type->modclass == MOD_CLASS_RESOURCE) {
+                            $atype = MOD_CLASS_RESOURCE;
+                        }
+                        $typeurl = new moodle_url($url, array('add'=>$type->type));
+                        $menu[$typeurl->out(false)] = $type->typestr;
+                    }
+                    if (!is_null($groupname)) {
+                        if ($atype == MOD_CLASS_RESOURCE) {
+                            $resources[] = array($groupname=>$menu);
+                        } else {
+                            $activities[] = array($groupname=>$menu);
+                        }
+                    } else {
+                        if ($atype == MOD_CLASS_RESOURCE) {
+                            $resources = array_merge($resources, $menu);
+                        } else {
+                            $activities = array_merge($activities, $menu);
+                        }
+                    }
+                }
+            } else {
+                $archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
+                $modurl = new moodle_url($url, array('add'=>$modname));
+                if ($archetype == MOD_ARCHETYPE_RESOURCE) {
+                    $resources[$modurl->out(false)] = $modnamestr;
+                } else {
+                    // all other archetypes are considered activity
+                    $activities[$modurl->out(false)] = $modnamestr;
+                }
+            }
+        }
+
+        $straddactivity = get_string('addactivity');
+        $straddresource = get_string('addresource');
+
+        $output = html_writer::start_tag('div', array('class'=>'section_add_menus'));
+        if (!$options['vertical']) {
+            $output .= html_writer::start_tag('div', array('class'=>'horizontal'));
+        }
+
+        if (!empty($resources)) {
+            $select = new url_select($resources, '', array(''=>$straddresource), "ressection$sectionid");
+            $select->set_help_icon('resources');
+            $output .= $this->output->render($select);
+        }
+
+        if (!empty($activities)) {
+            $select = new url_select($activities, '', array(''=>$straddactivity), "section$sectionid");
+            $select->set_help_icon('activities');
+            $output .= $this->output->render($select);
+        }
+
+        if (!$options['vertical']) {
+            $output .= html_writer::end_tag('div'); // .horizontal
+        }
+        $output .= html_writer::end_tag('div'); // .section_add_menus
+
+        return $output;
+    }
+    
+    /**
+     * Generates controls for a course module.
+     *
+     * @staticvar stdClass $str
+     * @param stdClass $mod The module to generate controls for
+     * @param bool $moveselect
+     * @param int $indent The level to indent to
+     * @param int $section The section this module belongs within.
+     * @return string 
+     */
+    public function section_module_controls($mod, $moveselect=true, $indent=-1, $section=-1) {
+        global $CFG;
+
+        static $str;
+
+        $modcontext = get_context_instance(CONTEXT_MODULE, $mod->id);
+        $coursecontext = get_context_instance(CONTEXT_COURSE, $mod->course);
+        
+        // no permission to edit
+        if (!has_capability('moodle/course:manageactivities', $modcontext)) {
+            return false;
+        }
+
+        if (!isset($str)) {
+            $str = new stdClass;
+            $str->assign         = get_string("assignroles", 'role');
+            $str->delete         = get_string("delete");
+            $str->move           = get_string("move");
+            $str->moveup         = get_string("moveup");
+            $str->movedown       = get_string("movedown");
+            $str->moveright      = get_string("moveright");
+            $str->moveleft       = get_string("moveleft");
+            $str->update         = get_string("update");
+            $str->duplicate      = get_string("duplicate");
+            $str->hide           = get_string("hide");
+            $str->show           = get_string("show");
+            $str->clicktochange  = get_string("clicktochange");
+            $str->forcedmode     = get_string("forcedmode");
+            $str->groupsnone     = get_string("groupsnone");
+            $str->groupsseparate = get_string("groupsseparate");
+            $str->groupsvisible  = get_string("groupsvisible");
+        }
+
+        $baseurl = new moodle_url('/course/mod.php', array('sesskey'=>sesskey()));
+        if ($section >= 0) {
+            $baseurl->param('sr', $section);
+        }
+
+        $output  = html_writer::start_tag('span', array('class'=>'commands'));
+
+        if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
+
+            if (right_to_left()) {   // Exchange arrows on RTL
+                $rightarrow = 't/left';
+                $leftarrow  = 't/right';
+            } else {
+                $rightarrow = 't/right';
+                $leftarrow  = 't/left';
+            }
+
+            if ($indent > 0) {
+                $attributes = array('class'=>'editing_moveleft', 'title'=>$str->moveleft);
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'indent'=>'-1'));
+                $icon = new pix_icon($leftarrow, $str->moveleft, 'moodle', array('class'=>'iconsmall'));
+                $output .= $this->output->action_icon($url, $icon, null, $attributes);
+            }
+            if ($indent >= 0) {
+                $attributes = array('class'=>'editing_moveright', 'title'=>$str->moveright);
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'indent'=>'1'));
+                $icon = new pix_icon($rightarrow, $str->moveright, 'moodle', array('class'=>'iconsmall'));
+                $output .= $this->output->action_icon($url, $icon, null, $attributes);
+            }
+        }
+
+        if (has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $mod->course))) {
+            if ($moveselect) {
+                $attributes = array('class'=>'editing_move', 'title'=>$str->move);
+                $url = new moodle_url($baseurl, array('copy'=>$mod->id));
+                $icon = new pix_icon('t/move', $str->move, 'moodle', array('class'=>'iconsmall'));
+                $output .= $this->output->action_icon($url, $icon, null, $attributes);
+            } else {
+                $attributes = array('class'=>'editing_moveup', 'title'=>$str->moveup);
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'move'=>'-1'));
+                $icon = new pix_icon('t/up', $str->moveup, 'moodle', array('class'=>'iconsmall'));
+                $output .= $this->output->action_icon($url, $icon, null, $attributes);
+
+                $attributes = array('class'=>'editing_movedown', 'title'=>$str->movedown);
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'move'=>'1'));
+                $icon = new pix_icon('t/down', $str->movedown, 'moodle', array('class'=>'iconsmall'));
+                $output .= $this->output->action_icon($url, $icon, null, $attributes);
+            }
+        }
+
+        $attributes = array('class'=>'editing_update', 'title'=>$str->update);
+        $url = new moodle_url($baseurl, array('update'=>$mod->id));
+        $icon = new pix_icon('t/edit', $str->update, 'moodle', array('class'=>'iconsmall'));
+        $output .= $this->output->action_icon($url, $icon, null, $attributes);
+
+        $attributes = array('class'=>'editing_delete', 'title'=>$str->delete);
+        $url = new moodle_url($baseurl, array('delete'=>$mod->id));
+        $icon = new pix_icon('t/delete', $str->delete, 'moodle', array('class'=>'iconsmall'));
+        $output .= $this->output->action_icon($url, $icon, null, $attributes);
+
+        if (has_capability('moodle/course:activityvisibility', $modcontext)) {
+            if ($mod->visible) {
+                $icon = new pix_icon('t/hide', $str->hide, 'moodle', array('class'=>'iconsmall'));
+                $url = new moodle_url($baseurl, array('hide'=>$mod->id));
+                $attributes = array('class'=>'editing_hide', 'title'=>$str->hide);
+            } else {
+                $icon = new pix_icon('t/show', $str->show, 'moodle', array('class'=>'iconsmall'));
+                $url = new moodle_url($baseurl, array('show'=>$mod->id));
+                $attributes = array('class'=>'editing_show', 'title'=>$str->show);
+            }
+            $output .= $this->output->action_icon($url, $icon, null, $attributes);
+        }
+
+        if ($mod->groupmode !== false) {
+            if ($mod->groupmode == SEPARATEGROUPS) {
+                $attributes = array('title' => $str->groupsseparate.' ('.$str->clicktochange.')', 'class'=>'editing_groupsseparate');
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'groupmode'=>0));
+                $icon = new pix_icon('t/groups', $str->groupsseparate, 'moodle', array('class'=>'iconsmall'));
+            } else if ($mod->groupmode == VISIBLEGROUPS) {
+                $attributes = array('title' => $str->groupsvisible.' ('.$str->clicktochange.')', 'class'=>'editing_groupsvisible');
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'groupmode'=>1));
+                $icon = new pix_icon('t/groupv', $str->groupsvisible, 'moodle', array('class'=>'iconsmall'));
+            } else {
+                $attributes = array('title' => $str->groupsnone.' ('.$str->clicktochange.')', 'class'=>'editing_groupsnone');
+                $url = new moodle_url($baseurl, array('id'=>$mod->id, 'groupmode'=>2));
+                $icon = new pix_icon('t/groupn', $str->groupsnone, 'moodle', array('class'=>'iconsmall'));
+            }
+            if ($mod->groupmodelink) {
+                $output .= $this->output->action_icon($url, $icon, null, $attributes);
+            } else {
+                $icon->attributes['title'] = $icon->attributes['alt'].' ('.$str->forcedmode.')';
+                $output .= $this->output->render($icon);
+            }
+        }
+
+        if (has_capability('moodle/course:managegroups', $modcontext)){
+            $attributes = array('class'=>'editing_assign', 'title'=>$str->assign);
+            $url = new moodle_url('/'.$CFG->admin.'/roles/assign.php', array('contextid'=>$modcontext->id));
+            $icon = new pix_icon('i/roles', $str->assign, 'moodle', array('class'=>'iconsmall'));
+            $output .= $this->output->action_icon($url, $icon, null, $attributes);
+        }
+
+        $output .= html_writer::end_tag('span');
+        return $output;
+    }
+    
+    /**
+     * Generates HTML to display a section summary.
+     *
+     * @param stdClass $section
+     * @param stdClass $coursecontext
+     * @return string
+     */
+    public function section_summary($section, $coursecontext) {
+        $streditsummary  = get_string('editsummary');
+        
+        $output = html_writer::start_tag('div', array('class'=>'summary'));
+        if ($section->summary) {
+            $summarytext = file_rewrite_pluginfile_urls($section->summary, 'pluginfile.php', $coursecontext->id, 'course', 'section', $section->id);
+            $summaryformatoptions = new stdClass();
+            $summaryformatoptions->noclean = true;
+            $summaryformatoptions->overflowdiv = true;
+            $output .= format_text($summarytext, $section->summaryformat, $summaryformatoptions);
+        } else {
+            $output .= '&nbsp;';
+        }
+
+        if ($this->page->user_is_editing() && has_capability('moodle/course:update', $coursecontext)) {
+            $url = new moodle_url('/course/editsection.php', array('id'=>$section->id));
+            $icon = new pix_icon('t/edit', $streditsummary, 'moodle', array('class'=>'icon edit'));
+            $output .= html_writer::tag('div', $this->output->action_icon($url, $icon, null, array('title'=>$streditsummary)));
+        }
+        $output .= html_writer::end_tag('div');
+        return $output;
+    }
+}
diff --git a/index.php b/index.php
index f871c9f..844c454 100644
--- a/index.php
+++ b/index.php
@@ -86,6 +86,7 @@
     $editing = $PAGE->user_is_editing();
     $PAGE->set_title($SITE->fullname);
     $PAGE->set_heading($SITE->fullname);
+    $renderer = $PAGE->get_renderer('core_course', 'generic_format');
     echo $OUTPUT->header();
 
 /// Print Section
@@ -129,10 +130,10 @@
             }
 
             get_all_mods($SITE->id, $mods, $modnames, $modnamesplural, $modnamesused);
-            print_section($SITE, $section, $mods, $modnamesused, true);
+            echo $renderer->section($SITE, $section, $mods, array('modnamesused'=>$modnamesused));
 
             if ($editing) {
-                print_section_add_menus($SITE, $section->section, $modnames);
+                echo $renderer->section_add_menus($SITE, $section->section, $modnames);
             }
             echo $OUTPUT->box_end();
         }
diff --git a/lib/outputlib.php b/lib/outputlib.php
index e3066d4..59d82d1 100644
--- a/lib/outputlib.php
+++ b/lib/outputlib.php
@@ -256,7 +256,7 @@ class theme_config {
      *      your own custom renderers in a lib.php file in this theme (or the parent theme).</li>
      * </ul>
      *
-     * @var string name of a class implementing the {@link renderer_factory} interface.
+     * @var renderer_factory string name of a class implementing the {@link renderer_factory} interface.
      */
     public $rendererfactory = 'standard_renderer_factory';
 
-- 
1.7.1

