<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/39/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bushido</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/39/en/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bushido"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/Special:Contributions/Bushido"/>
	<updated>2026-04-16T12:58:44Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development_talk:Backup_2.0_-_Converters_review_2011-04&amp;diff=83097</id>
		<title>Development talk:Backup 2.0 - Converters review 2011-04</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development_talk:Backup_2.0_-_Converters_review_2011-04&amp;diff=83097"/>
		<updated>2011-04-28T19:53:16Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Feedback from Mark regarding review */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please, for discussing any of the points in the page, do it in the corresponding MDL-xxx issue in the Tracker. TIA! --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 22:45, 26 April 2011 (WST)&lt;br /&gt;
&lt;br /&gt;
=== Ongoing discussion Eloy &amp;amp; Mark (20110428) ===&lt;br /&gt;
&lt;br /&gt;
Three (3) targets are planned, no action on next target will be performed before completing the previous one:&lt;br /&gt;
&lt;br /&gt;
* The &amp;quot;basic&amp;quot; (1st): Be able to restore everything but user-related information.&lt;br /&gt;
* The &amp;quot;desirable&amp;quot; (2nd): Be able to restore activity user-related information.&lt;br /&gt;
* The &amp;quot;complete&amp;quot; (3rd): Rest of information.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
From the review, points 01-19 must be analyzed, discussed and implemented, specially the ones detected as blockers for the consecution of the targets above. The ones not being considered blockers can be left for later, once the &amp;quot;basic&amp;quot; (1st) target has been fulfilled. The review page will show which ones are considered blockers and where (MDL-xxxx) their implementation is going to happen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Immediate plan, something like:&lt;br /&gt;
* you take a look to those points and add any objection / comment / missing point in the last section of the page.&lt;br /&gt;
* I also take a look to the thing and start implementing some stuff, like the start/end dispatchers and some tests to have them under control.&lt;br /&gt;
* Next day, availability of parties determined, we share thoughts.&lt;br /&gt;
* Next-next day, we start &amp;quot;doing&amp;quot; things :-)&lt;br /&gt;
&lt;br /&gt;
=== Feedback from Mark regarding review ===&lt;br /&gt;
&lt;br /&gt;
==== Related to integration with restore_controller &amp;amp; general behavior ====&lt;br /&gt;
&lt;br /&gt;
* R0401: I see what you are trying to get at here, but seems like over architecting IMO.  For example, you have something that goes from FOO &amp;gt; BAR &amp;gt; MOODLE2 (CONVERTPATH1) and then you have something that goes to FOO &amp;gt; MOODLE2 (CONVERTPATH2) both installed, then your proposal would be necessary.  Though, why would you have both installed?  CONVERTPATH2 would replace CONVERTPATH1 making CONVERTPATH1 obsolete and never used anyways.  Anyways, I&#039;d say let&#039;s hold this off as a fun project after everything else is done.&lt;br /&gt;
* R0402: I don&#039;t see much of an advantage here as by moving to static you then loose access to all of your instance variables and methods.  Cost of creating a new instance shouldn&#039;t be that terrible.  If this is required, fine, let&#039;s do it.&lt;br /&gt;
** As for checking the environment, I think that can be done in can_convert right?  Part of figuring out if it can handle the conversion.&lt;br /&gt;
* R0403-5: These are fine.  We should probably make our own converter_exceptions, what do you think?&lt;br /&gt;
&lt;br /&gt;
==== Related to the converters/moodle1 infrastructure ====&lt;br /&gt;
&lt;br /&gt;
* R0408: There is execute_after_convert but really, that&#039;s called after the XML has been processed.  Execution flow is kind of weird due to the processor.  We could add another stage of processing, though I do think execution flow will greatly improve once start/end callbacks are being used.&lt;br /&gt;
* R0410: I&#039;m not sure what this is.&lt;br /&gt;
* Rest are fine.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Related to coding in general ====&lt;br /&gt;
&lt;br /&gt;
* Sounds fine.&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development_talk:Backup_2.0_-_Converters_review_2011-04&amp;diff=83096</id>
		<title>Development talk:Backup 2.0 - Converters review 2011-04</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development_talk:Backup_2.0_-_Converters_review_2011-04&amp;diff=83096"/>
		<updated>2011-04-28T19:19:48Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please, for discussing any of the points in the page, do it in the corresponding MDL-xxx issue in the Tracker. TIA! --[[User:Eloy Lafuente (stronk7)|Eloy Lafuente (stronk7)]] 22:45, 26 April 2011 (WST)&lt;br /&gt;
&lt;br /&gt;
=== Ongoing discussion Eloy &amp;amp; Mark (20110428) ===&lt;br /&gt;
&lt;br /&gt;
Three (3) targets are planned, no action on next target will be performed before completing the previous one:&lt;br /&gt;
&lt;br /&gt;
* The &amp;quot;basic&amp;quot; (1st): Be able to restore everything but user-related information.&lt;br /&gt;
* The &amp;quot;desirable&amp;quot; (2nd): Be able to restore activity user-related information.&lt;br /&gt;
* The &amp;quot;complete&amp;quot; (3rd): Rest of information.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
From the review, points 01-19 must be analyzed, discussed and implemented, specially the ones detected as blockers for the consecution of the targets above. The ones not being considered blockers can be left for later, once the &amp;quot;basic&amp;quot; (1st) target has been fulfilled. The review page will show which ones are considered blockers and where (MDL-xxxx) their implementation is going to happen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Immediate plan, something like:&lt;br /&gt;
* you take a look to those points and add any objection / comment / missing point in the last section of the page.&lt;br /&gt;
* I also take a look to the thing and start implementing some stuff, like the start/end dispatchers and some tests to have them under control.&lt;br /&gt;
* Next day, availability of parties determined, we share thoughts.&lt;br /&gt;
* Next-next day, we start &amp;quot;doing&amp;quot; things :-)&lt;br /&gt;
&lt;br /&gt;
=== Feedback from Mark regarding review ===&lt;br /&gt;
&lt;br /&gt;
test&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Course_formats&amp;diff=82994</id>
		<title>Course formats</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Course_formats&amp;diff=82994"/>
		<updated>2011-04-26T17:06:52Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Page format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A course format refers to the layout of a course.  They can be changed by the course [[Course administration block]] under [[Course settings|settings]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Standard course formats==&lt;br /&gt;
&lt;br /&gt;
===Weekly format===&lt;br /&gt;
[[Image:Course top weekly mu1.jpg|thumb|Weekly format example]] The course is organized week by week, with a clear start date and a finish date.  Moodle will create a section for each week of your course.  You can add content, forums, quizzes, and so on in the section for each week.  &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; If you want all your students to work on the same materials at the same time, this would be a good format to choose.&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;NOTE:&#039;&#039; Make sure your course start date is correct. If it is not your weeks will have the wrong date on it. This is especially important if you are restoring a course to use with a new section of students.&lt;br /&gt;
&lt;br /&gt;
===Topics format===&lt;br /&gt;
The course is organised into topic sections. Each topic section consists of activities.&lt;br /&gt;
&lt;br /&gt;
TIP: This is great to use if your course is objective based and each objective may take different amounts of time to complete. An example of this would be scaffolding where the students are building upon the knowledge from earlier topics.&lt;br /&gt;
&lt;br /&gt;
===Social format===&lt;br /&gt;
[[Image:Course top social mu1.jpg|thumb|Social format example]] This format is oriented around one main [[Forum module|forum]], the social forum, which appears listed on the main page.  It is useful for situations that are more free form.  They may not even be courses. The [http://moodle.org/course/view.php?id=55 Moodle Lounge] is an example of a social format course.&lt;br /&gt;
&lt;br /&gt;
The social forum can be edited by clicking the &#039;Update this forum&#039; button on the social forum page. The forum introduction is displayed at the top of the course page (in Moodle 1.9.5 onwards).&lt;br /&gt;
&lt;br /&gt;
===LAMS course format===&lt;br /&gt;
[[LAMS|The Learning Activity Management System]] is an open source LMS which allows teachers to use a flash based authoring environment for developing learning sequences.  LAMS has been integrated with Moodle to allow teachers to develop LAMS activities within a Moodle course.  This course format makes LAMS central to the course, only displaying the LAMS interface.  &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; If you are interested in using LAMS, check with your system administrator to see if they have installed and configured LAMS.  Very few institutions use LAMS as it duplicates much of the Moodle functionality.&lt;br /&gt;
&lt;br /&gt;
===SCORM format===&lt;br /&gt;
The [[SCORM/AICC module|Sharable Content Reference Model]] (SCORM) is a content packaging standard.  SCORM packages are self-contained bundles of content and JavaScript activities, which can send data to Moodle about the students score and current location.  Moodle can use SCORM packages as a content type (see [[SCORM/AICC module]]), or as a course format.  &lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;TIP:&#039;&#039; If you have a large SCORM object you want to use as an entire course, then you can select this course format and students will only be able to interact with the SCORM object, not the rest of the Moodle tools.&lt;br /&gt;
&lt;br /&gt;
===Weekly format, CSS/no tables===&lt;br /&gt;
The CSS / No Tables variant of the Weekly format displays the Weekly course format without using tables for layout.  This improves the accessibility of the format, but older browsers have trouble displaying it correctly. This format is available in Moodle 1.6 onwards.&lt;br /&gt;
&lt;br /&gt;
==Contributed course formats==&lt;br /&gt;
&lt;br /&gt;
===Page format===&lt;br /&gt;
Also known as Flexpage, this format is very similar to the Book resource format in a Moodle course. It consists of a theme, course format, and menu module which enables blocks and modules to be intermixed on a 3 column layout, provide tab based navigation through course content, inline display of resources and forums, etc.  For more information on Flexpage, please visit [http://development.moodlerooms.com/course/view.php?id=34 this site] (You can self-register for this Moodle course.) This feature was developed by a Moodle partner [http://www.moodlerooms.com Moodlerooms, Inc.]&lt;br /&gt;
&lt;br /&gt;
===Collapsed Topics and Weeks formats===&lt;br /&gt;
&lt;br /&gt;
Collapsed Topics and its sister format, Collapsed Weeks are formats that are essentially the same as the standard Topic ([[Course_sections#Topics_format]]) and Weekly ([[Course_sections#Weekly_format]]) formats but with a &#039;toggle&#039; for each section except &#039;0&#039;.  The toggles&#039; purpose is to reduce the amount of initial information presented to the user thus reducing the &#039;scroll of death&#039; that can plague courses with a lot of content.  The &#039;state&#039; of the toggles is remembered on a per course per user basis.  Collapsed Weeks automatically opens the current week.  There are versions available for Moodle 1.8, 1.9 and 2.0.  For more information, please visit [[Collapsed_Topics_course_format]] and [[Collapsed_Weeks_course_format]].&lt;br /&gt;
&lt;br /&gt;
===Other contributed course formats===&lt;br /&gt;
&lt;br /&gt;
Other contributed course formats include [[Project Course Format]], [[Weekly Tabs]], Monthly Format (for Moodle 1.9), [[Development:Timeline course format|Timeline course format]] and the [[Shared activities course format]].&lt;br /&gt;
&lt;br /&gt;
An administrator wishing to remove installed formats may do so by removing the format plugin from the installation. That is: remove the directory containing the format for the &#039;&#039;moodle/course/format&#039;&#039; directory. You probably should not remove any of the default course formats, or formats that are in use on the site.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[[Course settings]]&lt;br /&gt;
*Using Moodle [http://moodle.org/mod/forum/view.php?id=47 Course formats forum]&lt;br /&gt;
*[http://www.moodleman.net/archives/47 Getting the most out of course design] blog post describing various contributed course formats&lt;br /&gt;
&lt;br /&gt;
Using Moodle forum discussions:&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=116428 Social format: where to put an introduction]&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=136453 RSS Feed for forum in a Social Format course]&lt;br /&gt;
&lt;br /&gt;
[[Category:Course format]]&lt;br /&gt;
&lt;br /&gt;
[[fr:Formats de cours]]&lt;br /&gt;
&lt;br /&gt;
[[es:FormatoCurso]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Auth_External_Database_Release_Notes&amp;diff=50095</id>
		<title>Development:Auth External Database Release Notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Auth_External_Database_Release_Notes&amp;diff=50095"/>
		<updated>2009-02-04T23:50:04Z</updated>

		<summary type="html">&lt;p&gt;Bushido: New page: * Added more data mappings: ** maildigest ** autosubscribe ** trackforums ** password * Implemented the cron method. * Added unlimited execution time for auth/db/auth_db_sync_users.php * N...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Added more data mappings:&lt;br /&gt;
** maildigest&lt;br /&gt;
** autosubscribe&lt;br /&gt;
** trackforums&lt;br /&gt;
** password&lt;br /&gt;
* Implemented the cron method.&lt;br /&gt;
* Added unlimited execution time for auth/db/auth_db_sync_users.php&lt;br /&gt;
* New settings when Password format is set to internal:&lt;br /&gt;
** Create Unique Password: If the password type is set to internal then this setting determines if a unique password is created and emailed to the user&#039;s email address in the external datbase.&lt;br /&gt;
** Only Change this Password: Adding a value to this field causes moodle to only create a password for those users that have their password set to the value. For example changeme will cause all users with the password changeme to have a unique password created and emailed to them. Leave this blank if you want to change all users password when their acocunt is first created.&lt;br /&gt;
** Force Password Change: If the password type is set to internal then this setting determines if the user is forced to change their password on their first login&lt;br /&gt;
* Performance improvements:&lt;br /&gt;
** With original code, attempted to create 100,000 users and execution was terminated after waiting for a long time (hour or more).&lt;br /&gt;
** With the new code, created 20,000 users in 36 seconds and 100,000 users in 188 seconds.&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=49156</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=49156"/>
		<updated>2009-01-21T18:55:50Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Adding note about replacing branch tables with check points&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student received 100% of the possible points on the last question, go to &#039;&#039;this&#039;&#039; page.  If 99% to 60%, go to &#039;&#039;this&#039;&#039; page.  If less than 60%, go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
*Visible Check Point: the user is presented with text and buttons with labels.  The buttons are navigational choices for the user.  This is the same fundamental functionality found in current lesson [[Branch_Table|Branch Tables]].&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced with Check Points. (Branch tables could be replaced, see above section Possible uses: Visible Check Points [[User:Mark Nielsen|Mark Nielsen]] 12:55, 21 January 2009 (CST))&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class more natural.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
*Lesson question will strictly be used for grading, no customized jumps depending upon a specific answer.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Development:Lesson Specification]]&lt;br /&gt;
*[[Development:Adding blocks to lesson]]&lt;br /&gt;
*[[Development:Adding question types to lesson]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|New lesson navigation]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=49155</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=49155"/>
		<updated>2009-01-21T18:53:58Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added new possible use: visible check point&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student received 100% of the possible points on the last question, go to &#039;&#039;this&#039;&#039; page.  If 99% to 60%, go to &#039;&#039;this&#039;&#039; page.  If less than 60%, go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
*Visible Check Point: the user is presented with text and buttons with labels.  The buttons are navigational choices for the user.  This is the same fundamental functionality found in current lesson [[Branch_Table|Branch Tables]].&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced with Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class more natural.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
*Lesson question will strictly be used for grading, no customized jumps depending upon a specific answer.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[Development:Lesson Specification]]&lt;br /&gt;
*[[Development:Adding blocks to lesson]]&lt;br /&gt;
*[[Development:Adding question types to lesson]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|New lesson navigation]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=49154</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=49154"/>
		<updated>2009-01-21T18:46:57Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added a new comment: Branch tables == visible check points&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
Please note that this page deals with a future version of [[Roadmap#Version_2.0|Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson module]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*(Primary) Increase the usability of the lesson module by making it easier for lesson authors to construct lessons.&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**Will this include the shuffle answer option for each question, or will/can this be a Lesson setting?--[[User:chris collman|chris collman]] 08:37, 10 December 2007 (CST)&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
:Not tracking individual student answers in a lesson would clearly separate Lesson from Quiz.  I like it. I believe once we have at least some sort of course dependency in Moodle 2, this will take a great deal of pressure off of Lesson.  The course dependency setting for any activity should at least have greater, less than choices from say a score or one or more activities/resources. (this seems similar to the State Checker idea).  It would be nice if it had limited nested if/then statements to allow a ranges of dependency to be really adaptive.  This will allow the teacher to break up big lessons into smaller ones and put a real quiz/test between them.  So when the student gets a 100% on a following quiz, they go to Lesson 10, but the student who scores less than 50% goes back to the Lesson or to a special lesson before they will see Lesson 10.   Under these conditions, we can confidently get rid of a history of answered questions in Lesson, and leave that function to Quiz.   --[[User:chris collman|chris collman]] 10:06, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
*migrate lesson navigation.&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
I think you can use this without invasions. The questions contain feedback (which is a rought equivalent of outcome), and the answers with equivalent feedbacks are very likely to give equivalent jumps (if they still not, user can easily rewrite it using different words or just add some spaces or punctuation). You may not invade in the question types, but use feedback they return instead. You can use a table (apart from question editing interface) that allows author to specify jumps for feedbacks (or place jump right in feedback in some sort of you own tag - but it&#039;ll restricts using one question on several pages or lessons with different jumps). This solution is quite easy to implement, probably an easier way than anyone mentioned there.&lt;br /&gt;
&lt;br /&gt;
You can get problem with some question types using this, but they are easily solved:&lt;br /&gt;
* essay  - you probably will want to suppress using of manual graded question types in lessons anyway;&lt;br /&gt;
*multichoice in several choices mode - you can use correct/partial/incorrect feedbacks;&lt;br /&gt;
*match - it lacks feedbacks now, but probably it must have just correct/partial/incorrect as multichoice question, they are needed in it anyway, not only for the lessons.&lt;br /&gt;
&lt;br /&gt;
You may want to use feedback text only as values to communicate with user thought, replacing it in database by subquestion id or code for correct, partial or incorrect values. This allows you to avoid problems with editing feedbacks for existing questions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; --[[User:Oleg Sychev|Oleg Sychev]] 08:52, 13 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
====A new path====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;by [[User:Mark Nielsen|Mark Nielsen]] 13:43, 13 November 2006 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After a nice discussion with [http://moodle.org/user/view.php?id=3432&amp;amp;course=5 Michael Penney], a new solution to this problem arose.  Instead of working with the current method of each question having a set of defined jumps, instead introduce a new feature called &#039;&#039;state checker&#039;&#039; (the name at the moment, could change later).  These &#039;&#039;state checkers&#039;&#039; could be inserted throughout the lesson and are used to determine the navigation.  These &#039;&#039;state checkers&#039;&#039; could be set to say, &#039;&#039;if student has more than 70% correct then send the student to location X, otherwise send student to location Y.&#039;&#039;  Alternatively, the &#039;&#039;state checker&#039;&#039; could be set to say &#039;&#039;if last question was correct, go to X otherwise go to Y&#039;&#039;.  These examples are binary, but the &#039;&#039;state checker&#039;&#039;, when fully implemented, should allow several more options and more granular control.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*No major changes are required to the question bank code.&lt;br /&gt;
*Since the navigational control logic is separate from the question logic, one cannot accidentally modify or break a lesson&#039;s navigation by editing a question. &lt;br /&gt;
*Lesson navigation can be controlled via one screen and &#039;&#039;&#039;is independent of questions&#039;&#039;&#039;.&lt;br /&gt;
*More possibilities for lesson navigation control.&lt;br /&gt;
*Could reduce the complexity of the multi-stage UI that the other solutions require.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Migration of old navigation structure could prove to be complicated depending on how the &#039;&#039;state checker&#039;&#039; would be developed (NOTE: this is already a problem.  See next section &#039;&#039;Migration of jumps&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:If State Checkers are used, then there should be an overall default for how one navigates from one page/question to the next. EG: Correct answer goes to next page in the logical order, Wrong answer goes to same page. Then one adds State Checkers to change the default navigation of the lesson.  There should be several configurable default navigations to choose from in the lesson settings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 16:17, 24 March 2007 (CDT)&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson module#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Comments on questions and jumps===&lt;br /&gt;
I think the adaptive jumps of Lesson are a key feature.  If I read the above correctly, I don&#039;t like limiting this to either a correct answer jump or a wrong answer jump.  I do like the concept of a jump form.   --[[User:chris collman|chris collman]] 09:49, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
This also begs the special navigation features used in clusters and &#039;branches&amp;quot; with end of Branch which Mark has addressed with [[Development:New_lesson_navigation#Check_Points|Check Points]] which I assume are different that State Checkers.I know nothing about elegance, and that is why I like to write about what developers have created :)--[[User:chris collman|chris collman]] 09:49, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson module#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
:Branch tables are grade neutral. That means neither 0% nor 100% credit for any answers or else it will count towards the grade/score.  I do not have a issue with a descriptive page, except I would call it a &amp;quot;Choice page&amp;quot; and make it essentially a grade neutral multiple choice question.  This would also allow graphics next to a choice, something not possible with a Branch Table.--[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
:Branch tables, offer the student choices and description question types do not offer any choices. This is a big difference.   Perhaps a description question needs the ever present &amp;quot;continue&amp;quot; choice when it will be imported into Lesson from Question Bank.--[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
:This could also make importing OOwriter and OOimpress pages easier into Lesson.  I am still hopeful that something like the GIFT format will allow pages to be imported and exported from Lesson. With the State checker and [[Development:New_lesson_navigation#Check_Points|Check Points]] kind of concepts, this would make that task easier.   Perhaps come up with some standard code to attach a state checker to the page? --[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
:Wanted to jot down a random though, a branch table could perhaps just be a visible Check Point with buttons to allow the user to choose where to go next.  More I think about this, the better it gets, code wise and lesson editing wise. [[User:Mark Nielsen|Mark Nielsen]] 12:46, 21 January 2009 (CST)&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:See discussion about making branch pages more like description questions in Quiz.  Or converting Branch tables to a grade neutral format similar to a multiple choice question, where there are no buttons but graphics are allowed.&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson module|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
*[[Development:New lesson navigation]]&lt;br /&gt;
*[[Development:Lesson Specification]]&lt;br /&gt;
*[[Development:Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer|Adding question types to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=49153</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=49153"/>
		<updated>2009-01-21T18:40:05Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added new pro: separation of logic to prevent accidently breaking lesson navigation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
Please note that this page deals with a future version of [[Roadmap#Version_2.0|Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson module]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*(Primary) Increase the usability of the lesson module by making it easier for lesson authors to construct lessons.&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**Will this include the shuffle answer option for each question, or will/can this be a Lesson setting?--[[User:chris collman|chris collman]] 08:37, 10 December 2007 (CST)&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
:Not tracking individual student answers in a lesson would clearly separate Lesson from Quiz.  I like it. I believe once we have at least some sort of course dependency in Moodle 2, this will take a great deal of pressure off of Lesson.  The course dependency setting for any activity should at least have greater, less than choices from say a score or one or more activities/resources. (this seems similar to the State Checker idea).  It would be nice if it had limited nested if/then statements to allow a ranges of dependency to be really adaptive.  This will allow the teacher to break up big lessons into smaller ones and put a real quiz/test between them.  So when the student gets a 100% on a following quiz, they go to Lesson 10, but the student who scores less than 50% goes back to the Lesson or to a special lesson before they will see Lesson 10.   Under these conditions, we can confidently get rid of a history of answered questions in Lesson, and leave that function to Quiz.   --[[User:chris collman|chris collman]] 10:06, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
*migrate lesson navigation.&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
I think you can use this without invasions. The questions contain feedback (which is a rought equivalent of outcome), and the answers with equivalent feedbacks are very likely to give equivalent jumps (if they still not, user can easily rewrite it using different words or just add some spaces or punctuation). You may not invade in the question types, but use feedback they return instead. You can use a table (apart from question editing interface) that allows author to specify jumps for feedbacks (or place jump right in feedback in some sort of you own tag - but it&#039;ll restricts using one question on several pages or lessons with different jumps). This solution is quite easy to implement, probably an easier way than anyone mentioned there.&lt;br /&gt;
&lt;br /&gt;
You can get problem with some question types using this, but they are easily solved:&lt;br /&gt;
* essay  - you probably will want to suppress using of manual graded question types in lessons anyway;&lt;br /&gt;
*multichoice in several choices mode - you can use correct/partial/incorrect feedbacks;&lt;br /&gt;
*match - it lacks feedbacks now, but probably it must have just correct/partial/incorrect as multichoice question, they are needed in it anyway, not only for the lessons.&lt;br /&gt;
&lt;br /&gt;
You may want to use feedback text only as values to communicate with user thought, replacing it in database by subquestion id or code for correct, partial or incorrect values. This allows you to avoid problems with editing feedbacks for existing questions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; --[[User:Oleg Sychev|Oleg Sychev]] 08:52, 13 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
====A new path====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;by [[User:Mark Nielsen|Mark Nielsen]] 13:43, 13 November 2006 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After a nice discussion with [http://moodle.org/user/view.php?id=3432&amp;amp;course=5 Michael Penney], a new solution to this problem arose.  Instead of working with the current method of each question having a set of defined jumps, instead introduce a new feature called &#039;&#039;state checker&#039;&#039; (the name at the moment, could change later).  These &#039;&#039;state checkers&#039;&#039; could be inserted throughout the lesson and are used to determine the navigation.  These &#039;&#039;state checkers&#039;&#039; could be set to say, &#039;&#039;if student has more than 70% correct then send the student to location X, otherwise send student to location Y.&#039;&#039;  Alternatively, the &#039;&#039;state checker&#039;&#039; could be set to say &#039;&#039;if last question was correct, go to X otherwise go to Y&#039;&#039;.  These examples are binary, but the &#039;&#039;state checker&#039;&#039;, when fully implemented, should allow several more options and more granular control.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*No major changes are required to the question bank code.&lt;br /&gt;
*Since the navigational control logic is separate from the question logic, one cannot accidentally modify or break a lesson&#039;s navigation by editing a question. &lt;br /&gt;
*Lesson navigation can be controlled via one screen and &#039;&#039;&#039;is independent of questions&#039;&#039;&#039;.&lt;br /&gt;
*More possibilities for lesson navigation control.&lt;br /&gt;
*Could reduce the complexity of the multi-stage UI that the other solutions require.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Migration of old navigation structure could prove to be complicated depending on how the &#039;&#039;state checker&#039;&#039; would be developed (NOTE: this is already a problem.  See next section &#039;&#039;Migration of jumps&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:If State Checkers are used, then there should be an overall default for how one navigates from one page/question to the next. EG: Correct answer goes to next page in the logical order, Wrong answer goes to same page. Then one adds State Checkers to change the default navigation of the lesson.  There should be several configurable default navigations to choose from in the lesson settings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 16:17, 24 March 2007 (CDT)&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson module#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Comments on questions and jumps===&lt;br /&gt;
I think the adaptive jumps of Lesson are a key feature.  If I read the above correctly, I don&#039;t like limiting this to either a correct answer jump or a wrong answer jump.  I do like the concept of a jump form.   --[[User:chris collman|chris collman]] 09:49, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
This also begs the special navigation features used in clusters and &#039;branches&amp;quot; with end of Branch which Mark has addressed with [[Development:New_lesson_navigation#Check_Points|Check Points]] which I assume are different that State Checkers.I know nothing about elegance, and that is why I like to write about what developers have created :)--[[User:chris collman|chris collman]] 09:49, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson module#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
:Branch tables are grade neutral. That means neither 0% nor 100% credit for any answers or else it will count towards the grade/score.  I do not have a issue with a descriptive page, except I would call it a &amp;quot;Choice page&amp;quot; and make it essentially a grade neutral multiple choice question.  This would also allow graphics next to a choice, something not possible with a Branch Table.--[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
:Branch tables, offer the student choices and description question types do not offer any choices. This is a big difference.   Perhaps a description question needs the ever present &amp;quot;continue&amp;quot; choice when it will be imported into Lesson from Question Bank.--[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
:This could also make importing OOwriter and OOimpress pages easier into Lesson.  I am still hopeful that something like the GIFT format will allow pages to be imported and exported from Lesson. With the State checker and [[Development:New_lesson_navigation#Check_Points|Check Points]] kind of concepts, this would make that task easier.   Perhaps come up with some standard code to attach a state checker to the page? --[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:See discussion about making branch pages more like description questions in Quiz.  Or converting Branch tables to a grade neutral format similar to a multiple choice question, where there are no buttons but graphics are allowed.&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson module|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
*[[Development:New lesson navigation]]&lt;br /&gt;
*[[Development:Lesson Specification]]&lt;br /&gt;
*[[Development:Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer|Adding question types to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=49150</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=49150"/>
		<updated>2009-01-21T17:39:29Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added usability goal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
Please note that this page deals with a future version of [[Roadmap#Version_2.0|Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson module]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*(Primary) Increase the usability of the lesson module by making it easier for lesson authors to construct lessons.&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**Will this include the shuffle answer option for each question, or will/can this be a Lesson setting?--[[User:chris collman|chris collman]] 08:37, 10 December 2007 (CST)&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
:Not tracking individual student answers in a lesson would clearly separate Lesson from Quiz.  I like it. I believe once we have at least some sort of course dependency in Moodle 2, this will take a great deal of pressure off of Lesson.  The course dependency setting for any activity should at least have greater, less than choices from say a score or one or more activities/resources. (this seems similar to the State Checker idea).  It would be nice if it had limited nested if/then statements to allow a ranges of dependency to be really adaptive.  This will allow the teacher to break up big lessons into smaller ones and put a real quiz/test between them.  So when the student gets a 100% on a following quiz, they go to Lesson 10, but the student who scores less than 50% goes back to the Lesson or to a special lesson before they will see Lesson 10.   Under these conditions, we can confidently get rid of a history of answered questions in Lesson, and leave that function to Quiz.   --[[User:chris collman|chris collman]] 10:06, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
*migrate lesson navigation.&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
I think you can use this without invasions. The questions contain feedback (which is a rought equivalent of outcome), and the answers with equivalent feedbacks are very likely to give equivalent jumps (if they still not, user can easily rewrite it using different words or just add some spaces or punctuation). You may not invade in the question types, but use feedback they return instead. You can use a table (apart from question editing interface) that allows author to specify jumps for feedbacks (or place jump right in feedback in some sort of you own tag - but it&#039;ll restricts using one question on several pages or lessons with different jumps). This solution is quite easy to implement, probably an easier way than anyone mentioned there.&lt;br /&gt;
&lt;br /&gt;
You can get problem with some question types using this, but they are easily solved:&lt;br /&gt;
* essay  - you probably will want to suppress using of manual graded question types in lessons anyway;&lt;br /&gt;
*multichoice in several choices mode - you can use correct/partial/incorrect feedbacks;&lt;br /&gt;
*match - it lacks feedbacks now, but probably it must have just correct/partial/incorrect as multichoice question, they are needed in it anyway, not only for the lessons.&lt;br /&gt;
&lt;br /&gt;
You may want to use feedback text only as values to communicate with user thought, replacing it in database by subquestion id or code for correct, partial or incorrect values. This allows you to avoid problems with editing feedbacks for existing questions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; --[[User:Oleg Sychev|Oleg Sychev]] 08:52, 13 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
====A new path====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;by [[User:Mark Nielsen|Mark Nielsen]] 13:43, 13 November 2006 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After a nice discussion with [http://moodle.org/user/view.php?id=3432&amp;amp;course=5 Michael Penney], a new solution to this problem arose.  Instead of working with the current method of each question having a set of defined jumps, instead introduce a new feature called &#039;&#039;state checker&#039;&#039; (the name at the moment, could change later).  These &#039;&#039;state checkers&#039;&#039; could be inserted throughout the lesson and are used to determine the navigation.  These &#039;&#039;state checkers&#039;&#039; could be set to say, &#039;&#039;if student has more than 70% correct then send the student to location X, otherwise send student to location Y.&#039;&#039;  Alternatively, the &#039;&#039;state checker&#039;&#039; could be set to say &#039;&#039;if last question was correct, go to X otherwise go to Y&#039;&#039;.  These examples are binary, but the &#039;&#039;state checker&#039;&#039;, when fully implemented, should allow several more options and more granular control.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*No major changes are required to the question bank code.&lt;br /&gt;
*Lesson navigation can be controlled via one screen and &#039;&#039;&#039;is independent of questions&#039;&#039;&#039;.&lt;br /&gt;
*More possibilities for lesson navigation control.&lt;br /&gt;
*Could reduce the complexity of the multi-stage UI that the other solutions require.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Migration of old navigation structure could prove to be complicated depending on how the &#039;&#039;state checker&#039;&#039; would be developed (NOTE: this is already a problem.  See next section &#039;&#039;Migration of jumps&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:If State Checkers are used, then there should be an overall default for how one navigates from one page/question to the next. EG: Correct answer goes to next page in the logical order, Wrong answer goes to same page. Then one adds State Checkers to change the default navigation of the lesson.  There should be several configurable default navigations to choose from in the lesson settings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 16:17, 24 March 2007 (CDT)&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson module#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Comments on questions and jumps===&lt;br /&gt;
I think the adaptive jumps of Lesson are a key feature.  If I read the above correctly, I don&#039;t like limiting this to either a correct answer jump or a wrong answer jump.  I do like the concept of a jump form.   --[[User:chris collman|chris collman]] 09:49, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
This also begs the special navigation features used in clusters and &#039;branches&amp;quot; with end of Branch which Mark has addressed with [[Development:New_lesson_navigation#Check_Points|Check Points]] which I assume are different that State Checkers.I know nothing about elegance, and that is why I like to write about what developers have created :)--[[User:chris collman|chris collman]] 09:49, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson module#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
:Branch tables are grade neutral. That means neither 0% nor 100% credit for any answers or else it will count towards the grade/score.  I do not have a issue with a descriptive page, except I would call it a &amp;quot;Choice page&amp;quot; and make it essentially a grade neutral multiple choice question.  This would also allow graphics next to a choice, something not possible with a Branch Table.--[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
:Branch tables, offer the student choices and description question types do not offer any choices. This is a big difference.   Perhaps a description question needs the ever present &amp;quot;continue&amp;quot; choice when it will be imported into Lesson from Question Bank.--[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
:This could also make importing OOwriter and OOimpress pages easier into Lesson.  I am still hopeful that something like the GIFT format will allow pages to be imported and exported from Lesson. With the State checker and [[Development:New_lesson_navigation#Check_Points|Check Points]] kind of concepts, this would make that task easier.   Perhaps come up with some standard code to attach a state checker to the page? --[[User:chris collman|chris collman]] 09:33, 8 November 2008 (CST)&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:See discussion about making branch pages more like description questions in Quiz.  Or converting Branch tables to a grade neutral format similar to a multiple choice question, where there are no buttons but graphics are allowed.&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson module|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
*[[Development:New lesson navigation]]&lt;br /&gt;
*[[Development:Lesson Specification]]&lt;br /&gt;
*[[Development:Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer|Adding question types to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:lib/formslib.php_Form_Definition&amp;diff=30247</id>
		<title>Development:lib/formslib.php Form Definition</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:lib/formslib.php_Form_Definition&amp;diff=30247"/>
		<updated>2007-12-14T22:30:11Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Missing $ infront of mform&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Formslib}}&lt;br /&gt;
==definition()==&lt;br /&gt;
&lt;br /&gt;
The definition of the elements to be included in the form, their &#039;types&#039; (PARAM_*), helpbuttons included, etc is all included in a function you must define in your class &#039;definition();&#039;&lt;br /&gt;
&lt;br /&gt;
definition() is used to define the elements in the form and &#039;&#039;&#039;this definition will be used for validating data submitted as well as for printing the form.&#039;&#039;&#039; For select and checkbox type elements only data that could have been selected will be allowed. And only data that corresponds to a form element in the defintion will be accepted as submitted data.&lt;br /&gt;
&lt;br /&gt;
The definition() should include all elements that are going to be used on form, some elements may be removed or tweaked later in definition_after_data(). Please do not create conditional elements in definition(), the definition() should not directly depend on the submitted data.&lt;br /&gt;
&lt;br /&gt;
==Use Fieldsets to group Form Elements==&lt;br /&gt;
&lt;br /&gt;
You use code like this to open a fieldset with a legend.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//-------------------------------------------------------------------------------&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;header&#039;, &#039;nameforyourheaderelement&#039;, get_string(&#039;titleforlegened&#039;, &#039;modulename&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can&#039;t yet nest these visible fieldsets unfortunately. But in fact groups of elements are wrapped in invisible fieldsets.&lt;br /&gt;
&lt;br /&gt;
You close a fieldset with moodle_form&#039;s closeHeaderBefore method. You tell closeHeaderBefore the element before you wish to end the fieldset. A fieldset is automatically closed if you open a new one. You need to use this code only if you want to close a fieldset and the subsequent form elements are not to be enclosed by a visible fieldset (they are still enclosed with an invisibe one with no legend) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;closeHeaderBefore(&#039;buttonar&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==addElement==&lt;br /&gt;
&lt;br /&gt;
Use the addElement method to add a an element to a form. The first few arguments are always the same. The first param is the type of the element to add. The second is the elementname to use which is normally the html name of the element in the form. The third is often the text for the label for the element.&lt;br /&gt;
&lt;br /&gt;
Some examples are below :&lt;br /&gt;
===button===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;button&#039;, &#039;intro&#039;, get_string(&amp;quot;buttonlabel&amp;quot;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A button element. If you want a submit or cancel button see &#039;submit&#039; element. &lt;br /&gt;
&lt;br /&gt;
===checkbox===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;checkbox&#039;, &#039;ratingtime&#039;, get_string(&#039;ratingtime&#039;, &#039;forum&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a simple checkbox. The third param for this element is the label to display on the left side of the form. You can also supply a string as a fourth param to specify a label that will appear on the right of the element. Checkboxes and radio buttons can be grouped and have individual labels on their right.&lt;br /&gt;
&lt;br /&gt;
====advcheckbox====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;advcheckbox&#039;, &#039;ratingtime&#039;, get_string(&#039;ratingtime&#039;, &#039;forum&#039;), array(0, 1), array(&#039;group&#039; =&amp;gt; 1));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Similar to the checkbox above, but with a couple of important improvements:&lt;br /&gt;
&lt;br /&gt;
#The 4th parameter is an array of values that will be associated with the checked/unchecked state of the checkbox. With a normal checkbox you cannot choose that value, and in fact an unchecked checkbox will not even be sent with the form data.&lt;br /&gt;
#The 5th parameter is a normal $attributes array, normally used to set HTML attributes for the &amp;lt;input&amp;gt; element. However, a special value of &#039;group&#039; can be given, which will add a class name to the element, and enable its grouping for a [[Development:lib/formslib.php_add_checkbox_controller|checkbox controller]]&lt;br /&gt;
&lt;br /&gt;
===choosecoursefile===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;choosecoursefile&#039;, &#039;mediafile&#039;, get_string(&#039;mediafile&#039;, &#039;lesson&#039;), array(&#039;courseid&#039;=&amp;gt;$COURSE-&amp;gt;id));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Choose a file from the course files area. The fourth option is a list of options for the element. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
array(&#039;courseid&#039;=&amp;gt;null,\\if it is null (default then use globabl $COURSE&lt;br /&gt;
 &#039;height&#039;=&amp;gt;500,\\ height of the popup window&lt;br /&gt;
 &#039;width&#039;=&amp;gt;750, \\ width of the popup window&lt;br /&gt;
&#039;options&#039;=&amp;gt;&#039;none&#039;);\\options string for the pop up window &lt;br /&gt;
                   \\eg. &#039;menubar=0,location=0,scrollbars,resizable&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===date_selector===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;date_selector&#039;, &#039;assesstimefinish&#039;, get_string(&#039;to&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a date selector. You can select a Day, Month and Year using a group of select boxes. The fourth param here is an array of options. The defaults for the options are :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;array(&#039;startyear&#039;=&amp;gt;1970, &#039;stopyear&#039;=&amp;gt;2020,&lt;br /&gt;
                    &#039;timezone&#039;=&amp;gt;99, &#039;applydst&#039;=&amp;gt;true);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can override these defaults by supplying an array as fourth param with one or more keys with a value to override the default. You can supply a fifth param of attributes here as well.&lt;br /&gt;
&lt;br /&gt;
===date_time_selector===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;date_time_selector&#039;, &#039;assesstimestart&#039;, get_string(&#039;from&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a group of select boxes to select a date (Day Month and Year) and time (Hour and Minute). When submitted, submitted data is processed and a timestamp is passed to $form-&amp;gt;get_data(); the fourth param here is an array of options. The defaults for the options are:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;array(&#039;startyear&#039;=&amp;gt;1970, &#039;stopyear&#039;=&amp;gt;2020,&lt;br /&gt;
                    &#039;timezone&#039;=&amp;gt;99, &#039;applydst&#039;=&amp;gt;true, &#039;step&#039;=&amp;gt;5);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can override these defaults by supplying an array as fourth param with one or more keys with a value to override the default. You can supply a fifth param of attributes here as well.&lt;br /&gt;
&lt;br /&gt;
===file===&lt;br /&gt;
&lt;br /&gt;
File upload input box with browse button. In the form definition type&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
after form submission and validation use&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
              ...&lt;br /&gt;
              $mform-&amp;gt;save_files($destination_directory);&lt;br /&gt;
              ...&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need advanced settings such as required file, different max upload size or name of uploaded file&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            $this-&amp;gt;set_upload_manager(new upload_manager(&#039;attachment&#039;, true, false, $COURSE, false, 0, true, true, false));&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;file&#039;, &#039;attachment&#039;, get_string(&#039;attachment&#039;, &#039;forum&#039;));&lt;br /&gt;
            $mform-&amp;gt;addRule(&#039;attachment&#039;, null, &#039;required&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            if ($data = $mform-&amp;gt;get_data()) {&lt;br /&gt;
              ...&lt;br /&gt;
              $mform-&amp;gt;save_files($destination_directory);&lt;br /&gt;
              $newfilename = $mform-&amp;gt;get_new_filename();&lt;br /&gt;
              ...&lt;br /&gt;
            }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When porting old code it is also possible to use the upload manager directly for processing of uploaded files.&lt;br /&gt;
&lt;br /&gt;
Please note that if using set_upload_manager() it must be before addElement(&#039;file&#039;,..).&lt;br /&gt;
&lt;br /&gt;
===hidden===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;hidden&#039;, &#039;reply&#039;, &#039;yes&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A hidden element. Set the element name (in this case &#039;&#039;&#039;reply&#039;&#039;&#039;) to the stated value (in this case &#039;&#039;&#039;yes&#039;&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
===htmleditor &amp;amp; format===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;htmleditor&#039;, &#039;text&#039;, get_string(&#039;choicetext&#039;, &#039;choice&#039;));&lt;br /&gt;
        $mform-&amp;gt;setType(&#039;text&#039;, PARAM_RAW);&lt;br /&gt;
	$mform-&amp;gt;addRule(&#039;text&#039;, null, &#039;required&#039;, null, &#039;client&#039;);&lt;br /&gt;
&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;format&#039;, &#039;format&#039;, get_string(&#039;format&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can supply a fourth param to htmleditor of an array of options :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
array(&#039;canUseHtmlEditor&#039;=&amp;gt;&#039;detect&#039;,&#039;rows&#039;=&amp;gt;10, &#039;cols&#039;=&amp;gt;65, &lt;br /&gt;
&#039;width&#039;=&amp;gt;0,&#039;height&#039;=&amp;gt;0, &#039;course&#039;=&amp;gt;0);&lt;br /&gt;
//options same as print_textarea params&lt;br /&gt;
//use rows and cols options to control htmleditor size.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===modgrade===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;modgrade&#039;, &#039;scale&#039;, get_string(&#039;grade&#039;), false);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This is a custom element for selecting a grade for any activity module. The fourth argument is whether to include an option for no grade which has a value 0. This select box does include scales. The default is true, include no grade option.&lt;br /&gt;
&lt;br /&gt;
A helpbutton is automatically added.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===password===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;password&#039;, &#039;password&#039;, get_string(&#039;label&#039;), $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A password element. Fourth param is an array or string of attributes.&lt;br /&gt;
&lt;br /&gt;
===passwordunmask===&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;passwordunmask&#039;, &#039;password&#039;, get_string(&#039;label&#039;), $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A password element with option to show the password in plaintext. Fourth param is an array or string of attributes.&lt;br /&gt;
&lt;br /&gt;
===radio===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $radioarray=array();&lt;br /&gt;
        $radioarray[] = &amp;amp;MoodleQuickForm::createElement(&#039;radio&#039;, &#039;yesno&#039;, &#039;&#039;, get_string(&#039;yes&#039;), 1, $attributes);&lt;br /&gt;
        $radioarray[] = &amp;amp;MoodleQuickForm::createElement(&#039;radio&#039;, &#039;yesno&#039;, &#039;&#039;, get_string(&#039;no&#039;), 0, $attributes);&lt;br /&gt;
        $mform-&amp;gt;addGroup($radioarray, &#039;radioar&#039;, &#039;&#039;, array(&#039; &#039;), false);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Second param names the radio button and should be the same for each button in the group in order to toggle correctly. Third param would be the label for the form element but is generally ignored as this element will always be in a group which has it&#039;s own label. Fourth param is a string, a label to be displayed on the right of the element. The fifth is the value for this radio button. $attributes can be a string or an array of attributes.&lt;br /&gt;
&lt;br /&gt;
===select===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;select&#039;, &#039;type&#039;, get_string(&#039;forumtype&#039;, &#039;forum&#039;), $FORUM_TYPES, $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The fourth param for this element is an array of options for the select box. The keys are the values for the option and the value of the array is the text for the option. The fifth param $attributes is optional, see text element for description of attributes param.&lt;br /&gt;
&lt;br /&gt;
===selectyesno===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;selectyesno&#039;, &#039;maxbytes&#039;, get_string(&#039;maxattachmentsize&#039;, &#039;forum&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want a yes / no select box this one automatically translates itself and has value 1 for yes and 0 for no.&lt;br /&gt;
&lt;br /&gt;
===static===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         $mform-&amp;gt;addElement(&#039;static&#039;, &#039;description&#039;, get_string(&#039;description&#039;, &#039;exercise&#039;),&lt;br /&gt;
                  get_string(&#039;descriptionofexercise&#039;, &#039;exercise&#039;, $COURSE-&amp;gt;students));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a static element. It should be used with care it is used to display a static piece of text with a label. The third param is the label and the fourth is the static text itself.&lt;br /&gt;
&lt;br /&gt;
===submit, reset and cancel===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        //normally you use add_action_buttons instead of this code&lt;br /&gt;
        $buttonarray=array();&lt;br /&gt;
        $buttonarray[] = &amp;amp;$mform-&amp;gt;createElement(&#039;submit&#039;, &#039;submitbutton&#039;, get_string(&#039;savechanges&#039;));&lt;br /&gt;
        $buttonarray[] = &amp;amp;$mform-&amp;gt;createElement(&#039;reset&#039;, &#039;resetbutton&#039;, get_string(&#039;revert&#039;));&lt;br /&gt;
        $buttonarray[] = &amp;amp;$mform-&amp;gt;createElement(&#039;cancel&#039;);&lt;br /&gt;
        $mform-&amp;gt;addGroup($buttonarray, &#039;buttonar&#039;, &#039;&#039;, array(&#039; &#039;), false);&lt;br /&gt;
        $mform-&amp;gt;closeHeaderBefore(&#039;buttonar&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A &#039;Submit&#039; type element is a submit type form element which will submit the form. A &#039;Reset&#039; will not submit the form but will reset any changes the user has made to form contents. A &#039;Cancel&#039; element cancels form submission. You need to have a branch in your code before you check for get_data() to check if submission has been cancelled with is_cancelled(); See the example on the usage page.&lt;br /&gt;
&lt;br /&gt;
You should name your submit and reset buttons &#039;submitbutton&#039; and &#039;resetbutton&#039; or something similar (not &#039;submit&#039; and &#039;reset&#039;). This avoids problems in JavaScript of collisions between form element names and names of JavaScript methods of the form object.&lt;br /&gt;
&lt;br /&gt;
====add_action_buttons($cancel = true, $submitlabel=null);====&lt;br /&gt;
&lt;br /&gt;
You will normally use this helper function which is a method of moodleform to add all the &#039;action&#039; buttons to the end of your form. A boolean parameter allow you to specify whether to include a cancel button and specify the label for your submit button (pass the result of get_string). Default for the submit button label is get_string(&#039;savechanges&#039;).&lt;br /&gt;
&lt;br /&gt;
===text===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;text&#039;, &#039;name&#039;, get_string(&#039;forumname&#039;, &#039;forum&#039;), $attributes);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
For a simple text element. Your fourth parameter here can be a string or array of attributes for the text element. The following are equivalent :&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $attributes=&#039;size=&amp;quot;20&amp;quot;&#039;;&lt;br /&gt;
        $attributes=array(&#039;size&#039;=&amp;gt;&#039;20&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Generally you are encouraged to use CSS instead of using attributes for styling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A format element can be used as a format select box. It will be non-selectable if you&#039;re using an html editor.&lt;br /&gt;
&lt;br /&gt;
The third param for this element is $useHtmlEditor and it defaults to null in which case an html editor is used if the browser and user profile support it.&lt;br /&gt;
&lt;br /&gt;
===textarea===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;addElement(&#039;textarea&#039;, &#039;introduction&#039;, get_string(&amp;quot;introtext&amp;quot;, &amp;quot;survey&amp;quot;), &#039;wrap=&amp;quot;virtual&amp;quot; rows=&amp;quot;20&amp;quot; cols=&amp;quot;50&amp;quot;&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A textarea element. If you want an htmleditor use htmleditor element. Fourth element here is a string or array of attributes.&lt;br /&gt;
&lt;br /&gt;
==addGroup==&lt;br /&gt;
&lt;br /&gt;
A &#039;group&#039; in formslib is just a group of elements that will have a label and will be included on one line. &lt;br /&gt;
&lt;br /&gt;
For example typical code to include a submit and cancel button on the same line : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $buttonarray=array();&lt;br /&gt;
        $buttonarray[] =&amp;amp; $mform-&amp;gt;createElement(&#039;submit&#039;, &#039;submitbutton&#039;, get_string(&#039;savechanges&#039;));&lt;br /&gt;
        $buttonarray[] =&amp;amp; $mform-&amp;gt;createElement(&#039;submit&#039;, &#039;cancel&#039;, get_string(&#039;cancel&#039;));&lt;br /&gt;
        $mform-&amp;gt;addGroup($buttonarray, &#039;buttonar&#039;, &#039;&#039;, array(&#039; &#039;), false);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You use the same arguments for createElement as you do for addElement. Any label for the element in the third argument is normally ignored (but not in the case of the submit buttons above where the third argument is not for a label but is the text for the button).&lt;br /&gt;
&lt;br /&gt;
Here&#039;s an example of putting a date_selector (which is itself a group of elements) and a checkbox on the same line, note that you can disable every element in the group using the group name &#039;availablefromgroup&#039; but it doesn&#039;t disable the controlling element the &#039;availablefromenabled&#039; checkbox:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $availablefromgroup=array();&lt;br /&gt;
	$availablefromgroup[] =&amp;amp; $mform-&amp;gt;createElement(&#039;date_selector&#039;, &#039;availablefrom&#039;, &#039;&#039;);&lt;br /&gt;
	$availablefromgroup[] =&amp;amp; $mform-&amp;gt;createElement(&#039;checkbox&#039;, &#039;availablefromenabled&#039;, &#039;&#039;, get_string(&#039;enable&#039;));&lt;br /&gt;
        $mform-&amp;gt;addGroup($availablefromgroup, &#039;availablefromgroup&#039;, get_string(&#039;availablefromdate&#039;, &#039;data&#039;), &#039;&amp;amp;nbsp;&#039;, false);&lt;br /&gt;
        $mform-&amp;gt;disabledIf(&#039;availablefromgroup&#039;, &#039;availablefromenabled&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==setHelpButton==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
            $mform-&amp;gt;setHelpButton(&#039;lessondefault&#039;, array(&#039;lessondefault&#039;, get_string(&#039;lessondefault&#039;, &#039;lesson&#039;), &#039;lesson&#039;));&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
First param is an elementname and the second param is an array of params that are passed to helpbutton in weblib.php. Params are :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 * @param string $page  The keyword that defines a help page&lt;br /&gt;
 * @param string $title The title of links, rollover tips, alt tags etc&lt;br /&gt;
 *           &#039;Help with&#039; (or the language equivalent) will be prefixed and &#039;...&#039; will be stripped.&lt;br /&gt;
 * @param string $module Which module is the page defined in&lt;br /&gt;
 * @param mixed $image Use a help image for the link?  (true/false/&amp;quot;both&amp;quot;)&lt;br /&gt;
 * @param boolean $linktext If true, display the title next to the help icon.&lt;br /&gt;
 * @param string $text If defined then this text is used in the page, and&lt;br /&gt;
 *           the $page variable is ignored.&lt;br /&gt;
 * @param boolean $return If true then the output is returned as a string, if false it is printed to the current page.&lt;br /&gt;
 * @param string $imagetext The full text for the helpbutton icon. If empty use default help.gif&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Make sure you don&#039;t set boolean $return to false. &lt;br /&gt;
&lt;br /&gt;
You need to do use this method after addElement();&lt;br /&gt;
&lt;br /&gt;
==setDefault==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        $mform-&amp;gt;addElement(&#039;select&#039;, &#039;grade&#039;, get_string(&#039;gradeforsubmission&#039;, &#039;exercise&#039;), $grades);&lt;br /&gt;
        $mform-&amp;gt;setHelpButton(&#039;grade&#039;, array(&#039;grade&#039;, get_string(&#039;gradeforsubmission&#039;, &#039;exercise&#039;), &#039;exercise&#039;));&lt;br /&gt;
        $mform-&amp;gt;setDefault(&#039;grade&#039;, 100);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Set the default of the form value with setDefault($elementname, $value); where elementname is the elementname whose default you want to set and $value is the default to set. We set the defaults for the form in definition(). This default is what is used if no data is loaded into the form with set_data(); eg. on display of the form for an &#039;add&#039; rather than &#039;update&#039; function.&lt;br /&gt;
&lt;br /&gt;
==disabledIf==&lt;br /&gt;
&lt;br /&gt;
For any element or groups of element in a form you can conditionally disable the group or individual element depending on conditions.&lt;br /&gt;
&lt;br /&gt;
You can use $mform-&amp;gt;disabledIf($elementName, $dependentOn, $condition = &#039;notchecked&#039;, $value=null)&lt;br /&gt;
&lt;br /&gt;
* elementname can be a group. If you specify a group all elements in the group will be disabled (if dependentOn is in elementname group that is ignored and not disabled). These are the element names you&#039;ve used as the first argument in addElement or addGroup.&lt;br /&gt;
* dependentOn is the actual name of the element as it will appear in html. This can be different to the name used in addGroup particularly but also addElement where you&#039;re adding a complex element like a date_selector. Check the html of your page. You typically make the depedentOn a checkbox or select box.&lt;br /&gt;
* $condition will be notchecked, checked, selected, eq or if it is anything else then we test for neq.&lt;br /&gt;
* If $condition is eq or neq then we check the value of the dependentOn field and check for equality (==) or nonequality (!=) in js&lt;br /&gt;
* If $condition is checked or notchecked then we check to see if a checkbox is checked or not.&lt;br /&gt;
* If $condition is selected then we check to see if a particular option is selected from a dropdown list.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note: I am not sure this section is complete. I just found and added one missing case, but there may be others--[[User:Tim Hunt|Tim Hunt]] 06:04, 15 October 2007 (CDT)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==setType==&lt;br /&gt;
&lt;br /&gt;
PARAM_* types are used to specify how a submitted variable should be cleaned. These should be used for get parameters such as id, course etc. which are used to load a page and also with setType(); method. Every form element should have a type specified except select, radio box and checkbox elements, these elements do a good job of cleaning themselves (only specified options are allowed as user input).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Most Commonly Used PARAM_* Types===&lt;br /&gt;
&lt;br /&gt;
These are the most commonly used PARAM_* types and their proper uses. More types can be seen in moodlelib.php starting around line 100.&lt;br /&gt;
&lt;br /&gt;
* PARAM_CLEAN is deprecated and you should try to use a more specific type.&lt;br /&gt;
* PARAM_TEXT should be used for cleaning data that is expected to be plain text. It will strip all html tags. But will still let tags for multilang support through.&lt;br /&gt;
* PARAM_NOTAGS should be used for cleaning data that is expected to be plain text. It will strip *all* html type tags. It will still *not* let tags for multilang support through. This should be used for instance for email addresses where no multilang support is appropriate.&lt;br /&gt;
* PARAM_RAW means no cleaning whatsoever, it is used mostly for data from the html editor. Data from the editor is later cleaned before display using format_text() function. PARAM_RAW can also be used for data that is validated by some other way or printed by p() or s().&lt;br /&gt;
* PARAM_INT should be used for integers.&lt;br /&gt;
* PARAM_ACTION is an alias of PARAM_ALPHA and is used for hidden fields specifying form actions.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
* [http://midnighthax.com/quickform.php PEAR HTML QuickForm Getting Started Guide by Keith Edmunds of Midnighthax.com]&lt;br /&gt;
&lt;br /&gt;
[[Category:Formslib]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=23769</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=23769"/>
		<updated>2007-05-28T08:50:18Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson and to reduce the number of lesson settings, which are numerous, then block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks goals==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
Added in Moodle 1.9.  Please note that the global configuration to disable blocks was not implemented.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After exploring the code, I found that currently the page API does not support this idea. - [[User:Mark Nielsen|Mark Nielsen]] 18:14, 24 March 2007 (CDT)&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks ==&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
To add blocks to lesson, just go to the &amp;quot;Preview&amp;quot; tab and turn block editing on by clicking on the &amp;quot;Blocks editing on&amp;quot; button in the upper right hand corner. &lt;br /&gt;
[[Image:Lesson Preview BlocksEditingOn button.JPG|center|thumb|Example of buttons]]&lt;br /&gt;
&lt;br /&gt;
*The only quirk is if you answer a question and are on the feedback screen and then push the &amp;quot;Blocks editing on/off&amp;quot; button, you go back to the question that you just answered.&lt;br /&gt;
&lt;br /&gt;
[[Image:Lesson Blocks pulldown Menu.JPG|center|thumb|Example of pulldown menu in lesson]]&lt;br /&gt;
&lt;br /&gt;
Before you can add blocks, be sure that &amp;quot;Show blocks on module pages&amp;quot; is turned on in the administrative settings area. Hint: search for showblocksonmodpages&lt;br /&gt;
&lt;br /&gt;
[http://moodle.org/mod/forum/post.php?reply=304539 Forum thread by Mark Nielsen, developer]&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
*Reduce lesson&#039;s code base.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Adding blocks to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=21789</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=21789"/>
		<updated>2007-03-24T23:14:43Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Sticky blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson and to reduce the number of lesson settings, which are numerous, then block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
Added in Moodle 1.9.  Please note that the global configuration to disable blocks was not implemented.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After exploring the code, I found that currently the page API does not support this idea. - [[User:Mark Nielsen|Mark Nielsen]] 18:14, 24 March 2007 (CDT)&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
*Reduce lesson&#039;s code base.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Adding blocks to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=21788</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=21788"/>
		<updated>2007-03-24T23:12:09Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Other blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson and to reduce the number of lesson settings, which are numerous, then block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
{{Moodle 1.9}}&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
Added in Moodle 1.9.  Please note that the global configuration to disable blocks was not implemented.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
*Reduce lesson&#039;s code base.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer|Adding blocks to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=21787</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=21787"/>
		<updated>2007-03-24T21:36:00Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Possible uses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student received 100% of the possible points on the last question, go to &#039;&#039;this&#039;&#039; page.  If 99% to 60%, go to &#039;&#039;this&#039;&#039; page.  If less than 60%, go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced with Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class more natural.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=21786</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=21786"/>
		<updated>2007-03-24T21:35:20Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Possible uses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student received 100% of the possible points, go to &#039;&#039;this&#039;&#039; page.  If 99% to 60%, go to &#039;&#039;this&#039;&#039; page.  If less than 60%, go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced with Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class more natural.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=21784</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=21784"/>
		<updated>2007-03-24T21:17:56Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added a comment to state checkers solution&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
*migrate lesson navigation.&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
====A new path====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;by [[User:Mark Nielsen|Mark Nielsen]] 13:43, 13 November 2006 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After a nice discussion with [http://moodle.org/user/view.php?id=3432&amp;amp;course=5 Michael Penney], a new solution to this problem arose.  Instead of working with the current method of each question having a set of defined jumps, instead introduce a new feature called &#039;&#039;state checker&#039;&#039; (the name at the moment, could change later).  These &#039;&#039;state checkers&#039;&#039; could be inserted throughout the lesson and are used to determine the navigation.  These &#039;&#039;state checkers&#039;&#039; could be set to say, &#039;&#039;if student has more than 70% correct then send the student to location X, otherwise send student to location Y.&#039;&#039;  Alternatively, the &#039;&#039;state checker&#039;&#039; could be set to say &#039;&#039;if last question was correct, go to X otherwise go to Y&#039;&#039;.  These examples are binary, but the &#039;&#039;state checker&#039;&#039;, when fully implemented, should allow several more options and more granular control.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*No major changes are required to the question bank code.&lt;br /&gt;
*Lesson navigation can be controlled via one screen and &#039;&#039;&#039;is independent of questions&#039;&#039;&#039;.&lt;br /&gt;
*More possibilities for lesson navigation control.&lt;br /&gt;
*Could reduce the complexity of the multi-stage UI that the other solutions require.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Migration of old navigation structure could prove to be complicated depending on how the &#039;&#039;state checker&#039;&#039; would be developed (NOTE: this is already a problem.  See next section &#039;&#039;Migration of jumps&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:If State Checkers are used, then there should be an overall default for how one navigates from one page/question to the next. EG: Correct answer goes to next page in the logical order, Wrong answer goes to same page. Then one adds State Checkers to change the default navigation of the lesson.  There should be several configurable default navigations to choose from in the lesson settings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 16:17, 24 March 2007 (CDT)&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer|Adding question types to lesson]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Capabilities/block/quickmail:cansend&amp;diff=20989</id>
		<title>Capabilities/block/quickmail:cansend</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Capabilities/block/quickmail:cansend&amp;diff=20989"/>
		<updated>2007-03-01T22:05:48Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If a user has this capability, then s/he can see the Quickmail block in the course and use it to send emails to other users in the same course.&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Blocks&amp;diff=19183</id>
		<title>Development:Blocks</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Blocks&amp;diff=19183"/>
		<updated>2007-01-08T20:10:44Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Fixed example code for the config_global.html (added pre tags)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039; A Step-by-step Guide To Creating Blocks &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Original Author: Jon Papaioannou (pj@uom.gr)&lt;br /&gt;
&lt;br /&gt;
The present document serves as a guide to developers who want to create their own blocks for use in Moodle. It applies to the 1.5 development version of Moodle (and any newer) &#039;&#039;&#039;only&#039;&#039;&#039;, as the blocks subsystem was rewritten and expanded for the 1.5 release. However, you can also find it useful if you want to modify blocks written for Moodle 1.3 and 1.4 to work with the latest versions (look at [[Blocks_Howto#appendix_b| Appendix B]]).&lt;br /&gt;
The guide is written as an interactive course which aims to develop a configurable, multi-purpose block that displays arbitrary HTML. It&#039;s targeted mainly at people with little experience with Moodle or programming in general and aims to show how easy it is to create new blocks for Moodle. A certain small amount of PHP programming knowledge is still required, though. Experienced developers and those who just want a reference text should refer to [[Blocks_Howto#appendix_a| Appendix A]] because the main guide has a rather low concentration of pure information in the text.&lt;br /&gt;
&lt;br /&gt;
== Basic Concepts ==&lt;br /&gt;
Through this guide, we will be following the creation of an &amp;quot;HTML&amp;quot; block from scratch in order to demonstrate most of the block features at our disposal. Our block will be named &amp;quot;SimpleHTML&amp;quot;. This does not constrain us regarding the name of the actual directory on the server where the files for our block will be stored, but for consistency we will follow the practice of using the lowercased form &amp;quot;simplehtml&amp;quot; in any case where such a name is required. Whenever we refer to a file or directory name which contains &amp;quot;simplehtml&amp;quot;, it&#039;s important to remember that &#039;&#039;only&#039;&#039; the &amp;quot;simplehtml&amp;quot; part is up to us to change; the rest is standardized and essential for Moodle to work correctly.&lt;br /&gt;
Whenever a file&#039;s path is mentioned in this guide, it will always start with a slash. This refers to the Moodle home directory; all files and directories will be referred to with respect to that directory.&lt;br /&gt;
&lt;br /&gt;
== Ready, Set, Go! ==&lt;br /&gt;
To define a &amp;quot;block&amp;quot; in Moodle, in the most basic case we need to provide just one source code file. We start by creating the directory &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/&amp;lt;/span&amp;gt; and creating a file named &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/block_simplehtml.php&amp;lt;/span&amp;gt; which will hold our code. We then begin coding the block:&lt;br /&gt;
 class block_simplehtml extends block_base {&lt;br /&gt;
     function init() {&lt;br /&gt;
         $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
         $this-&amp;gt;version = 2004111200;&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
The first line is our block class definition; it must be named exactly in the manner shown. Again, only the &amp;quot;simplehtml&amp;quot; part can (and indeed must) change; everything else is standardized.&lt;br /&gt;
Our class is then given a small method: [[Blocks_Howto#method_init| init]]. This is essential for all blocks, and its purpose is to set the two class member variables listed inside it. But what do these values actually mean? Here&#039;s a more detailed description.&lt;br /&gt;
[[Blocks_Howto#variable_title| $this-&amp;gt;title]] is the title displayed in the header of our block. We can set it to whatever we like; in this case it&#039;s set to read the actual title from a language file we are presumably distributing together with the block. I &#039;ll skip ahead a bit here and say that if you want your block to display &#039;&#039;&#039;no&#039;&#039;&#039; title at all, then you should set this to any descriptive value you want (but &#039;&#039;&#039;not&#039;&#039;&#039; make it an empty string). We will later see [[Blocks_Howto#section_eye_candy| how to disable the title&#039;s display]].&lt;br /&gt;
[[Blocks_Howto#variable_version| $this-&amp;gt;version]] is the version of our block. This actually would only make a difference if your block wanted to keep its own data in special tables in the database (i.e. for very complex blocks). In that case the version number is used exactly as it&#039;s used in activities; an upgrade script uses it to incrementally upgrade an &amp;quot;old&amp;quot; version of the block&#039;s data to the latest. We will outline this process further ahead, since blocks tend to be relatively simple and not hold their own private data. In our example, &lt;br /&gt;
this is certainly the case so we just set [[Blocks_Howto#variable_version| $this-&amp;gt;version]] to &#039;&#039;&#039;YYYYMMDD00&#039;&#039;&#039; and forget about it.&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; Prior to version 1.5, the basic structure of each block class was slightly different. Refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
== I Just Hear Static ==&lt;br /&gt;
In order to get our block to actually display something on screen, we need to add one more method to our class (before the final closing brace in our file). The new code is:&lt;br /&gt;
 function get_content() {&lt;br /&gt;
     if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
         return $this-&amp;gt;content;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     $this-&amp;gt;content = new stdClass;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;text = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
     return $this-&amp;gt;content;&lt;br /&gt;
 }&lt;br /&gt;
It can&#039;t get any simpler than that, can it? Let&#039;s dissect this method to see what&#039;s going on...&lt;br /&gt;
First of all, there is a check that returns the current value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] if it&#039;s not NULL; otherwise we proceed with &amp;quot;computing&amp;quot; it. Since the computation is potentially a time-consuming operation and it &#039;&#039;&#039;will&#039;&#039;&#039; be called several times for each block (Moodle works that way internally), we take a precaution and include this time-saver.&lt;br /&gt;
Supposing the content had not been computed before (it was NULL), we then define it from scratch. The code speaks for itself there, so there isn&#039;t much to say. Just keep in mind that we can use HTML both in the text &#039;&#039;&#039;and&#039;&#039;&#039; in the footer, if we want to.&lt;br /&gt;
At this point our block should be capable of being automatically installed in Moodle and added to courses; visit your administration page to install it and after seeing it in action come back to continue our tutorial.&lt;br /&gt;
== Configure That Out ==&lt;br /&gt;
The current version of our block doesn&#039;t really do much; it just displays a fixed message, which is not very useful. What we &#039;d really like to do is allow the teachers to customize what goes into the block. This, in block-speak, is called &amp;quot;instance configuration&amp;quot;. So let&#039;s give our block some instance configuration...&lt;br /&gt;
First of all, we need to tell Moodle that we want it to provide instance-specific configuration amenities to our block. That&#039;s as simple as adding one more method to our block class:&lt;br /&gt;
 function instance_allow_config() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
This small change is enough to make Moodle display an &amp;quot;Edit...&amp;quot; icon in our block&#039;s header when we turn editing mode on in any course. However, if you try to click on that icon you will be presented with a notice that complains about the block&#039;s configuration not being implemented correctly. Try it, it&#039;s harmless.&lt;br /&gt;
Moodle&#039;s complaints do make sense. We told it that we want to have configuration, but we didn&#039;t say &#039;&#039;what&#039;&#039; kind of configuration we want, or how it should be displayed. To do that, we need to create one more file: &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt; (which has to be named exactly like that). For the moment, copy paste the following into it and save:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;table cellpadding=&amp;quot;9&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;?php print_string(&#039;configcontent&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&lt;br /&gt;
     &amp;lt;/td&amp;gt;&lt;br /&gt;
     &amp;lt;td&amp;gt;&lt;br /&gt;
         &amp;lt;?php print_textarea(true, 10, 50, 0, 0, &#039;text&#039;, $this-&amp;gt;config-&amp;gt;text); ?&amp;gt;&lt;br /&gt;
     &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;tr&amp;gt;&lt;br /&gt;
     &amp;lt;td colspan=&amp;quot;2&amp;quot; align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;) ?&amp;gt;&amp;quot; /&amp;gt;&lt;br /&gt;
     &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
 &amp;lt;?php use_html_editor(); ?&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
It isn&#039;t difficult to see that the above code just provides us with a wysiwyg-editor-enabled textarea to write our block&#039;s desired content in and a submit button to save. But... what&#039;s $this-&amp;gt;config-&amp;gt;text? Well...&lt;br /&gt;
Moodle goes a long way to make things easier for block developers. Did you notice that the textarea is actually named &amp;quot;text&amp;quot;? When the submit button is pressed, Moodle saves each and every field it can find in our &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file as instance configuration data. We can then access that data as &#039;&#039;&#039;$this-&amp;gt;config-&amp;gt;&#039;&#039;variablename&#039;&#039;&#039;&#039;&#039;, where &#039;&#039;variablename&#039;&#039; is the actual name we used for our field; in this case, &amp;quot;text&amp;quot;. So in essence, the above form just pre-populates the textarea with the current content of the block (as indeed it should) and then allows us to change it.&lt;br /&gt;
You also might be surprised by the presence of a submit button and the absence of any &amp;lt;form&amp;gt; element at the same time. But the truth is, we don&#039;t need to worry about that at all; Moodle goes a really long way to make things easier for developers! We just print the configuration options we want, in any format we want; include a submit button, and Moodle will handle all the rest itself. The instance configuration variables are automatically at our disposal to access from any of the class methods &#039;&#039;except&#039;&#039; [[Blocks_Howto#method_init| init]].&lt;br /&gt;
In the event where the default behavior is not satisfactory, we can still override it. However, this requires advanced modifications to our block class and will not be covered here; refer to [[Blocks_Howto#appendix_a| Appendix A]] for more details.&lt;br /&gt;
Having now the ability to refer to this instance configuration data through [[Blocks_Howto#variable_config| $this-&amp;gt;config]], the final twist is to tell our block to actually &#039;&#039;display&#039;&#039; what is saved in is configuration data. To do that, find this snippet in &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/block_simplehtml.php&amp;lt;/span&amp;gt;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text = &#039;The content of our SimpleHTML block!&#039;;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
and change it to:&lt;br /&gt;
 &lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
Oh, and since the footer isn&#039;t really exciting at this point, we remove it from our block because it doesn&#039;t contribute anything. We could just as easily have decided to make the footer configurable in the above way, too. So for our latest code, the snippet becomes:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 $this-&amp;gt;content = new stdClass;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;text = $this-&amp;gt;config-&amp;gt;text;&lt;br /&gt;
 $this-&amp;gt;content-&amp;gt;footer = &#039;&#039;;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
After this discussion, our block is ready for prime time! Indeed, if you now visit any course with a SimpleHTML block, you will see that modifying its contents is now a snap.&lt;br /&gt;
&lt;br /&gt;
== The Specialists ==&lt;br /&gt;
Implementing instance configuration for the block&#039;s contents was good enough to whet our appetite, but who wants to stop there? Why not customize the block&#039;s title, too?&lt;br /&gt;
Why not, indeed. Well, our first attempt to achieve this is natural enough: let&#039;s add another field to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_instance.html&amp;lt;/span&amp;gt;. Here goes:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;p&amp;gt;&amp;lt;?php print_string(&#039;configtitle&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;:&amp;lt;/td&amp;gt;&lt;br /&gt;
     &amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;title&amp;quot; size=&amp;quot;30&amp;quot; value=&amp;quot;&amp;lt;?php echo $this-&amp;gt;config-&amp;gt;title; ?&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
We save the edited file, go to a course, edit the title of the block and... nothing happens! The instance configuration is saved correctly, all right (editing it once more proves that) but it&#039;s not being displayed. All we get is just the simple &amp;quot;SimpleHTML&amp;quot; title.&lt;br /&gt;
That&#039;s not too wierd, if we think back a bit. Do you remember that [[Blocks_Howto#method_init| init]] method, where we set [[Blocks_Howto#variable_title| $this-&amp;gt;title]]? We didn&#039;t actually change its value from then, and [[Blocks_Howto#variable_title| $this-&amp;gt;title]] is definitely not the same as $this-&amp;gt;config-&amp;gt;title (to Moodle, at least). What we need is a way to update [[Blocks_Howto#variable_title| $this-&amp;gt;title]] with the value in the instance configuration. But as we said a bit earlier, we can use [[Blocks_Howto#variable_config| $this-&amp;gt;config]] in all methods &#039;&#039;except&#039;&#039; [[Blocks_Howto#method_init| init]]&amp;lt;nowiki&amp;gt;! So what can we do?&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Let&#039;s pull out another ace from our sleeve, and add this small method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function specialization() {&lt;br /&gt;
     $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;title;&lt;br /&gt;
 }&lt;br /&gt;
Aha, here&#039;s what we wanted to do all along! But what&#039;s going on with the [[Blocks_Howto#method_specialization| specialization]] method?&lt;br /&gt;
This &amp;quot;magic&amp;quot; method has actually a very nice property: it&#039;s &#039;&#039;guaranteed&#039;&#039; to be automatically called by Moodle as soon as our instance configuration is loaded and available (that is, immediately after [[Blocks_Howto#method_init| init]] is called). That means before the block&#039;s content is computed for the first time, and indeed before &#039;&#039;anything&#039;&#039; else is done with the block. Thus, providing a [[Blocks_Howto#method_specialization| specialization]] method is the natural choice for any configuration data that needs to be acted upon &amp;quot;as soon as possible&amp;quot;, as in this case.&lt;br /&gt;
&lt;br /&gt;
== Now You See Me, Now You Don&#039;t ==&lt;br /&gt;
Now would be a good time to mention another nifty technique that can be used in blocks, and which comes in handy quite often. Specifically, it may be the case that our block will have something interesting to display some of the time; but in some other cases, it won&#039;t have anything useful to say. (An example here would be the &amp;quot;Recent Activity&amp;quot; block, in the case where no recent activity in fact exists. However in that case the block chooses to explicitly inform you of the lack of said activity, which is arguably useful). It would be nice, then, to be able to have our block &amp;quot;disappear&amp;quot; if it&#039;s not needed to display it.&lt;br /&gt;
This is indeed possible, and the way to do it is to make sure that after the [[Blocks_Howto#method_get_content| get_content]]&amp;lt;nowiki&amp;gt; method is called, the block is completely void of content. Specifically, &amp;quot;void of content&amp;quot; means that both $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer are each equal to the empty string (&#039;&#039;). Moodle performs this check by calling the block&#039;s &amp;lt;/nowiki&amp;gt;[[Blocks_Howto#method_is_empty| is_empty()]] method, and if the block is indeed empty then it is not displayed at all.&lt;br /&gt;
Note that the exact value of the block&#039;s title and the presence or absence of a [[Blocks_Howto#method_hide_header| hide_header]] method do &#039;&#039;not&#039;&#039; affect this behavior. A block is considered empty if it has no content, irrespective of anything else.&lt;br /&gt;
== We Are Legion ==&lt;br /&gt;
Right now our block is fully configurable, both in title and content. It&#039;s so versatile, in fact, that we could make pretty much anything out of it. It would be really nice to be able to add multiple blocks of this type to a single course. And, as you might have guessed, doing that is as simple as adding another small method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function instance_allow_multiple() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
This tells Moodle that it should allow any number of instances of the SimpleHTML block in any course. After saving the changes to our file, Moodle immediately allows us to add multiple copies of the block without further ado!&lt;br /&gt;
There are a couple more of interesting points to note here. First of all, even if a block itself allows multiple instances in the same page, the administrator still has the option of disallowing such behavior. This setting can be set separately for each block from the Administration / Configuration / Blocks page.&lt;br /&gt;
And finally, a nice detail is that as soon as we defined an [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] method, the method [[Blocks_Howto#method_instance_allow_config| instance_allow_config]] that was already defined became obsolete. Moodle assumes that if a block allows multiple instances of itself, those instances will want to be configured (what is the point of same multiple instances in the same page if they are identical?) and thus automatically provides an &amp;quot;Edit&amp;quot; icon. So, we can also remove the whole [[Blocks_Howto#method_instance_allow_config| instance_allow_config]] method now without harm. We had only needed it when multiple instances of the block were not allowed.&lt;br /&gt;
== The Effects of Globalization ==&lt;br /&gt;
Configuring each block instance with its own personal data is cool enough, but sometimes administrators need some way to &amp;quot;touch&amp;quot; all instances of a specific block at the same time. In the case of our SimpleHTML block, a few settings that would make sense to apply to all instances aren&#039;t that hard to come up with. For example, we might want to limit the contents of each block to only so many characters, or we might have a setting that filters HTML out of the block&#039;s contents, only allowing pure text in. Granted, such a feature wouldn&#039;t win us any awards for naming our block &amp;quot;SimpleHTML&amp;quot; but some tormented administrator somewhere might actually find it useful.&lt;br /&gt;
This kind of configuration is called &amp;quot;global configuration&amp;quot; and applies only to a specific block type (all instances of that block type are affected, however). Implementing such configuration for our block is quite similar to implementing the instance configuration. We will now see how to implement the second example, having a setting that only allows text and not HTML in the block&#039;s contents.&lt;br /&gt;
First of all, we need to tell Moodle that we want our block to provide global configuration by, what a surprise, adding a small method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function has_config() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
Then, we need to create a HTML file that actually prints out the configuration screen. In our case, we &#039;ll just print out a checkbox saying &amp;quot;Do not allow HTML in the content&amp;quot; and a &amp;quot;submit&amp;quot; button. Let&#039;s create the file &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/blocks/simplehtml/config_global.html&amp;lt;/span&amp;gt; which again must be named just so, and copy paste the following into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 &amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;block_simplehtml_strict&amp;quot; value=&amp;quot;1&amp;quot;&lt;br /&gt;
   &amp;lt;?php if(!empty($CFG-&amp;gt;block_simplehtml_strict)) echo &#039;checked=&amp;quot;checked&amp;quot;&#039;; ?&amp;gt; /&amp;gt;&lt;br /&gt;
 &amp;lt;?php print_string(&#039;donotallowhtml&#039;, &#039;block_simplehtml&#039;); ?&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;&amp;lt;?php print_string(&#039;savechanges&#039;); ?&amp;gt;&amp;quot; /&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
True to our block&#039;s name, this looks simple enough. What it does is that it displays a checkbox named &amp;quot;block_simplehtml_strict&amp;quot; and if the Moodle configuration variable with the same name (i.e., $CFG-&amp;gt;block_simplehtml_strict) is set and not empty (that means it&#039;s not equal to an empty string, to zero, or to boolean false) it displays the box as pre-checked (reflecting the current status). Why does it check the configuration setting with the same name? Because the default implementation of the global configuration saving code takes all the variables we have in our form and saves them as Moodle configuration options with the same name. Thus, it&#039;s good practice to use a descriptive name and also one that won&#039;t possibly conflict with the name of another setting. &amp;quot;block_simplehtml_strict&amp;quot; clearly satisfies both requirements.&lt;br /&gt;
The astute reader may have noticed that we actually have &#039;&#039;two&#039;&#039; input fields named &amp;quot;block_simplehtml_strict&amp;quot; in our configuration file. One is hidden and its value is always 0; the other is the checkbox and its value is 1. What gives? Why have them both there?&lt;br /&gt;
Actually, this is a small trick we use to make our job as simple as possible. HTML forms work this way: if a checkbox in a form is not checked, its name does not appear at all in the variables passed to PHP when the form is submitted. That effectively means that, when we uncheck the box and click submit, the variable is not passed to PHP at all. Thus, PHP does not know to update its value to &amp;quot;0&amp;quot;, and our &amp;quot;strict&amp;quot; setting cannot be turned off at all once we turn it on for the first time. Not the behavior we want, surely.&lt;br /&gt;
However, when PHP handles received variables from a form, the variables are processed in the order in which they appear in the form. If a variable comes up having the same name with an already-processed variable, the new value overwrites the old one. Taking advantage of this, our logic runs as follows: the variable &amp;quot;block_simplehtml_strict&amp;quot; is first unconditionally set to &amp;quot;0&amp;quot;. Then, &#039;&#039;if&#039;&#039; the box is checked, it is set to &amp;quot;1&amp;quot;, overwriting the previous value as discussed. The net result is that our configuration setting behaves as it should.&lt;br /&gt;
To round our bag of tricks up, notice that the use of if(!empty($CFG-&amp;gt;block_simplehtml_strict)) in the test for &amp;quot;should the box be checked by default?&amp;quot; is quite deliberate. The first time this script runs, the variable $CFG-&amp;gt;block_simplehtml_strict will not exist at all. After it&#039;s set for the first time, its value can be either &amp;quot;0&amp;quot; or &amp;quot;1&amp;quot;. Given that both &amp;quot;not set&amp;quot; and the string &amp;quot;0&amp;quot; evaluate as empty while the sting &amp;quot;1&amp;quot; does not, we manage to avoid any warnings from PHP regarding the variable not being set at all, &#039;&#039;and&#039;&#039; have a nice human-readable representation for its two possible values (&amp;quot;0&amp;quot; and &amp;quot;1&amp;quot;).&lt;br /&gt;
Now that we have managed to cram a respectable amount of tricks into a few lines of HTML, we might as well discuss the alternative in case that tricks are not enough for a specific configuration setup we have in mind. Saving the data is done in the method [[Blocks_Howto#method_config_save| config_save]], the default implementation of which is as follows:&lt;br /&gt;
 &lt;br /&gt;
 function config_save($data) {&lt;br /&gt;
     // Default behavior: save all variables as $CFG properties&lt;br /&gt;
     foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
         set_config($name, $value);&lt;br /&gt;
     }&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
As can be clearly seen, Moodle passes this method an associative array $data which contains all the variables coming in from our configuration screen. If we wanted to do the job without the &amp;quot;hidden variable with the same name&amp;quot; trick we used above, one way to do it would be by overriding this method with the following:&lt;br /&gt;
 &lt;br /&gt;
 function config_save($data) {&lt;br /&gt;
     if(isset($data[&#039;block_simplehtml_strict&#039;])) {&lt;br /&gt;
         set_config(&#039;block_simplehtml_strict&#039;, &#039;1&#039;);&lt;br /&gt;
     }&lt;br /&gt;
     else {&lt;br /&gt;
         set_config(&#039;block_simplehtml_strict&#039;, &#039;0&#039;);&lt;br /&gt;
     }&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
Quite straightfoward: if the variable &amp;quot;block_simplehtml_strict&amp;quot; is passed to us, then it can only mean that the user has checked it, so set the configuration variable with the same name to &amp;quot;1&amp;quot;. Otherwise, set it to &amp;quot;0&amp;quot;. Of course, this version would need to be updated if we add more configuration options because it doesn&#039;t respond to them as the default implementation does. Still, it&#039;s useful to know how we can override the default implementation if it does not fit our needs (for example, we might not want to save the variable as part of the Moodle configuration but do something else with it).&lt;br /&gt;
So, we are now at the point where we know if the block should allow HTML tags in its content or not. How do we get the block to actually respect that setting?&lt;br /&gt;
We could decide to do one of two things: either have the block &amp;quot;clean&amp;quot; HTML out from the input before saving it in the instance configuration and then display it as-is (the &amp;quot;eager&amp;quot; approach); or have it save the data &amp;quot;as is&amp;quot; and then clean it up each time just before displaying it (the &amp;quot;lazy&amp;quot; approach). The eager approach involves doing work once when saving the configuration; the lazy approach means doing work each time the block is displayed and thus it promises to be worse performance-wise. We shall hence go with the eager approach.&lt;br /&gt;
Much as we did just before with overriding [[Blocks_Howto#method_config_save| config_save]], what is needed here is overriding the method [[Blocks_Howto#method_instance_config_save| instance_config_save]] which handles the instance configuration. The default implementation is as follows:&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_save($data) {&lt;br /&gt;
     $data = stripslashes_recursive($data);&lt;br /&gt;
     $this-&amp;gt;config = $data;&lt;br /&gt;
     return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
 }&lt;br /&gt;
This may look intimidating at first (what&#039;s all this stripslashes_recursive() and base64_encode() and serialize() stuff?) but do not despair; we won&#039;t have to touch any of it. We will only add some extra validation code in the beginning and then instruct Moodle to additionally call this default implementation to do the actual storing of the data. Specifically, we will add a method to our class which goes like this:&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_save($data) {&lt;br /&gt;
     // Clean the data if we have to&lt;br /&gt;
     global $CFG;&lt;br /&gt;
     if(!empty($CFG-&amp;gt;block_simplehtml_strict)) {&lt;br /&gt;
         $data[&#039;text&#039;] = strip_tags($data[&#039;text&#039;]);&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     // And now forward to the default implementation defined in the parent class&lt;br /&gt;
     return parent::instance_config_save($data);&lt;br /&gt;
 }&lt;br /&gt;
At last! Now the administrator has absolute power of life and death over what type of content is allowed in our &amp;quot;SimpleHTML&amp;quot; block! Absolute? Well... not exactly. In fact, if we think about it for a while, it will become apparent that if at some point in time HTML is allowed and some blocks have saved their content with HTML included, and afterwards the administrator changes the setting to &amp;quot;off&amp;quot;, this will only prevent subsequent content changes from including HTML. Blocks which already had HTML in their content would continue to display it!&lt;br /&gt;
Following that train of thought, the next stop is realizing that we wouldn&#039;t have this problem if we had chosen the lazy approach a while back, because in that case we would &amp;quot;sanitize&amp;quot; each block&#039;s content just before it was displayed. The only thing we can do with the eager approach is strip all the tags from the content of all SimpleHTML instances as soon as the admin setting is changed to &amp;quot;HTML off&amp;quot;; but even then, turning the setting back to &amp;quot;HTML on&amp;quot; won&#039;t bring back the tags we stripped away. On the other hand, the lazy approach might be slower, but it&#039;s more versatile; we can choose whether to strip or keep the HTML before displaying the content, and we won&#039;t lose it at all if the admin toggles the setting off and on again. Isn&#039;t the life of a developer simple and wonderful?&lt;br /&gt;
We will let this part of the tutorial come to a close with the obligatory excercise for the reader: in order to have the SimpleHTML block work &amp;quot;correctly&amp;quot;, find out how to strengthen the eager approach to strip out all tags from the existing configuration of all instances of our block, &#039;&#039;&#039;or&#039;&#039;&#039; go back and implement the lazy approach instead. (Hint: do that in the [[Blocks_Howto#method_get_content| get_content]] method)&lt;br /&gt;
&#039;&#039;&#039;UPDATING&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;: Prior to version 1.5, the file &amp;lt;/nowiki&amp;gt;&amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_global.html&amp;lt;/span&amp;gt; was named simply &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config.html&amp;lt;/span&amp;gt;. Also, the methods [[Blocks_Howto#method_config_save| config_save]] and [[Blocks_Howto#method_config_print| config_print]] were named &#039;&#039;&#039;handle_config&#039;&#039;&#039; and &#039;&#039;&#039;print_config&#039;&#039;&#039; respectively. Upgrading a block to work with Moodle 1.5 involves updating these aspects; refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Eye Candy ==&lt;br /&gt;
Our block is just about complete functionally, so now let&#039;s take a look at some of the tricks we can use to make its behavior customized in a few more useful ways.&lt;br /&gt;
First of all, there are a couple of ways we can adjust the visual aspects of our block. For starters, it might be useful to create a block that doesn&#039;t display a header (title) at all. You can see this effect in action in the Course Description block that comes with Moodle. This behavior is achieved by, you guessed it, adding one more method to our block class:&lt;br /&gt;
 &lt;br /&gt;
 function hide_header() {&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
One more note here: we cannot just set an empty title inside the block&#039;s [[Blocks_Howto#method_init| init]] method; it&#039;s necessary for each block to have a unique, non-empty title after [[Blocks_Howto#method_init| init]] is called so that Moodle can use those titles to differentiate between all of the installed blocks.&lt;br /&gt;
Another adjustment we might want to do is instruct our block to take up a certain amount of width on screen. Moodle handles this as a two-part process: first, it queries each block about its preferred width and takes the maximum number as the desired value. Then, the page that&#039;s being displayed can choose to use this value or, more probably, bring it within some specific range of values if it isn&#039;t already. That means that the width setting is a best-effort settlement; your block can &#039;&#039;request&#039;&#039; a certain width and Moodle will &#039;&#039;try&#039;&#039; to provide it, but there&#039;s no guarantee whatsoever about the end result. As a concrete example, all standard Moodle course formats will deliver any requested width between 180 and 210 pixels, inclusive.&lt;br /&gt;
To instruct Moodle about our block&#039;s preferred width, we add one more method to the block class:&lt;br /&gt;
 &lt;br /&gt;
 function preferred_width() {&lt;br /&gt;
     // The preferred value is in pixels&lt;br /&gt;
     return 200;&lt;br /&gt;
 }&lt;br /&gt;
This will make our block (and all the other blocks displayed at the same side of the page) a bit wider than standard.&lt;br /&gt;
Finally, we can also affect some properties of the actual HTML that will be used to print our block. Each block is fully contained within a &amp;amp;lt;table&amp;amp;gt; element, inside which all the HTML for that block is printed. We can instruct Moodle to add HTML attributes with specific values to that container. This would be done to either a) directly affect the end result (if we say, assign bgcolor=&amp;quot;black&amp;quot;), or b) give us freedom to customize the end result using CSS (this is in fact done by default as we &#039;ll see below).&lt;br /&gt;
The default behavior of this feature in our case will assign to our block&#039;s container the class HTML attribute with the value &amp;quot;sideblock block_simplehtml&amp;quot; (the prefix &amp;quot;block_&amp;quot; followed by the name of our block, lowercased). We can then use that class to make CSS selectors in our theme to alter this block&#039;s visual style (for example, &amp;quot;.sideblock.block_simplehtml { border: 1px black solid}&amp;quot;).&lt;br /&gt;
To change the default behavior, we will need to define a method which returns an associative array of attribute names and values. For example, the version&lt;br /&gt;
 &lt;br /&gt;
 function html_attributes() {&lt;br /&gt;
     return array(&lt;br /&gt;
         &#039;class&#039;       =&amp;gt; &#039;sideblock block_&#039;. $this-&amp;gt;name(),&lt;br /&gt;
         &#039;onmouseover&#039; =&amp;gt; &#039;alert(&amp;quot;Mouseover on our block!&amp;quot;);&#039;&lt;br /&gt;
     );&lt;br /&gt;
 }&lt;br /&gt;
will result in a mouseover event being added to our block using JavaScript, just as if we had written the onmouseover=&amp;quot;alert(...)&amp;quot; part ourselves in HTML. Note that we actually duplicate the part which sets the class attribute (we want to keep that, and since we override the default behavior it&#039;s our responsibility to emulate it if required). And the final elegant touch is that we don&#039;t set the class to the hard-coded value &amp;quot;block_simplehtml&amp;quot; but instead use the [[Blocks_Howto#method_name| name]] method to make it dynamically match our block&#039;s name.&lt;br /&gt;
&lt;br /&gt;
== Authorized Personnel Only ==&lt;br /&gt;
It&#039;s not difficult to imagine a block which is very useful in some circumstances but it simply cannot be made meaningful in others. An example of this would be the &amp;quot;Social Activities&amp;quot; block which is indeed useful in a course with the social format, but doesn&#039;t do anything useful in a course with the weeks format. There should be some way of allowing the use of such blocks only where they are indeed meaningful, and not letting them confuse users if they are not.&lt;br /&gt;
Moodle allows us to declare which course formats each block is allowed to be displayed in, and enforces these restrictions as set by the block developers at all times. The information is given to Moodle as a standard associative array, with each key corresponding to a page format and defining a boolean value (true/false) that declares whether the block should be allowed to appear in that page format.&lt;br /&gt;
Notice the deliberate use of the term &#039;&#039;page&#039;&#039; instead of &#039;&#039;course&#039;&#039; in the above paragraph. This is because in Moodle 1.5 and onwards, blocks can be displayed in any page that supports them. The best example of such pages are the course pages, but we are not restricted to them. For instance, the quiz view page (the first one we see when we click on the name of the quiz) also supports blocks.&lt;br /&gt;
The format names we can use for the pages derive from the name of the script which is actually used to display that page. For example, when we are looking at a course, the script is &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;/course/view.php&amp;lt;/span&amp;gt; (this is evident from the browser&#039;s address line). Thus, the format name of that page is &#039;&#039;&#039;course-view&#039;&#039;&#039;. It follows easily that the format name for a quiz view page is &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039;. This rule of thumb does have a few exceptions, however:&lt;br /&gt;
#* The format name for the front page of Moodle is &#039;&#039;&#039;site-index&#039;&#039;&#039;.&lt;br /&gt;
#* The format name for courses is actually not just &#039;&#039;&#039;course-view&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; it is &amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;, &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;, etc.&lt;br /&gt;
#* Even though there is no such page, the format name &#039;&#039;&#039;all&#039;&#039;&#039; can be used as a catch-all option.&lt;br /&gt;
We can include as many format names as we want in our definition of the applicable formats. Each format can be allowed or disallowed, and there are also three more rules that help resolve the question &amp;quot;is this block allowed into this page or not?&amp;quot;:&lt;br /&gt;
#* Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
#* The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
#* The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
#* The order that the format names appear does not make any difference.&lt;br /&gt;
All of the above are enough to make the situation sound complex, so let&#039;s look at some specific examples. First of all, to have our block appear &#039;&#039;&#039;only&#039;&#039;&#039; in the site front page, we would use:&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     return array(&#039;site&#039; =&amp;gt; true);&lt;br /&gt;
 }&lt;br /&gt;
Since &#039;&#039;&#039;all&#039;&#039;&#039; is missing, the block is disallowed from appearing in &#039;&#039;any&#039;&#039; course format; but then &#039;&#039;&#039;site&#039;&#039;&#039; is set to true, so it&#039;s explicitly allowed to appear in the site front page (remember that &#039;&#039;&#039;site&#039;&#039;&#039; matches &#039;&#039;&#039;site-index&#039;&#039;&#039; because it&#039;s a prefix).&lt;br /&gt;
For another example, if we wanted to allow the block to appear in all course formats &#039;&#039;except&#039;&#039; social, and also to &#039;&#039;not&#039;&#039; be allowed anywhere but in courses, we would use:&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     return array(&#039;course-view&#039; =&amp;gt; true, &#039;course-view-social&#039; =&amp;gt; false);&lt;br /&gt;
 }&lt;br /&gt;
This time, we first allow the block to appear in all courses and then we explicitly disallow the social format.&lt;br /&gt;
For our final, most complicated example, suppose that a block can be displayed in the site front page, in courses (but not social courses) and also when we are viewing any activity module, &#039;&#039;except&#039;&#039; quiz. This would be:&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     return array(&#039;site-index&#039; =&amp;gt; true,&lt;br /&gt;
                  &#039;course-view&#039; =&amp;gt; true, &#039;course-view-social&#039; =&amp;gt; false,&lt;br /&gt;
                  &#039;mod&#039; =&amp;gt; true, &#039;mod-quiz&#039; =&amp;gt; false);&lt;br /&gt;
 }&lt;br /&gt;
It is not difficult to realize that the above accomplishes the objective if we remember that there is a &amp;quot;best match&amp;quot; policy to determine the end result.&lt;br /&gt;
&#039;&#039;&#039;UPDATING:&#039;&#039;&#039; Prior to version 1.5, blocks were only allowed in courses (and in Moodle 1.4, in the site front page). Also, the keywords used to describe the valid course formats at the time were slightly different and had to be changed in order to allow for a more open architecture. Refer to [[Blocks_Howto#appendix_b| Appendix B]] for more information on the changes that old blocks have to make to conform to the new standard.&lt;br /&gt;
== Lists and Icons ==&lt;br /&gt;
In this final part of the guide we will briefly discuss an additional capability of Moodle&#039;s block system, namely the ability to very easily create blocks that display a list of choices to the user. This list is displayed with one item per line, and an optional image (icon) next to the item. An example of such a &#039;&#039;list block&#039;&#039; is the standard Moodle &amp;quot;admin&amp;quot; block, which illustrates all the points discussed in this section.&lt;br /&gt;
As we have seen so far, blocks of use two properties of [[Blocks_Howto#variable_content| $this-&amp;gt;content]]&amp;lt;nowiki&amp;gt;: &amp;quot;text&amp;quot; and &amp;quot;footer&amp;quot;. The text is displayed as-is as the block content, and the footer is displayed below the content in a smaller font size. List blocks use $this-&amp;gt;content-&amp;gt;footer in the exact same way, but they ignore $this-&amp;gt;content-&amp;gt;text.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Instead, Moodle expects such blocks to set two other properties when the [[Blocks_Howto#method_get_content| get_content]] method is called: $this-&amp;gt;content-&amp;gt;items and $this-&amp;gt;content-&amp;gt;icons. $this-&amp;gt;content-&amp;gt;items should be a numerically indexed array containing elements that represent the HTML for each item in the list that is going to be displayed. Usually these items will be HTML anchor tags which provide links to some page. $this-&amp;gt;content-&amp;gt;icons should also be a numerically indexed array, with exactly as many items as $this-&amp;gt;content-&amp;gt;items has. Each of these items should be a fully qualified HTML &amp;lt;img&amp;gt; tag, with &amp;quot;src&amp;quot;, &amp;quot;height&amp;quot;, &amp;quot;width&amp;quot; and &amp;quot;alt&amp;quot; attributes. Obviously, it makes sense to keep the images small and of a uniform size.&lt;br /&gt;
In order to tell Moodle that we want to have a list block instead of the standard text block, we need to make a small change to our block class declaration. Instead of extending class &#039;&#039;&#039;block_base&#039;&#039;&#039;, our block will extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;. For example:&lt;br /&gt;
 &lt;br /&gt;
 class block_my_menu extends block_list {&lt;br /&gt;
     // The init() method does not need to change at all&lt;br /&gt;
 }&lt;br /&gt;
In addition to making this change, we must of course also modify the [[Blocks_Howto#method_get_content| get_content]] method to construct the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable as discussed above:&lt;br /&gt;
 &lt;br /&gt;
 function get_content() {&lt;br /&gt;
     if ($this-&amp;gt;content !== NULL) {&lt;br /&gt;
         return $this-&amp;gt;content;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     $this-&amp;gt;content = new stdClass;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;items = array();&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;icons = array();&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;footer = &#039;Footer here...&#039;;&lt;br /&gt;
 &lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;items[] = &#039;&amp;lt;a href=&amp;quot;some_file.php&amp;quot;&amp;gt;Menu Option 1&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
     $this-&amp;gt;content-&amp;gt;icons[] = &#039;&amp;lt;img src=&amp;quot;images/icons/1.gif&amp;quot; width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; alt=&amp;quot;&amp;quot; /&amp;gt;&#039;;&lt;br /&gt;
 &lt;br /&gt;
     // Add more list items here&lt;br /&gt;
 &lt;br /&gt;
     return $this-&amp;gt;content;&lt;br /&gt;
 }&lt;br /&gt;
To summarize, if we want to create a list block instead of a text block, we just need to change the block class declaration and the [[Blocks_Howto#method_get_content| get_content]] method. Adding the mandatory [[Blocks_Howto#method_init| init]] method as discussed earlier will then give us our first list block in no time!&lt;br /&gt;
&lt;br /&gt;
== Appendix A: Reference ==&lt;br /&gt;
&lt;br /&gt;
This Appendix will discuss the base class &#039;&#039;&#039;block_base&#039;&#039;&#039; from which all other block classes derive, and present each and every method that can be overridden by block developers in detail. Methods that should &#039;&#039;&#039;not&#039;&#039;&#039; be overridden are explicitly referred to as such. After reading this Appendix, you will have a clear understanding of every method which you should or could override to implement functionality for your block.&lt;br /&gt;
&lt;br /&gt;
The methods are divided into three categories: those you may use and override in your block, those that you may &#039;&#039;&#039;not&#039;&#039;&#039; override but might want to use, and those internal methods that should &#039;&#039;&#039;neither&#039;&#039;&#039; be used &#039;&#039;&#039;nor&#039;&#039;&#039; overridden. In each category, methods are presented in alphabetical order.&lt;br /&gt;
&lt;br /&gt;
=== Methods you can freely use and override: ===&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;applicable_formats&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function applicable_formats() {&lt;br /&gt;
     // Default case: the block can be used in courses and site index, but not in activities&lt;br /&gt;
     return array(&#039;all&#039; =&amp;gt; true, &#039;mod&#039; =&amp;gt; false);&lt;br /&gt;
 }&lt;br /&gt;
This method allows you to control which pages your block can be added to. Page formats are formulated from the full path of the script that is used to display that page. You should return an array with the keys being page format names and the values being booleans (true or false). Your block is only allowed to appear in those formats where the value is true.&lt;br /&gt;
Example format names are: &#039;&#039;&#039;course-view&#039;&#039;&#039;, &#039;&#039;&#039;site-index&#039;&#039;&#039; (this is an exception, referring front page of the Moodle site), &#039;&#039;&#039;course-format-weeks&#039;&#039;&#039; (referring to a specific course format), &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; (referring to the quiz module) and &#039;&#039;&#039;all&#039;&#039;&#039; (this will be used for those formats you have not explicitly allowed or disallowed).&lt;br /&gt;
The full matching rules are:&lt;br /&gt;
*** Prefixes of a format name will match that format name; for example, &#039;&#039;&#039;mod&#039;&#039;&#039; will match all the activity modules. &#039;&#039;&#039;course-view&#039;&#039;&#039; will match any course, regardless of the course format. And finally, &#039;&#039;&#039;site&#039;&#039;&#039; will also match the front page (remember that its full format name is &#039;&#039;&#039;site-index&#039;&#039;&#039;).&lt;br /&gt;
*** The more specialized a format name that matches our page is, the higher precedence it has when deciding if the block will be allowed. For example, &#039;&#039;&#039;mod&#039;&#039;&#039;, &#039;&#039;&#039;mod-quiz&#039;&#039;&#039; and &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; all match the quiz view page. But if all three are present, &#039;&#039;&#039;mod-quiz-view&#039;&#039;&#039; will take precedence over the other two because it is a better match.&lt;br /&gt;
*** The character &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039; can be used in place of any word. For example, &#039;&#039;&#039;mod&#039;&#039;&#039; and &#039;&#039;&#039;mod-*&#039;&#039;&#039; are equivalent. At the time of this document&#039;s writing, there is no actual reason to utilize this &amp;quot;wildcard matching&amp;quot; feature, but it exists for future usage.&lt;br /&gt;
*** The order that the format names appear does not make any difference.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;config_print&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function config_print() {&lt;br /&gt;
     // Default behavior: print the config_global.html file&lt;br /&gt;
     // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
     if (!$this-&amp;gt;has_config()) {&lt;br /&gt;
         return false;&lt;br /&gt;
     }&lt;br /&gt;
     global $CFG, $THEME;&lt;br /&gt;
     print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
     include($CFG-&amp;gt;dirroot.&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_global.html&#039;);&lt;br /&gt;
     print_simple_box_end();&lt;br /&gt;
     return true;&lt;br /&gt;
 }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This method allows you to choose how to display the global configuration screen for your block. This is the screen that the administrator is presented with when he chooses &amp;quot;Settings...&amp;quot; for a specific block. Override it if you need something much more complex than the default implementation allows you to do. However, keep these points in mind:&lt;br /&gt;
**# If you save your configuration options in $CFG, you will probably need to use global $CFG; before including any HTML configuration screens.&lt;br /&gt;
**# The HTML &amp;lt;input&amp;gt; elements that you include in your method&#039;s output will be automatically enclosed in a &amp;lt;form&amp;gt; element. You do not need to worry about where and how that form is submitted; however, you &#039;&#039;&#039;must&#039;&#039;&#039; provide a way to submit it (i.e., an &amp;lt;input type=&amp;quot;submit&amp;quot; /&amp;gt;.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;config_save&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function config_save($data) {&lt;br /&gt;
     // Default behavior: save all variables as $CFG properties&lt;br /&gt;
     // You don&#039;t need to override this if you &#039;re satisfied with the above&lt;br /&gt;
     foreach ($data as $name =&amp;gt; $value) {&lt;br /&gt;
         set_config($name, $value);&lt;br /&gt;
     }&lt;br /&gt;
     return true;&lt;br /&gt;
 }&lt;br /&gt;
This method allows you to override the storage mechanism for your global configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values. The default implementation saves everything as Moodle $CFG variables.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_content&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_content() {&lt;br /&gt;
     // This should be implemented by the derived class.&lt;br /&gt;
     return NULL;&lt;br /&gt;
 }&lt;br /&gt;
This method should, when called, populate the [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable of your block. Populating the variable means:&lt;br /&gt;
&#039;&#039;&#039;EITHER&#039;&#039;&#039;&amp;lt;br /&amp;gt;defining $this-&amp;gt;content-&amp;gt;text and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_base&#039;&#039;&#039;. Both of these should be strings, and can contain arbitrary HTML.&lt;br /&gt;
&#039;&#039;&#039;OR&#039;&#039;&#039;&amp;lt;br /&amp;gt;defining $this-&amp;gt;content-&amp;gt;items, $this-&amp;gt;content-&amp;gt;icons and $this-&amp;gt;content-&amp;gt;footer if your block derives from &#039;&#039;&#039;block_list&#039;&#039;&#039;. The first two should be numerically indexed arrays having the exact same number of elements. $this-&amp;gt;content-&amp;gt;items is an array of strings that can contain arbitrary HTML while $this-&amp;gt;content-&amp;gt;icons also contains should strings, but those must be fully-qualified HTML &amp;lt;img&amp;gt; tags &#039;&#039;&#039;and nothing else&#039;&#039;&#039;. $this-&amp;gt;content-&amp;gt;footer is a string, as above.&lt;br /&gt;
If you set &#039;&#039;all&#039;&#039; of these variables to their default &amp;quot;empty&amp;quot; values (empty arrays for the arrays and empty strings for the strings), the block will &#039;&#039;&#039;not&#039;&#039;&#039; be displayed at all except to editing users. This is a good way of having your block hide itself to unclutter the screen if there is no reason to have it displayed.&lt;br /&gt;
Before starting to populate [[Blocks_Howto#variable_content| $this-&amp;gt;content]], you should also include a simple caching check. If [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is exactly equal to NULL then proceed as normally, while if it is not, return the existing value instead of calculating it once more. If you fail to do this, Moodle will suffer a performance hit.&lt;br /&gt;
In any case, your method should return the fully constructed [[Blocks_Howto#variable_content| $this-&amp;gt;content]] variable.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;has_config&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function has_config() {&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to present a configuration interface to site admins or not. The configuration that this interface offers will impact all instances of the block equally.&lt;br /&gt;
To actually implement the configuration interface, you will either need to rely on the default [[Blocks_Howto#method_instance_config_print| config_print]] method or override it. The full guide contains [[Blocks_Howto#section_effects_of_globalization| more information on this]].&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;hide_header&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function hide_header() {&lt;br /&gt;
     //Default, false--&amp;gt; the header is shown&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
This method should return a boolean value that denotes whether your block wants to hide its header (or title). Thus, if you override it to return true, your block will not display a title unless the current user is in editing mode.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;html_attributes&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function html_attributes() {&lt;br /&gt;
     // Default case: an id with the instance and a class with our name in it&lt;br /&gt;
     return array(&#039;id&#039; =&amp;gt; &#039;inst&#039;.$this-&amp;gt;instance-&amp;gt;id, &#039;class&#039; =&amp;gt; &#039;block_&#039;. $this-&amp;gt;name());&lt;br /&gt;
 }&lt;br /&gt;
This method should return an associative array of HTML attributes that will be given to your block&#039;s container element when Moodle constructs the output HTML. No sanitization will be performed in these elements at all.&lt;br /&gt;
If you intend to override this method, you should return the default attributes as well as those you add yourself. The recommended way to do this is:&lt;br /&gt;
 &lt;br /&gt;
 function html_attributes() {&lt;br /&gt;
     $attrs = parent::html_attributes();&lt;br /&gt;
     // Add your own attributes here, e.g.&lt;br /&gt;
     // $attrs[&#039;width&#039;] = &#039;50%&#039;;&lt;br /&gt;
     return $attrs;&lt;br /&gt;
 }&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;init&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function init() {&lt;br /&gt;
     $this-&amp;gt;title = get_string(&#039;simplehtml&#039;, &#039;block_simplehtml&#039;);&lt;br /&gt;
     $this-&amp;gt;version = 2004111200;&lt;br /&gt;
 }&lt;br /&gt;
This method must be implemented for all blocks. It has to assign meaningful values to the object variables [[Blocks_Howto#variable_title| $this-&amp;gt;title]] and [[Blocks_Howto#variable_version| $this-&amp;gt;version]] (which is used by Moodle for performing automatic updates when available).&lt;br /&gt;
No return value is expected from this method.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_allow_config&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_allow_config() {&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
This method should return a boolean value. True indicates that your block wants to have per-instance configuration, while false means it does not. If you do want to implement instance configuration, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
This method&#039;s return value is irrelevant if [[Blocks_Howto#method_instance_allow_multiple| instance_allow_multiple]] returns true; it is assumed that if you want multiple instances then each instance needs its own configuration.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_allow_multiple&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_allow_multiple() {&lt;br /&gt;
     // Are you going to allow multiple instances of each block?&lt;br /&gt;
     // If yes, then it is assumed that the block WILL USE per-instance configuration&lt;br /&gt;
     return false;&lt;br /&gt;
 }&lt;br /&gt;
This method should return a boolean value, indicating whether you want to allow multiple instances of this block in the same page or not. If you do allow multiple instances, it is assumed that you will also be providing per-instance configuration for the block. Thus, you will need to take some additional steps apart from overriding this method; refer to the full guide for [[Blocks_Howto#section_configure_that_out| more information]].&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_config_print&amp;lt;/div&amp;gt;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 function instance_config_print() {&lt;br /&gt;
     // Default behavior: print the config_instance.html file&lt;br /&gt;
     // You don&#039;t need to override this if you&#039;re satisfied with the above&lt;br /&gt;
     if (!$this-&amp;gt;instance_allow_multiple() &amp;amp;&amp;amp; !$this-&amp;gt;instance_allow_config()) {&lt;br /&gt;
         return false;&lt;br /&gt;
     }&lt;br /&gt;
     global $CFG, $THEME;&lt;br /&gt;
 &lt;br /&gt;
     if (is_file($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;)) {&lt;br /&gt;
         print_simple_box_start(&#039;center&#039;, &#039;&#039;, $THEME-&amp;gt;cellheading);&lt;br /&gt;
         include($CFG-&amp;gt;dirroot .&#039;/blocks/&#039;. $this-&amp;gt;name() .&#039;/config_instance.html&#039;);&lt;br /&gt;
         print_simple_box_end();&lt;br /&gt;
     } else {&lt;br /&gt;
         notice(get_string(&#039;blockconfigbad&#039;),&lt;br /&gt;
                str_replace(&#039;blockaction=&#039;, &#039;dummy=&#039;, qualified_me()));&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     return true;&lt;br /&gt;
 }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
This method allows you to choose how to display the instance configuration screen for your block. Override it if you need something much more complex than the default implementation allows you to do. Keep in mind that whatever you do output from [[Blocks_Howto#method_instance_config_print| config_print]], it will be enclosed in a HTML form automatically. You only need to provide a way to submit that form.&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_config_save&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_save($data) {&lt;br /&gt;
     $data = stripslashes_recursive($data);&lt;br /&gt;
     $this-&amp;gt;config = $data;&lt;br /&gt;
     return set_field(&#039;block_instance&#039;, &#039;configdata&#039;, base64_encode(serialize($data)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
 }&lt;br /&gt;
This method allows you to override the storage mechanism for your instance configuration data. The received argument is an associative array, with the keys being setting names and the values being setting values.&lt;br /&gt;
The configuration must be stored in the &amp;quot;configdata&amp;quot; field of your instance record in the database so that Moodle can auto-load it when your block is constructed. However, you may still want to override this method if you need to take some additional action apart from saving the data. In that case, you really should do what data processing you want and then call parent::instance_config_save($data) with your new $data array. This will keep your block from becoming broken if the default implementation of instance_config_save changes in the future.&lt;br /&gt;
Note that $data does not hold all of the submitted POST data because Moodle adds some hidden fields to the form in order to be able to process it. However, before calling this method it strips the hidden fields from the received data and so when this method is called only the &amp;quot;real&amp;quot; configuration data remain.&lt;br /&gt;
If you want to update the stored copy of the configuration data at run time (for example to persist some changes you made programmatically), you should not use this method. The correct procedure for that purpose is to call [[Blocks_Howto#method_instance_config_commit| instance_config_commit]].&lt;br /&gt;
You should return a boolean value denoting the success or failure of your method&#039;s actions.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;preferred_width&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function preferred_width() {&lt;br /&gt;
     // Default case: the block wants to be 180 pixels wide&lt;br /&gt;
     return 180;&lt;br /&gt;
 }&lt;br /&gt;
This method should return an integer value, which is the number of pixels of width your block wants to take up when displayed. Moodle will try to honor your request, but this is actually up to the implementation of the format of the page your block is being displayed in and therefore no guarantee is given. You might get exactly what you want or any other width the format decides to give you, although obviously an effort to accomodate your block will be made.&lt;br /&gt;
Most display logic at this point allocates the maximum width requested by the blocks that are going to be displayed, bounding it both downwards and upwards to avoid having a bad-behaving block break the format.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;refresh_content&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function refresh_content() {&lt;br /&gt;
     // Nothing special here, depends on content()&lt;br /&gt;
     $this-&amp;gt;content = NULL;&lt;br /&gt;
     return $this-&amp;gt;get_content();&lt;br /&gt;
 }&lt;br /&gt;
This method should cause your block to recalculate its content immediately. If you follow the guidelines for [[Blocks_Howto#get_content| get_content]], which say to respect the current content value unless it is NULL, then the default implementation will do the job just fine.&lt;br /&gt;
You should return the new value of [[Blocks_Howto#variable_content| $this-&amp;gt;content]] after refreshing it.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;specialization&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function specialization() {&lt;br /&gt;
     // Just to make sure that this method exists.&lt;br /&gt;
 }&lt;br /&gt;
This method is automatically called by the framework immediately after your instance data (which includes the page type and id and all instance configuration data) is loaded from the database. If there is some action that you need to take as soon as this data becomes available and which cannot be taken earlier, you should override this method.&lt;br /&gt;
The instance data will be available in the variables [[Blocks_Howto#variable_instance| $this-&amp;gt;instance]] and [[Blocks_Howto#variable_config| $this-&amp;gt;config]].&lt;br /&gt;
This method should not return anything at all.&lt;br /&gt;
=== Methods which you should &#039;&#039;not&#039;&#039; override but may want to use: ===&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;instance_config_commit&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function instance_config_commit() {&lt;br /&gt;
     return set_field(&#039;block_instance&#039;,&lt;br /&gt;
                      &#039;configdata&#039;, base64_encode(serialize($this-&amp;gt;config)),&lt;br /&gt;
                      &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;id);&lt;br /&gt;
 }&lt;br /&gt;
This method saves the current contents of [[Blocks_Howto#variable_config| $this-&amp;gt;config]] to the database. If you need to make a change to the configuration settings of a block instance at run time (and not through the usual avenue of letting the user change it), just make the changes you want to [[Blocks_Howto#variable_config| $this-&amp;gt;config]] and then call this method.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_content_type&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_content_type() {&lt;br /&gt;
     return $this-&amp;gt;content_type;&lt;br /&gt;
 }&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_title&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_title() {&lt;br /&gt;
     return $this-&amp;gt;title;&lt;br /&gt;
 }&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_title| $this-&amp;gt;title]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;get_version&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function get_version() {&lt;br /&gt;
     return $this-&amp;gt;version;&lt;br /&gt;
 }&lt;br /&gt;
This method returns the value of [[Blocks_Howto#variable_version| $this-&amp;gt;version]], and is the preferred way of accessing that variable. It is guaranteed to always work, now and forever. Directly accessing the variable is &#039;&#039;&#039;not recommended&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;; future library changes may break compatibility with code that does so.&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;is_empty&amp;lt;/div&amp;gt;&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_base&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function is_empty() {&lt;br /&gt;
     $this-&amp;gt;get_content();&lt;br /&gt;
     return(empty($this-&amp;gt;content-&amp;gt;text) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
 }&lt;br /&gt;
For blocks that extend class &#039;&#039;&#039;block_list&#039;&#039;&#039;&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function is_empty() {&lt;br /&gt;
     $this-&amp;gt;get_content();&lt;br /&gt;
     return (empty($this-&amp;gt;content-&amp;gt;items) &amp;amp;&amp;amp; empty($this-&amp;gt;content-&amp;gt;footer));&lt;br /&gt;
 }&lt;br /&gt;
This method returns the a boolean true/false value, depending on whether the block has any content at all to display. Blocks without content are not displayed by the framework.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;name&amp;lt;/div&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 function name() {&lt;br /&gt;
     static $myname;&lt;br /&gt;
     if ($myname === NULL) {&lt;br /&gt;
         $myname = strtolower(get_class($this));&lt;br /&gt;
         $myname = substr($myname, strpos($myname, &#039;_&#039;) + 1);&lt;br /&gt;
     }&lt;br /&gt;
     return $myname;&lt;br /&gt;
 }&lt;br /&gt;
This method returns the internal name of your block inside Moodle, without the &#039;&#039;&#039;block_&#039;&#039;&#039; prefix. Obtaining the name of a block object is sometimes useful because it can be used to write code that is agnostic to the actual block&#039;s name (and thus more generic and reusable). For an example of this technique, see the [[Blocks_Howto#method_config_print| config_print]] method.&lt;br /&gt;
=== Methods which you should &#039;&#039;not&#039;&#039; override and &#039;&#039;not&#039;&#039; use at all: ===&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_self_test&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_add_edit_controls&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_load_instance&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_print_block&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
** &amp;lt;div class=&amp;quot;function_title&amp;quot;&amp;gt;_print_shadow&amp;lt;/div&amp;gt;&lt;br /&gt;
This is a private method; no description is given.&lt;br /&gt;
&lt;br /&gt;
The class &#039;&#039;&#039;block_base&#039;&#039;&#039; also has a few standard member variables which its methods manipulate. These variables, the purpose of each and the type of data they are expected to hold is explained in the next section of this Appendix.&lt;br /&gt;
&lt;br /&gt;
=== Class variables: ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;config&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable holds all the specialized instance configuration data that have been provided for this specific block instance (object). It is an object of type stdClass, with member variables directly corresponding to the HTML &amp;lt;input&amp;gt; elements in the block&#039;s &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_instance.html&amp;lt;/span&amp;gt; file.&lt;br /&gt;
The variable is initialized just after the block object is constructed, immediately before [[Blocks_Howto#method_specialization| specialization]] is called for the object. It is possible that the block has no instance configuration, in which case the variable will be NULL.&lt;br /&gt;
It is obvious that there is a direct relationship between this variable and the configdata field in the mdl_block_instance table. However, it is &#039;&#039;strongly&#039;&#039; advised that you refrain from accessing the configdata field yourself. If you absolutely must update its value at any time, it is recommended that you call the method [[Blocks_Howto#method_instance_config_commit| instance_config_commit]] to do the actual work.&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;content_type&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable instructs Moodle on what type of content it should assume the block has, and is used to differentiate text blocks from list blocks. It is essential that it has a meaningful value, as Moodle depends on this for correctly displaying the block on screen. Consequently, this variable is closely tied with the variable [[Blocks_Howto#variable_content| $this-&amp;gt;content]]. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
The only valid values for this variable are the two named constants [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]] and [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]].&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;content&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable holds all the actual content that is displayed inside each block. Valid values for it are either NULL or an object of class stdClass, which must have specific member variables set as explained below. Normally, it begins life with a value of NULL and it becomes fully constructed (i.e., an object) when [[Blocks_Howto#method_get_content| get_content]] is called.&lt;br /&gt;
After it is fully constructed, this object is expected to have certain properties, depending on the value of [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]]. Specifically:&lt;br /&gt;
** If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_text| BLOCK_TYPE_TEXT]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;text&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a string of arbitrary length and content. It is displayed inside the main area of the block, and can contain HTML.&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;footer&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
** If [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] is [[Blocks_Howto#constant_block_type_list| BLOCK_TYPE_LIST]], then [[Blocks_Howto#variable_content| $this-&amp;gt;content]] is expected to have the following member variables:&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;items&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a numerically indexed array of strings which holds the title for each item in the list that will be displayed in the block&#039;s area. Since usually such lists function like menus, the title for each item is normally a fully qualified HTML &amp;lt;a&amp;gt; tag.&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;icons&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a numerically indexed array of strings which represent the images displayed before each item of the list. It therefore follows that it should have the exact number of elements as the items member variable. Each item in this array should be a fully qualified HTML &amp;lt;img&amp;gt; tag.&lt;br /&gt;
*** &amp;lt;div&amp;gt;&#039;&#039;&#039;footer&#039;&#039;&#039;&amp;lt;/div&amp;gt;This is a string of arbitrary length and contents. It is displayed below the text, using a smaller font size. It can also contain HTML.&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;instance&amp;lt;/div&amp;gt;&lt;br /&gt;
This member variable holds all the specific information that differentiates one block instance (i.e., the PHP object that embodies it) from another. It is an object of type stdClass retrieved by calling get_record on the table mdl_block_instance. Its member variables, then, directly correspond to the fields of that table. It is initialized immediately after the block object itself is constructed.&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;title&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable is a string that contains the human-readable name of the block. It is used to refer to blocks of that type throughout Moodle, for example in the administrator&#039;s block configuration screen and in the editing teacher&#039;s add block menu. It is also the title that is printed when the block is displayed on screen, although blocks can specifically change this title to something else if they wish (see below). The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each object.&lt;br /&gt;
In the case of blocks which may want to configure their title dynamically through instance configuration, it is still essential to provide a valid title inside [[Blocks_Howto#method_init| init]]. This title may then be overridden when the [[Blocks_Howto#method_specialization| specialization]] method is called by the framework:&lt;br /&gt;
 &lt;br /&gt;
 function specialization() {&lt;br /&gt;
     // At this point, $this-&amp;gt;instance and $this-&amp;gt;config are available&lt;br /&gt;
     // for use. We can now change the title to whatever we want.&lt;br /&gt;
     $this-&amp;gt;title = $this-&amp;gt;config-&amp;gt;variable_holding_the_title;&lt;br /&gt;
 }&lt;br /&gt;
* &amp;lt;div class=&amp;quot;variable_title&amp;quot;&amp;gt;$this-&amp;gt;version&amp;lt;/div&amp;gt;&lt;br /&gt;
This variable should hold each block&#039;s version number in the form &#039;&#039;&#039;YYYYMMDDXX&#039;&#039;&#039;, as per the convention throughout Moodle. The version number is used by Moodle to detect when a block has been upgraded and it consequently needs to run the block&#039;s upgrade code to bring the &amp;quot;old&amp;quot; version of the block&#039;s data up to date. The variable is expected to have a valid value after the framework calls the [[Blocks_Howto#method_init| init]] method for each block.&lt;br /&gt;
Most blocks do not keep complex data of their own in the database the way that modules do, so in most cases nothing actually happens during a block version upgrade. However, the version number is displayed in the administration interface for blocks. It is good practice therefore to change your block&#039;s version number when it gains new functionality or receives important bug fixes, to enable site administrators to easily identify the exact version of the block they are working with.&lt;br /&gt;
&lt;br /&gt;
Appearing throughout the code related to the Blocks API, there is a number of predefined constants that are utilized to avoid the use of &amp;quot;magic numbers&amp;quot; in the code. These constants are:&lt;br /&gt;
&lt;br /&gt;
=== Named constants: ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;div class=&amp;quot;named_constant&amp;quot;&amp;gt;BLOCK_TYPE_LIST&amp;lt;/div&amp;gt;&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
* &amp;lt;div class=&amp;quot;named_constant&amp;quot;&amp;gt;BLOCK_TYPE_TEXT&amp;lt;/div&amp;gt;&lt;br /&gt;
This is one of the two valid values for the [[Blocks_Howto#variable_content_type| $this-&amp;gt;content_type]] member variable of every block. Its value specifies the exact requirements that Moodle will then have for [[Blocks_Howto#variable_content| $this-&amp;gt;content]].&lt;br /&gt;
&lt;br /&gt;
== Appendix B: Differences in the Blocks API for Moodle versions prior to 1.5 ==&lt;br /&gt;
&lt;br /&gt;
This Appendix will discuss what changes in the Blocks API were introduced by Moodle 1.5 and what steps developers need to take to update their blocks to be fully compatible with Moodle 1.5. Unfortunately, with these changes backward compatibility is broken; this means that blocks from Moodle 1.4 will never work with 1.5 and vice versa.&lt;br /&gt;
&lt;br /&gt;
=== Class naming conventions changed ===&lt;br /&gt;
In Moodle 1.4, all block classes were required to have a name like &#039;&#039;&#039;CourseBlock_something&#039;&#039;&#039; and the base class from which the derived was &#039;&#039;&#039;MoodleBlock&#039;&#039;&#039;. This has changed in Moodle 1.5, to bring the naming conventions in line with other object-oriented aspects of Moodle (for example there are classes enrolment_base, resource_base etc). The new block classes should instead be named like &#039;&#039;&#039;block_something&#039;&#039;&#039; and derive from &#039;&#039;&#039;block_base&#039;&#039;&#039;. This means that in order to make a block compatible with Moodle 1.5, you need to change the class definition&lt;br /&gt;
 &lt;br /&gt;
 class CourseBlock_online_users extends MoodleBlock { ... }&lt;br /&gt;
to&lt;br /&gt;
 &lt;br /&gt;
 class block_online_users extends block_base { ... }&lt;br /&gt;
An exception to the above is the special case where the block is intended to display a list of items instead of arbitrary text; in this case the block class must derive from class &#039;&#039;&#039;block_list&#039;&#039;&#039; instead, like this:&lt;br /&gt;
 &lt;br /&gt;
 class block_admin extends block_list { ... }&lt;br /&gt;
&lt;br /&gt;
=== Constructor versus init() ===&lt;br /&gt;
&lt;br /&gt;
In Moodle 1.4, in each block class it was mandatory to define a constructor which accepted a course data record as an argument (the example is from the actual Online Users block):&lt;br /&gt;
 &lt;br /&gt;
     function CourseBlock_online_users ($course) {&lt;br /&gt;
         $this-&amp;gt;title = get_string(&#039;blockname&#039;,&#039;block_online_users&#039;);&lt;br /&gt;
         $this-&amp;gt;content_type = BLOCK_TYPE_TEXT;&lt;br /&gt;
         $this-&amp;gt;course = $course;&lt;br /&gt;
         $this-&amp;gt;version = 2004052700;&lt;br /&gt;
     }&lt;br /&gt;
In contrast, Moodle 1.5 does away with the constructor and instead requires you to define an init() method that takes no arguments:&lt;br /&gt;
 &lt;br /&gt;
     function init() {&lt;br /&gt;
         $this-&amp;gt;title = get_string(&#039;blockname&#039;,&#039;block_online_users&#039;);&lt;br /&gt;
         $this-&amp;gt;version = 2004111600;&lt;br /&gt;
     }&lt;br /&gt;
Of course, this leaves you without access to the $course object, which you might actually need. Since that&#039;s probably going to be needed inside [[Blocks_Howto#method_get_content| get_content]], the way to retrieve it is by using this code:&lt;br /&gt;
 &lt;br /&gt;
     $course = get_record(&#039;course&#039;, &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;pageid);&lt;br /&gt;
If you are going to need access to $course from inside other methods in addition to [[Blocks_Howto#method_get_content| get_content]], you might fetch the $course object inside the [[Blocks_Howto#method_specialization| specialization]] method and save it as a class variable for later use, in order to avoid executing the same query multiple times:&lt;br /&gt;
 &lt;br /&gt;
     function specialization() {&lt;br /&gt;
         $this-&amp;gt;course = get_record(&#039;course&#039;, &#039;id&#039;, $this-&amp;gt;instance-&amp;gt;pageid);&lt;br /&gt;
     }&lt;br /&gt;
&lt;br /&gt;
=== Blocks with configuration ===&lt;br /&gt;
In Moodle 1.4, blocks could only have what are now (in Moodle 1.5) called &amp;quot;global configuration&amp;quot; options, to differentiate from the new &amp;quot;instance configuration&amp;quot; options. If your block has support for configuration, you will need to take these steps:&lt;br /&gt;
## Rename your &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config.html&amp;lt;/span&amp;gt; file to &amp;lt;span class=&amp;quot;filename&amp;quot;&amp;gt;config_global.html&amp;lt;/span&amp;gt;.&lt;br /&gt;
## Edit the newly renamed file and completely remove the &amp;lt;form&amp;gt; tag (Moodle now wraps your configuration in a form automatically).&lt;br /&gt;
## If you are using any HTML &amp;lt;input&amp;gt; tags other than those that directly affect your configuration (for example, &amp;quot;sesskey&amp;quot;), REMOVE those too (Moodle will add them automatically as required).&lt;br /&gt;
## If you have overridden &#039;&#039;&#039;print_config&#039;&#039;&#039;, rename your method to &#039;&#039;&#039;config_print&#039;&#039;&#039;.&lt;br /&gt;
## If you have overridden &#039;&#039;&#039;handle_config&#039;&#039;&#039;, rename your method to &#039;&#039;&#039;config_save&#039;&#039;&#039;.&lt;br /&gt;
=== Blocks with customized applicable formats ===&lt;br /&gt;
The correct way to specify the formats you want to allow or disallow your block to exist has been reworked for Moodle 1.5 to take account of the fact that blocks are no longer restricted to just courses. To have a block retain its intended behavior, you must change these format names (array keys in the return value of [[Blocks_Howto#method_applicable_formats| applicable_formats]]) if they are used in your block:&lt;br /&gt;
#* &#039;&#039;&#039;social&#039;&#039;&#039; should become &#039;&#039;&#039;course-view-social&#039;&#039;&#039;&lt;br /&gt;
#* &#039;&#039;&#039;topics&#039;&#039;&#039; should become &#039;&#039;&#039;course-view-topics&#039;&#039;&#039;&lt;br /&gt;
#* &#039;&#039;&#039;weeks&#039;&#039;&#039; should become &#039;&#039;&#039;course-view-weeks&#039;&#039;&#039;&lt;br /&gt;
You should also keep in mind that there is now the possibility of blocks being displayed in other pages too, like the introductory page that users see when they enter an activity module. You might therefore need to make the specification for applicable formats more restrictive to keep your block out of pages it is not supposed to be shown in. Also, there are subtle changes to the way that the final decision to allow or disallow a block is made. For the technical details refer to the definition of [[Blocks_Howto#method_applicable_formats| applicable_formats]], and for a more extended example read [[Blocks_Howto#section_authorized_personnel_only| the section dedicated to this subject]].&lt;br /&gt;
That&#039;s everything; your block will now be ready for use in Moodle 1.5!&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
&lt;br /&gt;
[[es:Desarrollo de bloques]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=User:Mark_Nielsen&amp;diff=18800</id>
		<title>User:Mark Nielsen</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=User:Mark_Nielsen&amp;diff=18800"/>
		<updated>2006-12-22T05:04:35Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Welcome */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What I think about==&lt;br /&gt;
&lt;br /&gt;
*[[Adding_question_types_to_lesson | Adding question types to lesson module]]&lt;br /&gt;
*[[Development:New lesson navigation | New lesson navigation]]&lt;br /&gt;
*[[Development:Adding blocks to lesson | Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
*[http://moodle.org/user/view.php?id=13075&amp;amp;course=5 My Moodle profile page]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18799</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18799"/>
		<updated>2006-12-22T03:57:42Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson and to reduce the number of lesson settings, which are numerous, then block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
*Reduce lesson&#039;s code base.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18798</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18798"/>
		<updated>2006-12-22T03:56:32Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
*Reduce lesson&#039;s code base.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18797</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18797"/>
		<updated>2006-12-22T03:54:03Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18796</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18796"/>
		<updated>2006-12-22T03:52:13Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson display and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Blocks seem to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18795</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18795"/>
		<updated>2006-12-22T03:45:42Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Conclusion */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson display and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
The adoption of blocks seems to suit lesson well.  Here are a few key points:&lt;br /&gt;
*Lesson would have a more customizable layout.&lt;br /&gt;
*Lesson can take advantage of an existing Moodle feature.&lt;br /&gt;
*Moodle users can create their own blocks to plug into lesson.&lt;br /&gt;
*The number of lesson settings can be reduced.&lt;br /&gt;
*More functionality can be added to existing lesson features.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18794</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18794"/>
		<updated>2006-12-22T03:33:09Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Sticky blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson display and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on specific lesson pages.  This would allow one to add a sticky block like &#039;&#039;lesson_menu&#039;&#039; to all pages and add another block like the HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still &#039;&#039;fuzzy&#039;&#039;.  It could prove to be difficult to design an interface that works well with the current block API.  &#039;&#039;&#039;If&#039;&#039;&#039; a clean implementation of sticky blocks cannot be found, then all blocks would behave like sticky blocks.  Meaning, all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18793</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18793"/>
		<updated>2006-12-22T03:30:13Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Other blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson display and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available to lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and add an HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.  If a clean implementation of sticky blocks cannot be found, then all blocks would like sticky blocks; all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18792</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18792"/>
		<updated>2006-12-22T03:23:42Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Lesson blocks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson display and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name &#039;&#039;lesson_menu&#039;&#039;)&lt;br /&gt;
*Media file (block name &#039;&#039;lesson_media_file&#039;&#039;)&lt;br /&gt;
*Timer (block name &#039;&#039;lesson_clock&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from lesson and would be handled by the block configuration interface.  Also these features, as blocks, could be more easily expanded.  For example:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;lesson_menu&#039;&#039; could be configurable to include any lesson page or branch table (often requested).&lt;br /&gt;
*&#039;&#039;lesson_media_file&#039;&#039; could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*&#039;&#039;lesson_clock&#039;&#039; could be configurable to be a count down timer or as a clock that displays how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available for adding to a lesson.  Some blocks would not make sense in a lesson like the admin block for example.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and add an HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.  If a clean implementation of sticky blocks cannot be found, then all blocks would like sticky blocks; all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18791</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18791"/>
		<updated>2006-12-22T03:15:06Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, are static and are block like.  In order to add greater flexibility to the lesson display and to reduce the number of lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name lesson_menu)&lt;br /&gt;
*Media file (block name lesson_media_file)&lt;br /&gt;
*Timer (block name lesson_clock)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from the lesson settings and be handled by the block configuration.  Also these features as blocks could be more easily expanded.  For example:&lt;br /&gt;
*lesson_menu could be configurable to include any lesson question page or branch table (often requested).&lt;br /&gt;
*lesson_media_file could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*lesson_clock could be configurable to be a count down timer or as a clock that reports how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available for adding to a lesson.  Some blocks would not make sense in a lesson like the admin block for example.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and add an HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.  If a clean implementation of sticky blocks cannot be found, then all blocks would like sticky blocks; all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18790</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18790"/>
		<updated>2006-12-22T03:13:04Z</updated>

		<summary type="html">&lt;p&gt;Bushido: added categories&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, but are static.&lt;br /&gt;
&lt;br /&gt;
In order to add greater flexibility to the lesson display and to reduce the number of settings in the lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name lesson_menu)&lt;br /&gt;
*Media file (block name lesson_media_file)&lt;br /&gt;
*Timer (block name lesson_clock)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from the lesson settings and be handled by the block configuration.  Also these features as blocks could be more easily expanded.  For example:&lt;br /&gt;
*lesson_menu could be configurable to include any lesson question page or branch table (often requested).&lt;br /&gt;
*lesson_media_file could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*lesson_clock could be configurable to be a count down timer or as a clock that reports how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available for adding to a lesson.  Some blocks would not make sense in a lesson like the admin block for example.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and add an HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.  If a clean implementation of sticky blocks cannot be found, then all blocks would like sticky blocks; all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18789</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18789"/>
		<updated>2006-12-22T03:11:27Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, but are static.&lt;br /&gt;
&lt;br /&gt;
In order to add greater flexibility to the lesson display and to reduce the number of settings in the lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name lesson_menu)&lt;br /&gt;
*Media file (block name lesson_media_file)&lt;br /&gt;
*Timer (block name lesson_clock)&lt;br /&gt;
&lt;br /&gt;
The settings for these features would be removed from the lesson settings and be handled by the block configuration.  Also these features as blocks could be more easily expanded.  For example:&lt;br /&gt;
*lesson_menu could be configurable to include any lesson question page or branch table (often requested).&lt;br /&gt;
*lesson_media_file could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*lesson_clock could be configurable to be a count down timer or as a clock that reports how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available for adding to a lesson.  Some blocks would not make sense in a lesson like the admin block for example.  To handle this, lesson would have a global configuration that could disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and add an HTML block that would only appear on a single page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.  If a clean implementation of sticky blocks cannot be found, then all blocks would like sticky blocks; all pages would have the same blocks.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18788</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18788"/>
		<updated>2006-12-22T02:17:14Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via the lesson settings, one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, but are static.&lt;br /&gt;
&lt;br /&gt;
In order to add greater flexibility to the lesson display and to reduce the number of settings in the lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name lesson_menu)&lt;br /&gt;
*Media file (block name lesson_media_file)&lt;br /&gt;
*Timer (block name lesson_clock)&lt;br /&gt;
&lt;br /&gt;
The settings for these would be removed from the lesson&#039;s settings and be handled by the block configuration.  Also these features could be easily expanded.  For example:&lt;br /&gt;
*The lesson_menu could be configurable to include any lesson question page or branch table (often requested).&lt;br /&gt;
*The lesson_media_file could be configurable to display the media file via a pop-up or embedded into the lesson page.&lt;br /&gt;
*The lesson_clock could be configurable to a count down timer or as a clock that reports how long a user has been in a lesson (has been requested).&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available for adding to a lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that can disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and then on a specific page add an HTML block with specific content for that page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]] 20:12, 21 December 2006 (CST)&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18787</id>
		<title>Development:Adding blocks to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_blocks_to_lesson&amp;diff=18787"/>
		<updated>2006-12-22T02:12:36Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The lesson module lends itself well to blocks.  It already has a three column format same as a course format.  Also, via a lesson&#039;s settings one can add a left menu, a timer or a link to a media file.  All of these are displayed in the left or the right column, but are static.&lt;br /&gt;
&lt;br /&gt;
In order to add greater flexibility to the lesson display and to reduce the number of settings in the lesson settings, which are numerous, block functionality should be added to lesson.&lt;br /&gt;
&lt;br /&gt;
==Lesson blocks==&lt;br /&gt;
&lt;br /&gt;
Lesson features that would be extracted from lesson and placed into blocks would be the following:&lt;br /&gt;
*Left menu (block name lesson_menu)&lt;br /&gt;
*Media file (block name lesson_media_file)&lt;br /&gt;
*Timer (block name lesson_clock)&lt;br /&gt;
&lt;br /&gt;
The settings for these would be removed from the lesson&#039;s settings and be handled by the block configuration.&lt;br /&gt;
&lt;br /&gt;
==Other blocks==&lt;br /&gt;
&lt;br /&gt;
By adding block functionality to lesson, other blocks become available for adding to a lesson.  Some blocks would not make sense in a lesson like the admin block.  To handle this, lesson would have a global configuration that can disable blocks from being added to a lesson.  This will help to reduce confusion for lesson authors.&lt;br /&gt;
&lt;br /&gt;
==Sticky blocks==&lt;br /&gt;
&lt;br /&gt;
Sticky blocks could be used to force a block to appear on every lesson page.  Then non-sticky blocks would only appear on the page to which it was added.  This would allow one to add a sticky block like lesson_menu to all pages and then on a specific page add an HTML block with specific content for that page.&lt;br /&gt;
&lt;br /&gt;
The possibility of using sticky blocks is still fuzzy.  It could prove to be difficult to design an interface that works well with the current block API.&lt;br /&gt;
&lt;br /&gt;
==Conclusion==&lt;br /&gt;
&lt;br /&gt;
Adding blocks seems to suit lesson well.  By doing so, lesson gains a the following:&lt;br /&gt;
*A more flexible layout.&lt;br /&gt;
*A new powerful tool: blocks.  Users can create their own blocks to plug into lesson.&lt;br /&gt;
*The lesson settings will be reduced.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]] 20:12, 21 December 2006 (CST)&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Developer_notes&amp;diff=18783</id>
		<title>Development:Developer notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Developer_notes&amp;diff=18783"/>
		<updated>2006-12-22T01:30:26Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Modules and other recognised plugin types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Note:&#039;&#039;&#039; New developer documentation pages should be added to the &#039;&#039;Development namespace&#039;&#039; by typing &amp;lt;code&amp;gt;Development:&amp;lt;/code&amp;gt; before the new page name i.e. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Development:New page name]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This area is for developers to work on various bits of code and documentation as necessary. Once material has matured it should be linked to from the main [[Development:Developer documentation|Developer documentation]] page.&lt;br /&gt;
&lt;br /&gt;
==Core code==&lt;br /&gt;
&lt;br /&gt;
*[[Other lang issues|Language issues]] &lt;br /&gt;
*[[Datalib Notes]]&lt;br /&gt;
*[[Application/session variables]]&lt;br /&gt;
*[[Roles]]&lt;br /&gt;
*[[Filters schema]]&lt;br /&gt;
*[[Filterall support]]&lt;br /&gt;
*[[Moodle forms library]]&lt;br /&gt;
*[[Martin form notes]]&lt;br /&gt;
*[[Groups documentation for module developers]]&lt;br /&gt;
&lt;br /&gt;
==Modules and other recognised plugin types==&lt;br /&gt;
&lt;br /&gt;
*[[Forum development|Forum functional upgrade]]&lt;br /&gt;
*[[Blogs and forums|Blogs, forums and the nature of discussion]]&lt;br /&gt;
*[[Conditional activities]]&lt;br /&gt;
*[[Wiki development|Wiki module development]]&lt;br /&gt;
*[[Improved Payment Plugin]]&lt;br /&gt;
*[[Calculated question development]]&lt;br /&gt;
*[[Cleanups required in the quiz and question bank]]&lt;br /&gt;
*[[Adding_question_types_to_lesson|Adding question types to lesson module]]&lt;br /&gt;
*[[Numerical question units and intervals]]&lt;br /&gt;
*[[Development:New lesson navigation | New lesson navigation]]&lt;br /&gt;
*[[Development:Adding blocks to lesson | Adding blocks to lesson]]&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[MoodleDocs development]]&lt;br /&gt;
*[[Usability]]&lt;br /&gt;
*[[Document Management API]]&lt;br /&gt;
*[[wikindx|Possible integration of WIKINDX with Moodle]]&lt;br /&gt;
*[[simple web services]]&lt;br /&gt;
*[[Quiz and quesions community testing day]]&lt;br /&gt;
*[[Development:OM Protocol]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;I split this into three categories becuase the list was getting a bit long.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]] 00:34, 17 August 2006 (WST)&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18660</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18660"/>
		<updated>2006-12-14T19:27:15Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Advantages */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced with Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class more natural.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18659</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18659"/>
		<updated>2006-12-14T19:26:27Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Changes to the lesson module */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced with Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18658</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18658"/>
		<updated>2006-12-14T19:25:54Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Possible uses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (random, linear, etc).&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18657</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18657"/>
		<updated>2006-12-14T19:25:31Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added another bullet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
*Flow change: as described above, this would change the default flow for which the questions are viewed (Random, linear, etc).&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18656</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18656"/>
		<updated>2006-12-14T19:22:52Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Possible uses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples.&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18655</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18655"/>
		<updated>2006-12-14T19:22:19Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added another point&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.&lt;br /&gt;
&lt;br /&gt;
One might ask though, &#039;&#039;how was the navigation defined for Questions #1 and #2?&#039;&#039;  In the lesson settings, one would set the default flow for the lesson.  This default flow could be overridden by the Check Points.&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18654</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18654"/>
		<updated>2006-12-14T19:18:20Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all of the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.  Simple, right?&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18653</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18653"/>
		<updated>2006-12-14T19:17:21Z</updated>

		<summary type="html">&lt;p&gt;Bushido: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.  Simple, right?&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18652</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18652"/>
		<updated>2006-12-14T19:15:35Z</updated>

		<summary type="html">&lt;p&gt;Bushido: /* Author */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer of complication, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.  Simple, right?&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18651</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18651"/>
		<updated>2006-12-14T19:15:08Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Wrote out a rough draft of the rest of the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer of complication, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
For a lack of a better name, &amp;quot;Check Points&amp;quot; could be the solution for which we search.  Check Points would be a special place holder within the lesson layout.  For example:&lt;br /&gt;
&lt;br /&gt;
 Question #1&lt;br /&gt;
 Question #2&lt;br /&gt;
 Check Point&lt;br /&gt;
 Question #3&lt;br /&gt;
 Question #4&lt;br /&gt;
&lt;br /&gt;
At these Check Points, one could define a change in navigation.  So, let&#039;s say that before the Check Point, the navigation was set to linear.  The student would then see Question #1 followed by Question #2.  Once the student came to the Check Point, the navigation could be changed.  Let&#039;s say the Check Point changes the navigation to random.  Thus, after answering Question #2, the student would then see Questions #3 and #4 in random order.  Simple, right?&lt;br /&gt;
&lt;br /&gt;
===Possible uses===&lt;br /&gt;
&lt;br /&gt;
Check Points could be used for much more than changing the order in which a student views the questions.  Here is an idea list for possible uses:&lt;br /&gt;
*Redirect: when a student hits the Check Point, s/he is redirected to another page in the lesson.&lt;br /&gt;
*Conditional: best to explain with examples&lt;br /&gt;
**If student has a current grade of 60% or more, then go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
**If student answered last question correctly, go to &#039;&#039;this&#039;&#039; page.  Otherwise go to &#039;&#039;this&#039;&#039; page.&lt;br /&gt;
&lt;br /&gt;
===Changes to the lesson module===&lt;br /&gt;
&lt;br /&gt;
Here is a quick list of the changes that would take place if Check Points were implemented:&lt;br /&gt;
*Jump definitions would be removed from questions.&lt;br /&gt;
*Cluster and End of Cluster pages would be replaced with Check Points.&lt;br /&gt;
*Branch pages would remain, but End of Branch would be removed.  The functionality between Branch and End of Branch pages would be replaced by Check Points.&lt;br /&gt;
&lt;br /&gt;
===Advantages===&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Primary:&#039;&#039;&#039; this would make the transition to the question type class much more possible.  See this [[Adding_question_types_to_lesson#Questions_and_jumps | problem]] with the migration (Note: &#039;&#039;A new path&#039;&#039; section talks about &#039;&#039;state checkers&#039;&#039;.  &#039;&#039;state checkers&#039;&#039; are the same as Check Points).&lt;br /&gt;
*Centralizes the navigation.  By using Check Points for navigation, we simplify the process for defining and maintaining a lesson&#039;s flow.  When one wants to change the navigation, s/he does not have to choose from a myriad of possibilities, s/he would know to add a Check Point.&lt;br /&gt;
*Check Points provide possibility for potential growth.  When engineering the Check Points, they can be designed to easily support with new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
===Disadvantages===&lt;br /&gt;
&lt;br /&gt;
*Lesson users will have to learn a new form for controlling their lesson&#039;s navigation.&lt;br /&gt;
*Migration to the use of Check Points would require Lesson users to redefine their lesson&#039;s navigation.  Although, some aspects of the navigation can be migrated automatically.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
&lt;br /&gt;
Check Points would provide a simplification to the design of the lesson yet allow for more advanced learning experiences.  A simple example would be if a student is answering all or most of the questions correctly, then the lesson could adapt to a harder set of questions in order to challenge the student (Adaptive Learning).  Also Check Points appear to solve the support problem by centralizing the navigation at both the user level and at the code base level.&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
&lt;br /&gt;
[[User:Mark Nielsen|Mark Nielsen]] 13:15, 14 December 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18650</id>
		<title>Development:New lesson navigation</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:New_lesson_navigation&amp;diff=18650"/>
		<updated>2006-12-14T18:22:53Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added intro and first heading&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the unique features of lesson is its ability to provide different forms of navigation: branching, randomization, linear, etc.  The current form for controlling this navigation is via jump definitions that are defined with nearly every question answer or [[Adding_a_branch_table | Branch]] page button.  Also, the navigation is defined by using special pages called [[Clusters | Cluster and End of Cluster]].  Lastly, to add yet another layer of complication, one can define specific navigation between Branch and End of Branch pages.  With so many options for designing the navigation of the lesson, one can easily get confused and lost.  Further, supporting all of these methods becomes a burden at the user support level and at the code base support level.  Thus, we must take a step back and look toward a new method that could combine all the above methods, but at the same time provide the possibility to support new navigation innovations.&lt;br /&gt;
&lt;br /&gt;
==Check Points==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;a pause for thinking...&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Developer_notes&amp;diff=18646</id>
		<title>Development:Developer notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Developer_notes&amp;diff=18646"/>
		<updated>2006-12-14T18:05:46Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added link to New lesson navigation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;p class=&amp;quot;note&amp;quot;&amp;gt;&#039;&#039;&#039;Note:&#039;&#039;&#039; New developer documentation pages should be added to the &#039;&#039;Development namespace&#039;&#039; by typing &amp;lt;code&amp;gt;Development:&amp;lt;/code&amp;gt; before the new page name i.e. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[Development:New page name]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This area is for developers to work on various bits of code and documentation as necessary. Once material has matured it should be linked to from the main [[Development:Developer documentation|Developer documentation]] page.&lt;br /&gt;
&lt;br /&gt;
==Core code==&lt;br /&gt;
&lt;br /&gt;
*[[Other lang issues|Language issues]] &lt;br /&gt;
*[[Datalib Notes]]&lt;br /&gt;
*[[Application/session variables]]&lt;br /&gt;
*[[Roles]]&lt;br /&gt;
*[[Filters schema]]&lt;br /&gt;
*[[Filterall support]]&lt;br /&gt;
*[[Moodle forms library]]&lt;br /&gt;
*[[Martin form notes]]&lt;br /&gt;
*[[Groups documentation for module developers]]&lt;br /&gt;
&lt;br /&gt;
==Modules and other recognised plugin types==&lt;br /&gt;
&lt;br /&gt;
*[[Forum development|Forum functional upgrade]]&lt;br /&gt;
*[[Blogs and forums|Blogs, forums and the nature of discussion]]&lt;br /&gt;
*[[Conditional activities]]&lt;br /&gt;
*[[Wiki development|Wiki module development]]&lt;br /&gt;
*[[Improved Payment Plugin]]&lt;br /&gt;
*[[Calculated question development]]&lt;br /&gt;
*[[Cleanups required in the quiz and question bank]]&lt;br /&gt;
*[[Adding_question_types_to_lesson|Adding question types to lesson module]]&lt;br /&gt;
*[[Numerical question units and intervals]]&lt;br /&gt;
*[[Development:New lesson navigation | New lesson navigation]]&lt;br /&gt;
&lt;br /&gt;
==Other==&lt;br /&gt;
&lt;br /&gt;
*[[MoodleDocs development]]&lt;br /&gt;
*[[Usability]]&lt;br /&gt;
*[[Document Management API]]&lt;br /&gt;
*[[wikindx|Possible integration of WIKINDX with Moodle]]&lt;br /&gt;
*[[simple web services]]&lt;br /&gt;
*[[Quiz and quesions community testing day]]&lt;br /&gt;
*[[Development:OM Protocol]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;I split this into three categories becuase the list was getting a bit long.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]] 00:34, 17 August 2006 (WST)&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=17943</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=17943"/>
		<updated>2006-11-14T01:29:38Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added another bullet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
*migrate lesson navigation.&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
====A new path====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;by [[User:Mark Nielsen|Mark Nielsen]] 13:43, 13 November 2006 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After a nice discussion with [http://moodle.org/user/view.php?id=3432&amp;amp;course=5 Michael Penney], a new solution to this problem arose.  Instead of working with the current method of each question having a set of defined jumps, instead introduce a new feature called &#039;&#039;state checker&#039;&#039; (the name at the moment, could change later).  These &#039;&#039;state checkers&#039;&#039; could be inserted throughout the lesson and are used to determine the navigation.  These &#039;&#039;state checkers&#039;&#039; could be set to say, &#039;&#039;if student has more than 70% correct then send the student to location X, otherwise send student to location Y.&#039;&#039;  Alternatively, the &#039;&#039;state checker&#039;&#039; could be set to say &#039;&#039;if last question was correct, go to X otherwise go to Y&#039;&#039;.  These examples are binary, but the &#039;&#039;state checker&#039;&#039;, when fully implemented, should allow several more options and more granular control.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*No major changes are required to the question bank code.&lt;br /&gt;
*Lesson navigation can be controlled via one screen and &#039;&#039;&#039;is independent of questions&#039;&#039;&#039;.&lt;br /&gt;
*More possibilities for lesson navigation control.&lt;br /&gt;
*Could reduce the complexity of the multi-stage UI that the other solutions require.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Migration of old navigation structure could prove to be complicated depending on how the &#039;&#039;state checker&#039;&#039; would be developed (NOTE: this is already a problem.  See next section &#039;&#039;Migration of jumps&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=17942</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=17942"/>
		<updated>2006-11-13T19:43:50Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added new solution&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle 2.0}}&lt;br /&gt;
Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
====A new path====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;by [[User:Mark Nielsen|Mark Nielsen]] 13:43, 13 November 2006 (CST)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
After a nice discussion with [http://moodle.org/user/view.php?id=3432&amp;amp;course=5 Michael Penney], a new solution to this problem arose.  Instead of working with the current method of each question having a set of defined jumps, instead introduce a new feature called &#039;&#039;state checker&#039;&#039; (the name at the moment, could change later).  These &#039;&#039;state checkers&#039;&#039; could be inserted throughout the lesson and are used to determine the navigation.  These &#039;&#039;state checkers&#039;&#039; could be set to say, &#039;&#039;if student has more than 70% correct then send the student to location X, otherwise send student to location Y.&#039;&#039;  Alternatively, the &#039;&#039;state checker&#039;&#039; could be set to say &#039;&#039;if last question was correct, go to X otherwise go to Y&#039;&#039;.  These examples are binary, but the &#039;&#039;state checker&#039;&#039;, when fully implemented, should allow several more options and more granular control.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*No major changes are required to the question bank code.&lt;br /&gt;
*Lesson navigation can be controlled via one screen and &#039;&#039;&#039;is independent of questions&#039;&#039;&#039;.&lt;br /&gt;
*More possibilities for lesson navigation control.&lt;br /&gt;
*Could reduce the complexity of the multi-stage UI that the other solutions require.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Migration of old navigation structure could prove to be complicated depending on how the &#039;&#039;state checker&#039;&#039; would be developed (NOTE: this is already a problem.  See next section &#039;&#039;Migration of jumps&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=17629</id>
		<title>Development:Adding question types to lesson</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Development:Adding_question_types_to_lesson&amp;diff=17629"/>
		<updated>2006-10-31T05:42:54Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Added my feedback to Tim&amp;#039;s solution&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please note that this page deals with a future version of [[Moodle 2.0]].&lt;br /&gt;
&lt;br /&gt;
A regularly discussed topic is that Lesson should use the same [[#Questions_and_jumps|question classes]] as [[Quiz]].  This page is geared toward this goal by explaining the different aspects required to complete this project.--Mark Nielsen&lt;br /&gt;
&lt;br /&gt;
I think this would be a really good idea, and am willing to help--[[User:Tim Hunt|Tim Hunt]], Quiz module/question bank maintainer.&lt;br /&gt;
&lt;br /&gt;
==Project goals==&lt;br /&gt;
*(Primary) Implement the [[Question_types|question type classes]] in [[Lesson]].&lt;br /&gt;
*(Primary) Reduce Moodle&#039;s code base.  Instead of Lesson having its own question code, it can now use [[Question_engine|existing code]].&lt;br /&gt;
*Simplify Lesson&#039;s code.  There is a high mix of presentation and logic and some rather confusing algorithms due to the nature of Lesson and how it is organized.&lt;br /&gt;
&lt;br /&gt;
==Primary coding tasks==&lt;br /&gt;
&lt;br /&gt;
===Adding support for question class===&lt;br /&gt;
Implement the question class code and the necessary interfaces for adding and editing questions within Lesson.  The needed functionality is as follows:&lt;br /&gt;
*Printing questions for attempts. &#039;&#039;Should be nothing to do if we are happy with the same presentation for both quiz and lesson&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*[[Question_engine#Grades|Grading]] the questions. &#039;&#039;Again, should be fine, as long as the question_(attempts|sessions|states) model is flexible enough for the quiz&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
*Provide a method of adding new questions to a Lesson. &#039;&#039;Hopefully question/showbank.php will work for you, perhaps with a few changs.&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
**When adding a question, display questions in course question bank to select from.&lt;br /&gt;
***Provide links/tabs for creating new questions.&lt;br /&gt;
**After adding a question, provide an interface to define possible jumps (This step may not be needed.  Depends on the solution to [[#Questions_and_jumps|the questions and jumps]] problem). &#039;&#039;This will be new work&#039;&#039;--[[User:Tim Hunt|Tim Hunt]]&lt;br /&gt;
&lt;br /&gt;
===Changing the attempts logic===&lt;br /&gt;
Among other Lesson table changes, one that is the most significant is changing the &#039;&#039;lesson_attempts&#039;&#039; table. Instead of storing one attempt record for every user answer, &#039;&#039;lesson_attempts&#039;&#039; table should store one record per Lesson attempt. The &#039;&#039;question_states&#039;&#039; table will replace the functionality of the original &#039;&#039;lesson_attempts&#039;&#039; table.  Since this is changing such a fundamental part of Lesson, almost all of Lesson&#039;s code will have to be adapted to the new logic of attempts.&lt;br /&gt;
&lt;br /&gt;
===Fixing code breaks===&lt;br /&gt;
By switching to the question class, nearly all of the current Lesson code will be broken and must be replaced or fixed. Here is a quick breakdown of foreseeable code breaks:&lt;br /&gt;
*High scores&lt;br /&gt;
*[[Lesson_reports|Lesson reports]]&lt;br /&gt;
**[[Quiz_reports|Quiz reports]] might provide a jump start(?)&lt;br /&gt;
*[[Lesson_module#Pages.2C_questions.2C_answers_and_responses|Page authoring]]&lt;br /&gt;
*[[Jumps#Special_jumps|Jump type interpretation algorithms]]&lt;br /&gt;
*On-going score&lt;br /&gt;
*Progress bar&lt;br /&gt;
*Backup/restore&lt;br /&gt;
**Rewrite for new table structures&lt;br /&gt;
**Add support for restoring Lessons prior question class support&lt;br /&gt;
**Add support in the primary backup/restore routines&lt;br /&gt;
&lt;br /&gt;
===Database migration===&lt;br /&gt;
Lesson tables need to be removed or changed and their old data needs to be migrated to new tables. Some of this code will be used in the restore process as well. Here is a basic overview of the database migration process:&lt;br /&gt;
*migrate &#039;&#039;lesson_pages&#039;&#039; and &#039;&#039;lesson_answer&#039;&#039; content to question tables.  Note: this will only be the content, not the logic for ordering Lesson pages or any other Lesson specific data.&lt;br /&gt;
*migrate &#039;&#039;lesson_attempts&#039;&#039; to &#039;&#039;question_states&#039;&#039;.&lt;br /&gt;
*Re-organization of the lesson tables (see [[#New_database_schema|new database schema]]).&lt;br /&gt;
&lt;br /&gt;
==Unsolved problems==&lt;br /&gt;
Here are some tricky issues that do not have a solid or obvious solution.  Please advise.&lt;br /&gt;
&lt;br /&gt;
===Questions and jumps===&lt;br /&gt;
Page [[Jumps|jumps]] determine the flow from one page to another and are a unique feature to Lesson.  So, how does one figure out all the necessary jump definitions needed for a question?  In Lesson, every answer has a jump, but this solution is not ideal.  A multiple choice question for example would have two cases: &lt;br /&gt;
*Single answer: a jump must be defined for each answer.&lt;br /&gt;
*[[Lesson_module#Multiple_choice.2C_multiple_answer|Multiple answer]]: a jump would be defined for the correct answer and a jump for the wrong answer.&lt;br /&gt;
&lt;br /&gt;
The follow two sections discuss possible solutions, but please feel free to suggest others.  When thinking about this problem and perhaps a new solution, remember the primary goals of this project: reduce code size and simplify the Lesson code to make it easier to maintain.&lt;br /&gt;
&lt;br /&gt;
====Invasive solution====&lt;br /&gt;
An invasive solution would be to modify the question class code.  This is invasive because the introduced code may only be used by Lesson unless it was implemented in such a way that it would be viable for other uses.  Some of the foreseeable changes would include the following:&lt;br /&gt;
*Add methods to the &#039;&#039;default_questiontype&#039;&#039; class that would handle the default behavior for defining jumps.  Default behavior would be two jump definitions: one for correct answers and one for incorrect answers.&lt;br /&gt;
*Provide a place to store the defined jumps.&lt;br /&gt;
*In each question type, override the default methods in the &#039;&#039;default_questiontype&#039;&#039; class to suite the behavior of the question (optional for each question type).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*All question type code is in one place.&lt;br /&gt;
*Clean implementation&lt;br /&gt;
*Better work-flow for question authoring&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Potentially introduce code that is unusable by other modules, etc.&lt;br /&gt;
&lt;br /&gt;
====Noninvasive solution====&lt;br /&gt;
Lesson would extend all question types that to handle jumps.  Lesson would have its own &#039;&#039;type&#039;&#039; folder (mod/lesson/type).  This &#039;&#039;type&#039;&#039; folder would be organized the same as &#039;&#039;question/type&#039;&#039; directory.  Each question type would have its own folder and in that folder a &#039;&#039;questiontype.php&#039;&#039;.  So, &#039;&#039;mod/lesson/type/{questiontype}/questiontype.php&#039;&#039; where {questiontype} is replaced with each question type name. The &#039;&#039;questiontype.php&#039;&#039; would extend the original question type class and add the necessary methods for handling jumps.  The following methods would be added:&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form:&#039;&#039;&#039; accepts the possible jump values from Lesson and then print (or return) the contents of a form.  This form would then be presented to the user to define the possible jumps.&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form:&#039;&#039;&#039; accepts the form data from &#039;&#039;&#039;print_jump_form&#039;&#039;&#039; and organize it.  It then returns the organized data so that Lesson can store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump:&#039;&#039;&#039; accepts the user&#039;s answer to the question and the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039;.  This method would determine which jump Lesson should use.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps:&#039;&#039;&#039; restore the returned value from &#039;&#039;&#039;process_jump_form&#039;&#039;&#039; during Lesson&#039;s restore routine.  Returns the restored value so that Lesson can store it.&lt;br /&gt;
&lt;br /&gt;
Example use:&lt;br /&gt;
&lt;br /&gt;
Two jump definitions: correct or incorrect:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;print_jump_form&#039;&#039;&#039; would return the following form:&lt;br /&gt;
  Correct answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
  Wrong answer jump: [drop-down-menu-with-lesson-jumps]&lt;br /&gt;
*&#039;&#039;&#039;process_jump_form&#039;&#039;&#039; would accept the POST data from the above form and organize it in an array like this: array(&#039;correct&#039; =&amp;gt; [lesson-jump-code], &#039;wrong&#039; =&amp;gt; [lesson-jump-code]).  Where [lesson-jump-code] is a Lesson page id or jump code from the [drop-down-menu-with-lesson-jumps].  This array would be returned so that Lesson could store it.&lt;br /&gt;
*&#039;&#039;&#039;interpret_jump&#039;&#039;&#039; would accept the students answer and the above array.  It would return the [lesson-jump-code] either associated with &#039;&#039;correct&#039;&#039; or &#039;&#039;wrong&#039;&#039; based on the student&#039;s answer.&lt;br /&gt;
*&#039;&#039;&#039;restore_jumps&#039;&#039;&#039; would be called during the Lesson restore process and it would return the restored array so that Lesson could store it.  Example: if each answer had a jump then the array would be defined like this: array(answerid =&amp;gt; [lesson-jump-code] ... ).  The &#039;&#039;answerid&#039;&#039; would have to be mapped to the new answerid during the restore process.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Pros for this implementation:&#039;&#039;&#039;&lt;br /&gt;
*Potential Lesson specific code remains in Lesson.&lt;br /&gt;
&#039;&#039;&#039;Cons:&#039;&#039;&#039;&lt;br /&gt;
*Work-flow would have an extra step (create question then define jumps).&lt;br /&gt;
*Creating new question types is more difficult.&lt;br /&gt;
&lt;br /&gt;
====A middle way====&lt;br /&gt;
&lt;br /&gt;
I (Tim) don&#039;t like either of the above two solutions. I don&#039;t like excessively lesson specific code in the question types, but it would be really bad if the code for a particular question type was not all in one place.&lt;br /&gt;
&lt;br /&gt;
I think that the solution is to add a new concept: question outcomes. It will take me a couple of paragraphs to explain what I mean with this.&lt;br /&gt;
&lt;br /&gt;
Currently, after a student attempts a question, you get stuff that falls into two categories:&lt;br /&gt;
# generic stuff, like the grade (both before and after applying the penalty factor), the penalty factor itself, the classification of the before grade as Correct/Partially Correct/Incorrect, a possible manual comment added by the teacher, the state of the question (saved, graded, manual graded, closed)&lt;br /&gt;
# question-type specific stuff, like the data in question_states-&amp;gt;answer column, or the feedback that is displayed on-screen.&lt;br /&gt;
&lt;br /&gt;
I think that in the generic stuff category, we need to add the new concept of &#039;outcome&#039;. This would be what the lesson module uses to select branches, and would probably also be useful to the quiz reports. It would categorise the student&#039;s answer into one of a number of categories, and the question type class would need to implement two new methods:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;array of strings&#039;&#039; all_outcomes($question)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;string&#039;&#039; outcome($question, $state)&lt;br /&gt;
&lt;br /&gt;
For multiple-choice (single response) this would return the answer selected. For shortanswer, numerical and calculated, this would return the answer that was matched. The generic implementation in the base class would probably have to just return &#039;incorrect&#039;/&#039;partiallycorrect&#039;/&#039;correct&#039; (that is the ids of the strings that are looked up in the language file. &lt;br /&gt;
&lt;br /&gt;
The lesson would then need to do branching be specifying where to go for each outcome. It would requre a multi-stage UI (create the question using the standard questionbank code, add the question to the lesson, link up the outcomes to jump targets). However, done well, this could be a very natural UI.&lt;br /&gt;
&lt;br /&gt;
The quiz UI is not perfect, but I think the way it is now: create a question, then add the question to the quiz, then adjust the grade for that question within the quiz, is very natural to use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;comment&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:This sounds like a generalization of the first solution.  The question types would provide the options (outcomes) that need jump associations that are defined by lesson.  The workflow is far different from what lesson currently has, but it sounds necessary and reasonable.&lt;br /&gt;
&lt;br /&gt;
:It also appears that lesson would be storing the outcome/jump associations, which is fine a long as the outcome does not change with question editing.  Not sure how this would work for multi-choice (single response).&lt;br /&gt;
&lt;br /&gt;
:This is why I posted my solutions :)  I did not like them either, but I was hoping that they would inspire better solutions.  Thank you Tim, I think your solution is much closer to the final solution than mine were.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&amp;lt;/comment&amp;gt;&#039;&#039; - [[User:Mark Nielsen|Mark Nielsen]] 23:42, 30 October 2006 (CST)&lt;br /&gt;
&lt;br /&gt;
====Migration of jumps====&lt;br /&gt;
Regardless of implementation, one problem remains: if each question potentially does not have a jump defined for each answer, then how are the currently defined jumps supposed to be migrated to the new question implementation (remember, Lesson questions have one jump defined for each answer regardless if it makes sense at all)?  The only solution that comes to mind is to have strict definitions for migration for the following [[Lesson#Types_of_questions_available_within_a_lesson|question types that exist in Lesson]]:&lt;br /&gt;
*Multichoice (single and multianswer)&lt;br /&gt;
*Matching&lt;br /&gt;
*Numerical&lt;br /&gt;
*Short Answer&lt;br /&gt;
*True/False&lt;br /&gt;
*Essay&lt;br /&gt;
&lt;br /&gt;
Note: the use of migration here refers to upgrading old Lessons &#039;&#039;&#039;and&#039;&#039;&#039; restoring older Lessons.&lt;br /&gt;
&lt;br /&gt;
===Branch tables===&lt;br /&gt;
Once a solution for the above problem has been found, I would like to discuss the possibility of replacing the functionality of [[Lesson#Branches_and_branch_tables|branch tables]] with the [[Question_types#Description|description question type]].  Reason for discussing this after a solution has been found is because the solution may influence the outcome to this problem.&lt;br /&gt;
&lt;br /&gt;
==New database schema==&lt;br /&gt;
&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  | &#039;&#039;&#039;course_modules&#039;&#039;&#039; |      | [[#lesson_default|lesson_default]] |&lt;br /&gt;
  |                |      |                |&lt;br /&gt;
  ------------------      ------------------&lt;br /&gt;
          |                        |&lt;br /&gt;
          |                        |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   |   [[#lesson|lesson]]   |-----------|   &#039;&#039;&#039;course&#039;&#039;&#039;   |&lt;br /&gt;
   |            |           |            |&lt;br /&gt;
   --------------           --------------&lt;br /&gt;
          |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |------| [[#lesson_high_scores|lesson_high_scores]] |------|  &#039;&#039;&#039;user&#039;&#039;&#039;  |&lt;br /&gt;
          |      |                    |      |        |&lt;br /&gt;
          |      ----------------------      ----------&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |------| [[#lesson_grades|lesson_grades]] |----------------|&lt;br /&gt;
          |      |               |                |&lt;br /&gt;
          |      -----------------                |&lt;br /&gt;
          |                                       |&lt;br /&gt;
          |      -------------------              |&lt;br /&gt;
          |      |                 |--------------|    ---------------------&lt;br /&gt;
          |------| [[#lesson_attempts|lesson_attempts]] |                   |                   |&lt;br /&gt;
          |      |                 |-------------------| &#039;&#039;&#039;question_attempts&#039;&#039;&#039; |&lt;br /&gt;
          |      -------------------                   |                   |&lt;br /&gt;
          |                                            ---------------------&lt;br /&gt;
          |      ----------------&lt;br /&gt;
          |      |              |&lt;br /&gt;
          |------| [[#lesson_pages|lesson_pages]] |&lt;br /&gt;
                 |              |&lt;br /&gt;
                 ----------------&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |------| [[#lesson_question_instances|lesson_question_instances]] |------| &#039;&#039;&#039;[[Quiz_database_structure#question|question]]&#039;&#039;&#039; |&lt;br /&gt;
                        |      |                           |      |          |&lt;br /&gt;
                        |      -----------------------------      ------------&lt;br /&gt;
                        |      &lt;br /&gt;
                        |      -------------------&lt;br /&gt;
                        |      |                 |&lt;br /&gt;
                        |------| [[#lesson_branches|lesson_branches]] |&lt;br /&gt;
                               |                 |&lt;br /&gt;
                               -------------------&lt;br /&gt;
*&#039;&#039;&#039;Note&#039;&#039;&#039;: tables in &#039;&#039;&#039;bold&#039;&#039;&#039; are standard in Moodle and are there only to show relations.&lt;br /&gt;
&lt;br /&gt;
==Table Descriptions==&lt;br /&gt;
&lt;br /&gt;
Key:&lt;br /&gt;
*PK = primary key&lt;br /&gt;
*FK = foreign key&lt;br /&gt;
&lt;br /&gt;
===lesson===&lt;br /&gt;
Primary module table&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*course: FK to course&lt;br /&gt;
*name: Name of the lesson&lt;br /&gt;
*practice: Flag for practice lessons&lt;br /&gt;
*modattempts&lt;br /&gt;
*password: Stores password for password protected lessons&lt;br /&gt;
*dependency: FK to [[#lesson|lesson]] table.  The lesson that this lesson is dependent upon&lt;br /&gt;
*conditions: conditions for the dependency&lt;br /&gt;
*grade: Max grade for the lesson&lt;br /&gt;
*cusom: custom scoring flag&lt;br /&gt;
*ongoing: display on going score flag&lt;br /&gt;
*usemaxgrade: use max grade or mean flag&lt;br /&gt;
*maxanswers: maximum answers for a question (would only be used by branch tables, remove?)&lt;br /&gt;
*maxattempts: number of attempts on a question&lt;br /&gt;
*review&lt;br /&gt;
*nextpagedefault: default flow control&lt;br /&gt;
*minquestions: minimum questions to answer&lt;br /&gt;
*maxpages&lt;br /&gt;
*time: allowed time in the lesson per attempt&lt;br /&gt;
*retake: allow student to retake&lt;br /&gt;
*activitylink: FK to course_modules table&lt;br /&gt;
*mediafile&lt;br /&gt;
*mediaheight: height of pop-up&lt;br /&gt;
*mediawidth: width of pop-up&lt;br /&gt;
*mediaclose: display close button for media&lt;br /&gt;
*slideshow: display branches in slide show mode flag&lt;br /&gt;
*width: width of slide show&lt;br /&gt;
*height: height of slide show&lt;br /&gt;
*bgcolor: background color of slide show&lt;br /&gt;
*displayleft: display left menu&lt;br /&gt;
*displayleftif: display left menu if student has already completed lesson flag&lt;br /&gt;
*progressbar: display progress bar flag&lt;br /&gt;
*highscores: high scores&lt;br /&gt;
*available: when lesson is available to student&lt;br /&gt;
*deadline: when lesson closes to student&lt;br /&gt;
*timemodified: last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_default===&lt;br /&gt;
Lesson default settings for a course.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*same as the lesson table minus the following fields: name, dependency, activity, mediafile, available, deadline, and modified&lt;br /&gt;
&lt;br /&gt;
===lesson_high_scores===&lt;br /&gt;
Keep track of the lesson top scores.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*gradeid: FK to [[#lesson_grades|lesson_grades]] table&lt;br /&gt;
*nickname: user&#039;s nickname&lt;br /&gt;
&lt;br /&gt;
===lesson_grades===&lt;br /&gt;
User attempt grades.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*grade: attempt grade&lt;br /&gt;
*completed: time of completion&lt;br /&gt;
&lt;br /&gt;
===lesson_attempts===&lt;br /&gt;
Lesson attempts by users.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*uniqueid: FK to question_sessions table&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*userid: FK to user table&lt;br /&gt;
*path: users path through the lesson (comma separated list of page ids from the [[#lesson_pages|lesson_pages]] table)&lt;br /&gt;
*attempt: user&#039;s attempt count&lt;br /&gt;
*sumgrade: current total for grades&lt;br /&gt;
*timestart: starting time of attempt&lt;br /&gt;
*timefinish: ending time of attempt&lt;br /&gt;
*timemodified: last time updated&lt;br /&gt;
&lt;br /&gt;
===lesson_pages===&lt;br /&gt;
All content pages in lesson.&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*prevpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*nextpageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*type: values include&lt;br /&gt;
**branch&lt;br /&gt;
**endofbranch&lt;br /&gt;
**cluster&lt;br /&gt;
**endofcluster&lt;br /&gt;
**question&lt;br /&gt;
*display: display in left menu flag&lt;br /&gt;
*jumps: jumps related to this page&lt;br /&gt;
*timemodified: time last updated&lt;br /&gt;
&lt;br /&gt;
===lesson_question_instances===&lt;br /&gt;
Store relation between lesson pages that are questions and the question table. (does not exist in moodle 1.6.1 standard)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*questionid: FK to [[Quiz_database_structure#question|question]] table&lt;br /&gt;
*grade: point value of the question&lt;br /&gt;
&lt;br /&gt;
===lesson_branches===&lt;br /&gt;
Lesson pages that are branch tables. (does not exist in moodle 1.6.1 but there is different set of fields in lesson_branch)&lt;br /&gt;
&lt;br /&gt;
Fields:&lt;br /&gt;
*id: PK&lt;br /&gt;
*lessonid: FK to [[#lesson|lesson]] table&lt;br /&gt;
*pageid: FK to [[#lesson_pages|lesson_pages]] table&lt;br /&gt;
*boilerplates: text of branch buttons&lt;br /&gt;
*layout: layout of branch buttons&lt;br /&gt;
&lt;br /&gt;
==Discussion==&lt;br /&gt;
If you would like to discuss topics on this page, please make a post in the [http://moodle.org/mod/forum/view.php?f=333 lesson forum].&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[http://moodle.org/mod/forum/discuss.php?d=42563 Original lesson forum discussion]&lt;br /&gt;
*[[Question_engine|Question engine]]&lt;br /&gt;
*[[Lesson|Lesson module]]&lt;br /&gt;
*[[Quiz database structure#Overview]] - now, at last, with a diagram of the structure in 1.7.&lt;br /&gt;
&lt;br /&gt;
[[Category:Future]]&lt;br /&gt;
[[Category:Moodle 2.0]]&lt;br /&gt;
[[Category:Developer]]&lt;br /&gt;
[[Category:Lesson]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=File:Quickmail-en-blockdisplay-screenshot.jpg&amp;diff=16512</id>
		<title>File:Quickmail-en-blockdisplay-screenshot.jpg</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=File:Quickmail-en-blockdisplay-screenshot.jpg&amp;diff=16512"/>
		<updated>2006-09-30T21:04:05Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Quickmail block added to a course.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Quickmail block added to a course.&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/39/en/index.php?title=Latest_release_notes&amp;diff=16187</id>
		<title>Latest release notes</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/39/en/index.php?title=Latest_release_notes&amp;diff=16187"/>
		<updated>2006-09-23T00:38:00Z</updated>

		<summary type="html">&lt;p&gt;Bushido: Some more items to lesson improvements&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{About Moodle}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.7 - development version==&lt;br /&gt;
Expected in September, 2006; available as nightly builds or from CVS HEAD. Please do not install on production sites yet.&lt;br /&gt;
&lt;br /&gt;
===Headline features===&lt;br /&gt;
&lt;br /&gt;
* [[Roles]]&lt;br /&gt;
:: Permissions based on fine-grained capabilities allow all kinds of roles to be created and assigned in all contexts around Moodle.&lt;br /&gt;
* [[XML database schema]]&lt;br /&gt;
:: added support for MS-SQL with more databases to come&lt;br /&gt;
* [[Unit tests|Unit testing framework]]&lt;br /&gt;
:: Making it easier for developers to write test code, which should ultimately lead to a more reliable Moodle.&lt;br /&gt;
&lt;br /&gt;
===Other improvements===&lt;br /&gt;
&lt;br /&gt;
* Improvements to the [[Lesson|Lesson module]]&lt;br /&gt;
**Now has a more unified view of lesson screens.&lt;br /&gt;
**Teacher editing:&lt;br /&gt;
***Collapsed view is formatted more nicely, displays more information regarding each page and allows the creation of new pages.&lt;br /&gt;
***Editing is now speedier by replacing 3 second redirect delays with a notification system.&lt;br /&gt;
**New feature: display default feedback.&lt;br /&gt;
***Default is &#039;&#039;&#039;On&#039;&#039;&#039; so previous lessons behave as before.&lt;br /&gt;
***Description: if no &#039;&#039;response&#039;&#039; is entered for a question answer and this setting is turned &#039;&#039;&#039;Off&#039;&#039;&#039;, then the user skips the feedback page.&lt;br /&gt;
**Graceful degrade of JavaScript.&lt;br /&gt;
**Several bug fixes.&lt;br /&gt;
&lt;br /&gt;
* Improvements to the [[Quiz|Quiz module]]&lt;br /&gt;
:* The teacher can configure comments that are displayed to the student at the end of their attempt, with the comment displayed depending on the student&#039;s score.&lt;br /&gt;
&lt;br /&gt;
* Improvements to some core question types&lt;br /&gt;
:* All question types can now have some general feedback. This is displayed to all students after they have finished the question (depending on the quiz settings) and does not depend on what response the student gave. Use this to tell the student what the question was about, or link them to more information about the topic it covers.&lt;br /&gt;
:* [[Matching question type|Matching]] questions can have extra wrong answers, and work when two questions have the same answer.&lt;br /&gt;
:* [[Multiple Choice question type|Multiple Choice]] questions can have feedback for the whole question, as well as specific answers. This is particularly useful for multiple-response questions.&lt;br /&gt;
:* [[Numerical question type|Numerical]] questions can have different answers with different precisions and scores. (Previously this was only supported via GIFT import. Now you can edit questions like this.)&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.6.2+==&lt;br /&gt;
To be later released as 1.6.3, available as nightly builds or from CVS branch MOODLE_16_STABLE.&lt;br /&gt;
&lt;br /&gt;
===Bug Fixes===&lt;br /&gt;
&lt;br /&gt;
* Fixed growing size of backups - existing backup files are no longer included in backups&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.6.2==&lt;br /&gt;
12th September, 2006&lt;br /&gt;
&lt;br /&gt;
===Security===&lt;br /&gt;
* Fixed handling of uploaded files in Database module&lt;br /&gt;
* Module instance id is now properly validated when creating course module object; developers should use get_coursemodule_from_id() to get valid $cm&lt;br /&gt;
* Default error reporting level was lowered to 5, E_WARNINGs are no longer displayed on production sites with debug off.&lt;br /&gt;
* Multiple problems leading to information leakage fixed in help.php file&lt;br /&gt;
* Fixed information leakage from scheduled backups&lt;br /&gt;
* Added basic detection of dataroot accessible from Internet, web installer now better suggests dataroot location outside of web file area&lt;br /&gt;
* Swf is now disabled by default in Mediaplugin&lt;br /&gt;
* forgot_password.php does not allow remote email or username enumeration by default, the old behavior can be enabled by setting protectusernames to No in site configuration&lt;br /&gt;
* Undisclosed SQL injections fixed by automatic data conversions in adodb layer&lt;br /&gt;
* Theoretical XSS problems fixed in doc/index.php and files/index.php scripts&lt;br /&gt;
* Access to tex and algebra files is blocked when filters are disabled&lt;br /&gt;
* Request for redirection in jumpto.php protected with sesskey&lt;br /&gt;
&lt;br /&gt;
===Bug Fixes===&lt;br /&gt;
&lt;br /&gt;
* Fixed error when upgrading forum read tracking&lt;br /&gt;
* Locales from language packs should finally work - please check your configuration variables and empty the locale field&lt;br /&gt;
* Added missing link for course request&lt;br /&gt;
* Fixed several glossary problems with non-ascii characters&lt;br /&gt;
* Fixed bug where you could not regrade a quiz question where the teacher had added a comment with a &#039; character.&lt;br /&gt;
* Quiz import of BlackBoard V6 files now much more reliable&lt;br /&gt;
* Fixed scheduled backups - they were broken in 1.6 and 1.6.1&lt;br /&gt;
* Fixed missing guest icons from course listing&lt;br /&gt;
* Database sessions respect sessiontimeout setting&lt;br /&gt;
* Fixed redirect problems during upgrade resulting in &amp;quot;Table xxx already exists&amp;quot;&lt;br /&gt;
* Lesson module: the &amp;quot;(Continue)&amp;quot; no longer displays for 3 seconds after branch tables.&lt;br /&gt;
* Lesson module: now properly checks import formats for support.&lt;br /&gt;
* Lesson module: feedback is set properly during the import process.&lt;br /&gt;
* and many other smaller fixes&lt;br /&gt;
&lt;br /&gt;
===New Features===&lt;br /&gt;
&lt;br /&gt;
* Authorize.net Payment Gateway: Autoconfigures credit card types if the merchant does not accept some types of credit cards&lt;br /&gt;
&lt;br /&gt;
===Known Problems===&lt;br /&gt;
* Broken images in published question categories&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.6.1==&lt;br /&gt;
20th July, 2006&lt;br /&gt;
&lt;br /&gt;
===Bug Fixes===&lt;br /&gt;
&lt;br /&gt;
* Fixed regression in Turkish locale handling&lt;br /&gt;
* Authorize and Paypal enrolment plugin cleanup&lt;br /&gt;
* Fixed serious problem with failing Database restore&lt;br /&gt;
* Fixed restore of HotPot module containing attempts&lt;br /&gt;
* Minor Database module fixes&lt;br /&gt;
* National characters in graphs now work for most languages out of the box&lt;br /&gt;
* Reviewed and fixed all *nix locale codes in language packs&lt;br /&gt;
* Fixed problems when using Resources with Blocks on the frontpage&lt;br /&gt;
* Fixed missing events on the first day of month in calendar&lt;br /&gt;
* Fixed several problems in Lesson - scores, branch tables, HTML editor issues&lt;br /&gt;
* Fixed broken intermodule relinking of absolute paths - please do not use course backups from original 1.6&lt;br /&gt;
* PDF byteserving problems caused by incorrect partial content length solved&lt;br /&gt;
* Fixed several regressions in handling of multiple groups&lt;br /&gt;
* Fixed alphabet problems in Glossary&lt;br /&gt;
* Chameleon theme fixes and enhancements&lt;br /&gt;
* Fixed all hard coded admin paths&lt;br /&gt;
* Fixed moving of course sections&lt;br /&gt;
* Fixed grading of Essays in Quiz&lt;br /&gt;
* Several Quiz regrading problems solved&lt;br /&gt;
* Questions are now exported into backupdata directory&lt;br /&gt;
* Added workaround for problems when editting two quizes in one browser&lt;br /&gt;
* Lots of other Quiz related bugs fixed - thanks Tim!&lt;br /&gt;
&lt;br /&gt;
* Fixed IE unsecure items warning on sites with https login&lt;br /&gt;
* Improved cookie test on the login page&lt;br /&gt;
* Potential security issue with unzipping maliciously-crafted zip files fixed&lt;br /&gt;
* Satinized input parameters in help.php&lt;br /&gt;
* Calendar view.php now respects forcelogin setting&lt;br /&gt;
&lt;br /&gt;
* And lots of other minor fixes worth upgrading&lt;br /&gt;
&lt;br /&gt;
===New Features===&lt;br /&gt;
&lt;br /&gt;
* Enhanced frontpage settings - frontpage can now be different for logged in users, changed category list display&lt;br /&gt;
* Improved administration page layout&lt;br /&gt;
* Possibility to change graph font for all locales - moodledata/lang/default.ttf takes precedence over lib/default.ttf&lt;br /&gt;
* Local language packs may also contain default.ttf&lt;br /&gt;
* Backported improved lang.php from HEAD&lt;br /&gt;
* New config.php option $CFG-&amp;gt;allowvisiblecoursesinhiddencategories&lt;br /&gt;
&lt;br /&gt;
===Known Problems===&lt;br /&gt;
&lt;br /&gt;
* Broken images in published question categories&lt;br /&gt;
* Small number of sites reports problems with Quiz upgrade - please always do a full database backup before any upgrade!&lt;br /&gt;
&lt;br /&gt;
===Related===&lt;br /&gt;
&lt;br /&gt;
* Third party modules should be already updated for 1.6.x - you must install new versions before UTF-8 migration!&lt;br /&gt;
* New integration of phpMyAdmin available - fixes upstream security problems and compatiblility with PHP 5&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.6==&lt;br /&gt;
19th June, 2006&lt;br /&gt;
&lt;br /&gt;
NOTE: Moodle 1.6 requires PHP 4.3.0 (or PHP 5.1.0) and MySQL 4.1.16 (4.1.12 if you use latin languages only). Here is more info on [[Upgrading to Moodle 1.6]].&lt;br /&gt;
&lt;br /&gt;
===New features===&lt;br /&gt;
&lt;br /&gt;
* [[UTF-8 migration|Unicode]]&lt;br /&gt;
::Moodle is now 100% Unicode, which means any language can be mixed together and an end to a number of problems that different character sets caused us.&lt;br /&gt;
* [[MoodleDocs development|Documentation]]&lt;br /&gt;
::A new one-stop wiki site for ALL Moodle documentation, including links from Moodle itself&lt;br /&gt;
* [[Database module]]&lt;br /&gt;
::A new activity module that allows collaborative collection of structured data, useful for many things!&lt;br /&gt;
* [[LAMS]]&lt;br /&gt;
::Integrated via a course format and an activity module&lt;br /&gt;
* [[Blogs]]&lt;br /&gt;
::Allows reflection on an ongoing basis.  Entries are marked and can be viewed by user, course, group, site etc.  Contains first new support for [[Tags]].  &lt;br /&gt;
* [[Reports]]&lt;br /&gt;
::All reports are now centralised under Course reports and Admin reports.  New reports can be written as plugins and dropped in very easily.  One big new report is the new course-based statistics system from Catalyst.&lt;br /&gt;
* [[Questions]]&lt;br /&gt;
::A centralized bank of questions with the potential to be (re-)used in a variety of modules.&lt;br /&gt;
* [[My Moodle]]&lt;br /&gt;
::A dashboard interface that allows an overview for each user of all their courses etc.&lt;br /&gt;
* [[Hive integration]]&lt;br /&gt;
::This initial integration with Hive allows teachers to upload, browse, search and select [[Resources|resources]] within the external repository.&lt;br /&gt;
* [[Multiple groups]]&lt;br /&gt;
::Users can be part of multiple groups within a course&lt;br /&gt;
* [[IMS content package]] resource type&lt;br /&gt;
::Supports the loading of any content package as a resource, with an optional repository for sharing packages between courses.&lt;br /&gt;
* [[Course backup|Granularised backup]]&lt;br /&gt;
* [[Chameleon|Chameleon theme]]&lt;br /&gt;
:: An interactive Moodle theme&lt;br /&gt;
* [[Enrolment plugins|Multi enrolment]]&lt;br /&gt;
::Moodle&#039;s enrolment plugins can be used simultaneously on the same site. Also new [[IMS Enterprise]] enrolment plugin.&lt;br /&gt;
*[[Authorize.net Payment Gateway]] enrolment plugin &lt;br /&gt;
::New feature called &#039;Order Review&#039;. Admins and teachers may accept or deny payments before processing the credit card and they can also refund payments after processing the credit card in &#039;Payment Management&#039; page. Students may view their order details. Address Verification System (AVS) and Scheduled-Capture support added. For &#039;Manual-Capture&#039; admins are notified 5 days prior to pending orders expiring.&lt;br /&gt;
===See also===&lt;br /&gt;
*[[:Category:Moodle 1.6|Moodle 1.6 features]]&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.5.4==&lt;br /&gt;
21st May, 2006&lt;br /&gt;
&lt;br /&gt;
(Because this release contains important security fixes, we highly advise that sites using any previous version of Moodle upgrade to this version as soon as possible.)&lt;br /&gt;
&lt;br /&gt;
===Various fixes===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Security&#039;&#039;&#039;&lt;br /&gt;
* Improved kses cleaning of html SC#204&lt;br /&gt;
* Prevent unwanted password change here SC#225&lt;br /&gt;
* Fix for Secunia Advisory SA18267, plus some logging of suspicious activity.&lt;br /&gt;
* AdoDB tests cleanup after Secunia Advisory SA18267&lt;br /&gt;
* Fixed $cfg-&amp;gt;forceloginforprofiles logic SC#207. Backported from HEAD&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;General&#039;&#039;&#039;&lt;br /&gt;
* Various updates/improvements in the the Environmental Check allowing to check if your server suits future Moodle requirements.&lt;br /&gt;
* Bug 4619. Fixed one DB query not following coding rules.&lt;br /&gt;
* Bug 4607. Avoid duplication of course shortname on restore.&lt;br /&gt;
* Fixed one problem with auto-link filters and frames.&lt;br /&gt;
* Important fixes to muti-byte text handling routines.&lt;br /&gt;
* Small changes to the installer.&lt;br /&gt;
* Bug 3853. Some important improvements in the restore of log actions.&lt;br /&gt;
* Bug 4328. Prevent some warnings in the blocks system.&lt;br /&gt;
* Bug 4341. Extending multi-lang support to the &amp;quot;jumpto&amp;quot; menu (showed in collapsed mode).&lt;br /&gt;
* Added rss_get_url() to 1.5 to help support data module&lt;br /&gt;
* Added support for having a linked tab even if it is currently selected.&lt;br /&gt;
* RSS Client block: Removed secondary cache. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4625 Bug 4625]&lt;br /&gt;
* Email confirmation now includes lastname. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4869 Bug 4869]&lt;br /&gt;
* Database connection errors can now be reported to an admin. See $CFG-&amp;gt;emailconnectionerrors in config-dist.php.&lt;br /&gt;
* Metacourses: Fixed a problem with self enrolment in child courses.&lt;br /&gt;
* Several MySQL v5 compatibility fixes&lt;br /&gt;
* Avoid listing more than 200 courses in my courses block, and course listing pages.&lt;br /&gt;
* SCORM: Fixed lesson status skin support&lt;br /&gt;
* Skype: Added webstatus icon&lt;br /&gt;
* File uploads: Only create a directory if needed, [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4659 bug 4659]&lt;br /&gt;
* Admin Block. Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4627 bug 4627]: Hide &amp;quot;change password&amp;quot; link in admin block if the user is restricted. Credits for report &amp;amp; patch go to Joseph Rezeau.&lt;br /&gt;
* HTMLArea: Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4562 bug 4562]. Fix posted by sgarcia.&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4626 bug 4626] - weblib.php: $course object conversion error in &amp;amp;quot;print_footer &amp;amp;quot; function&lt;br /&gt;
* Messaging: Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4621 bug 4621] errors in MySQL v3.23 with message backup.&lt;br /&gt;
* Introducing Admin-&amp;gt;Environment to help users assess installed software prior to the 1.6 upgrade&lt;br /&gt;
* Course Restore: Now we avoid duplicates. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4607 Bug 4607]&lt;br /&gt;
* Assignment: Guests can no longer submit an online assignment. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4604 Bug 4604]&lt;br /&gt;
* File Downloads: Fixed problems for slow (dial up) clients, and avoid hogging memory when PHP&#039;s output compression is on.&lt;br /&gt;
* Wiki: Supports initial load of contents from course file area. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=3830 Bug 3830]&lt;br /&gt;
* Lesson: Now when a teacher edits a page with the &amp;quot;Edit page contents&amp;quot; button and then saves or cancels, s/he gets redirected back to the lesson navigation. This will help to streamline the editing.&lt;br /&gt;
* Activity Modules Block - [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4586 bug 4586]&lt;br /&gt;
* Metacourse: Fixes unenrolling [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4541 bug 4541]&lt;br /&gt;
* File uploads: Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4533 bug 4533] - Max upload size at course level ignored.&lt;br /&gt;
* Enrol/Authorize.net: Added Address Verification System (AVS) support.&lt;br /&gt;
* Online Users Block: Limit the number of students displayed.&lt;br /&gt;
* Unicode Support: Typo3 Library updated to newest version.&lt;br /&gt;
* Course Categories: Fixed courses and subcategories in an invisible category being visible. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4074 Bug 4074]&lt;br /&gt;
* Wiki: Fixed a fatal error updating wiki pages.&lt;br /&gt;
* Added autocomplete=off in form tag to avoid browser autocomplete [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4423 bug:4423]&lt;br /&gt;
* Password change: Primary administrator password can only be changed by the administraror him/herself.&lt;br /&gt;
* Enrol/Authorize.net: Some changes:- allow_internal is not need anymore. Shows two option if enrolment key of course is set.- login_https is required for payment pages. My credit card is important. If you haven&#039;t a certificate forgot this module. (security)- Expiry date of credit card is more friendly :).&lt;br /&gt;
* User profile: Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4400 bug 4400]&lt;br /&gt;
* Removed old THEME variable.&lt;br /&gt;
* Added some more CSS hooks for the correctness feedback&lt;br /&gt;
* Fix [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4366 bug 4366]&lt;br /&gt;
* Makes autologinguest possible at site level&lt;br /&gt;
* Micro-increment version number to 2.0.10&lt;br /&gt;
* Corrected adjustment of relative URLs in &amp;lt;EMBED&amp;gt; tag&lt;br /&gt;
* Merging from HEAD:Fix for [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4371 bug 4371] (also SC#199):Now manually created users with admin privileges and force change passwordcannot change their username with impunity.&lt;br /&gt;
* Fix for [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4067 bug 4067] - allow user to update assignment when not yet marked&lt;br /&gt;
* Fix for [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4314 bug 4314]&lt;br /&gt;
* Fix for [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4206 bug 4206]&lt;br /&gt;
* Delayed merge from HEAD - If tablelib is going to do fullname voodoo, allow default sort field to be firstname/lastname&lt;br /&gt;
* Log actions must be strored to DB without &amp;amp;amp;print_log() takes care of it! [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=3853 Bug 3853]&lt;br /&gt;
* Fixes [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4354 bug 4354]&lt;br /&gt;
* shorten_text() AFTER format properly. See [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4355 bug  4355]&lt;br /&gt;
* Prevent a warning when params is empty. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4328 Bug 4328]&lt;br /&gt;
* Now the section &amp;quot;jumpto&amp;quot; menu (showed in collapse mode), supportsthe multilang filter. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4341 Bug 4341]&lt;br /&gt;
* Print performance info if exists and $CFG-&amp;gt;perfdebug is enabled.&lt;br /&gt;
* Fix for [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4351 bug 4351]. New parasmeter for get_record_sql to disableauto-added LIMIT (in case we are using our own)&lt;br /&gt;
* Solved bug found when trying to backup all users! http://moodle.org/mod/forum/discuss.php?d=27105&lt;br /&gt;
* Fixing [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4345 bug 4345]: merging problem when fixing [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4303 bug 4303]&lt;br /&gt;
* Mimic changes from &amp;quot;Ought to mention the improved assignment grading!&amp;quot;Merged from HEAD&lt;br /&gt;
* Ought to mention the improved assignment grading!&lt;br /&gt;
* Fixes [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4086 bug 4086] spelling mistake&lt;br /&gt;
* Commenting out gz_handler since it seem to cause problemsmore on http://moodle.org/mod/forum/discuss.php?d=34376&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Assignment&#039;&#039;&#039;&lt;br /&gt;
* Fixed bug in &amp;quot;Prevent late submissions&amp;quot;, thanks to Samuli, [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4780 bug 4780]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Enrolment&#039;&#039;&#039;&lt;br /&gt;
* Enrolment: Better explanation of flat file enrolment format. Re-formatted the imporved flat file enorlment description&lt;br /&gt;
* Auth/LDAP: Better support for ActiveDirectory&lt;br /&gt;
* Enrol/Authorize.net: PostgreSQL support and some indexes for speed.&lt;br /&gt;
* Authorize.net: Address Verification System (AVS) support added.&lt;br /&gt;
* Authorize.net: $CGF-&amp;gt;login_https must be ON for payment pages.&lt;br /&gt;
* Authorize.net: Shows two forms if the enrolment key of the course is set (internal and authorize forms).&lt;br /&gt;
* Authorize.net: IIS https fix. It doesn&#039;t recognize empty($_SERVER[&#039;HTTPS&#039;]) but accepts HTTPS=off.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Forum Module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Bug 4355. Solved one visualisation problem in the page showing the list of forums.&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4360 bug 4360]&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4431 bug 4431], affecting site course, added function forum_user_can_view_post in lib.php&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Glossary Module&#039;&#039;&#039;&lt;br /&gt;
* Bug 4543, 4713. Fixed some problems with entries and categories containing more than one word in their title.&lt;br /&gt;
* Bug 4858. Fixed one problem with formats, not being detected properly.&lt;br /&gt;
* Bug 4915. Entrylist format now displays the &amp;quot;Send Ratings&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hotpot Module&#039;&#039;&#039;&lt;br /&gt;
* Add support for HP5 quizzes (including JBC and old JQuiz)&lt;br /&gt;
* Removed weighting from questiontext in JCloze import&lt;br /&gt;
* Fixed import of JCloze into quiz module as a MULTIANSWER question&lt;br /&gt;
* Fixed bug in restoring attempts from backup&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lesson Module&lt;br /&gt;
* Lesson: $navigation and $grade_value were undefined when lesson was added to site main page&lt;br /&gt;
* Lesson: Lesson Essay Question Can&#039;t be Graded when attempt not finished. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4174 Bug 4174]&lt;br /&gt;
* Lesson: Added cancel button. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4216 Bug 4216] - cancel button&lt;br /&gt;
* Lesson: Fixed [http://moodle.org/mod/forum/discuss.php?d=37537 problem with storing the answerid for numerical questions].&lt;br /&gt;
* Lesson: Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=1187 bug 1187]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quiz Module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Fixed bug 4250: Added missing percentages to the grade selector&lt;br /&gt;
* Fixed bug 4495: Don&#039;t apply lateness check when teacher previews&lt;br /&gt;
* Fixed bug 4544: Incorrect path to exported files in some language packs&lt;br /&gt;
* Fixed bug 4780: Bug in &amp;quot;Prevent late submissions&amp;quot; setting fixed&lt;br /&gt;
* Fixed bug 5070: Students can&#039;t see quizzes when they are closed&lt;br /&gt;
* Turned off regrading of quizzes that have the attemptonlast option set&lt;br /&gt;
* A number of other minor interface fixes&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4319 bug 4319]. Thanks to Jaroslav&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4217 bug 4217]&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4829 bug 4829]&lt;br /&gt;
* Now we avoid checking for lateness when teacher previews. [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4495 Bug 4495]&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4688 bug 4688]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=39548 Rounding errors could lead to &amp;quot;Partially correct&amp;quot; for correct answers]&lt;br /&gt;
* Added missing percentages to the grade selector, [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4250 bug 4250]&lt;br /&gt;
* Avoid error messages in case $quiz-&amp;gt;sumgrades is zero, [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4454 bug 4454]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=27730#181773 get_actual_response() method for cloze question type] contributed by Jean-Michel&lt;br /&gt;
* Better PostgreSQL support&lt;br /&gt;
* Now With Nicer Presentation of Questions&lt;br /&gt;
* Summary text shouldn&#039;t be cleaned as only entered by teacher.&lt;br /&gt;
* Fixed [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4345 bug 4345]. Report performance improvements caused regression with MySQLv3&lt;br /&gt;
* Now we turn off browser-based autocomplete. Fixes [http://moodle.org/bugs/bug.php?op=show&amp;amp;bugid=4423 bug 4423] - Short Answer Quiz Q&#039;s Saving Form Entries&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resource Module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Solved one problem on restore that was causing some links to become corrupted.&lt;br /&gt;
* Slightly changes to the delete_instance() function in resources to allow future improvements.&lt;br /&gt;
* Resource restore: Solved bug when [http://moodle.org/mod/forum/discuss.php?d=38801 decoding encoded links for resource]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wiki Module&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Solved one problem sending double-slashed info to DB.&lt;br /&gt;
* Bug 3830. Load of initial content from course file area is now allowed.&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.5.3==&lt;br /&gt;
&lt;br /&gt;
11th November, 2005&lt;br /&gt;
&lt;br /&gt;
(Because this release contains important security fixes, we highly advise that sites using any previous version of Moodle upgrade to this version as soon as possible.)&lt;br /&gt;
&lt;br /&gt;
===A few new things===&lt;br /&gt;
&lt;br /&gt;
* We now have SCORM 1.3 (SCORM 2004) support!&lt;br /&gt;
* Much improved Assignment grading interface, including &amp;quot;quick grading&amp;quot; options&lt;br /&gt;
* A new Single-Sign-On API is available&lt;br /&gt;
&lt;br /&gt;
===Various fixes===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;General&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Contains warnings when Moodle is used on an PHP configuration known to be insecure&lt;br /&gt;
* Contains fixes for some recently reported security problems (see [http://security.moodle.org/ security.moodle.org])&lt;br /&gt;
* Backups now runs a lot faster medium/large installs. Many issues fixed in this area&lt;br /&gt;
* Listing of directory sizes can be made much faster on Linux/Unix servers, thanks to a performance fix you can enable from Admin-&amp;gt;Variables: &amp;quot;path_to_du&amp;quot;&lt;br /&gt;
* We now log more meaningful IP addresses when the server or the clients are working behind a proxy&lt;br /&gt;
* Fixed some issues with PHP accelerators&lt;br /&gt;
* Upgrade scripts have been refined and work much better for PostgreSQL installations&lt;br /&gt;
* General PostgreSQL port code cleanup&lt;br /&gt;
* Upgrading to 1.5.3 will fix any legacy Journal to Online Assignment upgrade issues&lt;br /&gt;
* RSS libraries now support RSS 2.0 categories, see bug 3654&lt;br /&gt;
* Better accesibilty in file uploads, see bug 3662&lt;br /&gt;
* Better support for site-wide HTTPS, see bug 3848&lt;br /&gt;
* We now send away bots (like Googlebot) from that try mangled URLs, see bug 3958&lt;br /&gt;
* Better DST support for non-logged-in users&lt;br /&gt;
* Better DST support for repeat events in Calendar&lt;br /&gt;
* Small fixes to the lesson, choice and grade modules&lt;br /&gt;
* Minor CSS improvements to formal_white and orangewhite themes&lt;br /&gt;
* Better pagination in course listing and loglive pages&lt;br /&gt;
* Fixed an IE-only bug related to HTMLArea content where user-edited tables could float and hide part of the UI.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Authentication&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Fixes to change password/forgotten password with external auth&lt;br /&gt;
* Data fetched from external DB or LDAP is now truncated correctly&lt;br /&gt;
* Fixed bug 4305 -- better login block behaviour when using secureforms&lt;br /&gt;
* Better support for utf-8 user data from external auth&lt;br /&gt;
* LDAP: General fixes covering sync_users script and logging of errors&lt;br /&gt;
* LDAP: Fixed bug 3141 - Can&#039;t update external data with LDAP authentication&lt;br /&gt;
* LDAP: Fixed bug 3992 - LDAP password including a quote does not work - credits go to Kita&lt;br /&gt;
* LDAP: Better support for ActiveDirectory.&lt;br /&gt;
* LDAP: Fixed bug #3594&lt;br /&gt;
* LDAP: Better handling of multi-source field mapping&lt;br /&gt;
* LDAP: Fix for using DN as idnumber - thanks fo Jeff Graham - http://moodle.org/mod/forum/discuss.php?d=28840&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Enrolment and metacourses&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Metacourses: Prevent normal users to gain access to meta courses via manual enrolment&lt;br /&gt;
* Metacourses: better support for MySQL v3.23.x&lt;br /&gt;
* DB: Enrolment lookups now work reliably with Moodle on MySQL and Postgres&lt;br /&gt;
* DB: Non-MySQL databases work again as external enrolment databases&lt;br /&gt;
* LDAP: Fixed a wrong call to add_teacher in LDAP plugin.&lt;br /&gt;
* LDAP: Servers being down or unavailable no longer prevent logins&lt;br /&gt;
* LDAP: Course auto-creation works again&lt;br /&gt;
* LDAP: Fixed several bugs reported by Jeff Graham and Barron Koralesky -- including bugs 3912 and 3974&lt;br /&gt;
* LDAP: We can now bind non-anonymously to LDAP&lt;br /&gt;
* Authorize.net: several fixes&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Resources&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Bugfix: Avoid linking to empty or unlinkable activity names&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Forums&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Big and small optimizations to tracking of read/unread messages, specially for PostgreSQL&lt;br /&gt;
* Fixed some PostgreSQL bugs&lt;br /&gt;
* Some more actions are now supported by backup/restore when processing log records, see bug 3582&lt;br /&gt;
* Now message forum RSS feeds are including category data -- useful under some RSS agregators able to group messages, see bug 3654&lt;br /&gt;
* Fixed paging on forum search&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Blocks&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Several performance improvements&lt;br /&gt;
* Fixes to the upgrade process, including PostgreSQL syntax and lower memory usage&lt;br /&gt;
* Brought in several bugfixes from 1.6dev&lt;br /&gt;
* Fixed bug 3478: Cannot add RSS feed as course creator&lt;br /&gt;
* Fixed bug 3793: Prevent warning message when configuring a glossary_random block in a course which has no glossaries&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quiz&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Some CSS style fixes&lt;br /&gt;
* Better compatibility with themes that contain forms in the headers&lt;br /&gt;
* Highlighting of correct answers can now be turned off&lt;br /&gt;
* Fixed bug 3986: Too many random questions. (mindforge)&lt;br /&gt;
* Fixed missing action icons&lt;br /&gt;
* Fixed bug 3899 and removed some &#039;missing course object&#039; messages&lt;br /&gt;
* Fixed bug 3950: Ee-attempt button inconsistency for multi-attempt quizzes&lt;br /&gt;
* Fixed bug 3953: Quiz/report.php pagesize can be set to 0, credits to Jean-Michel&lt;br /&gt;
* Fixed potential data data corruption bug 3915&lt;br /&gt;
* Fixed bug 3884: Quiz correct highlights missing for 2 of 3 options.&lt;br /&gt;
* Fix for the Student review highlight doesn&#039;t seem to work bug&lt;br /&gt;
* Fixed bug 3804: Differences in question types between 1.5 and 1.6&lt;br /&gt;
* Fixed bug 3822: don&#039;t count previews as attempts&lt;br /&gt;
* Fixed bug 3807: Question numbering issue&lt;br /&gt;
* Fixes for the item analysis plug-in, assembled by Jean-Michel&lt;br /&gt;
* Now we reset the timeout counter to avoid timeouts&lt;br /&gt;
* Several improvements contributed by Jean-Michel Vedrine. You can now change the number of attempts per page displayed on screen, and download results to Excel/text file, including detailed grades&lt;br /&gt;
* Fixed export bug with non-English languages&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SCORM&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* We now support SCORM 1.3 (SCORM 2004)!&lt;br /&gt;
* Fixed a bug with next and prev SCO search&lt;br /&gt;
* Fixed bugs related to masteryscore&lt;br /&gt;
* Fixed a problem in AICC course tracking&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wiki&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Now paging of older versions is showed and working properly, see bug 3750&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Mediaplugin filter now finds multi-line links in HTML code&lt;br /&gt;
* Censor filter: Added original word as title to the blacked-out version. The filter can obscure actual important words by mistake (eg Dickens) and there needs to be some way to recover the meaning&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.5.2==&lt;br /&gt;
&lt;br /&gt;
16th July, 2005&lt;br /&gt;
&lt;br /&gt;
=== Various fixes ===&lt;br /&gt;
&lt;br /&gt;
*  Journal -&amp;gt; Assignment upgrade now works properly :-/&lt;br /&gt;
* Assignment submodules now upgrade as expected&lt;br /&gt;
* Various other bugs with new Assignments fixed&lt;br /&gt;
* Journal module is now disabled by default on new installations&lt;br /&gt;
* Login page is now 100% HTTPS if required&lt;br /&gt;
* Various small standard theme tweaks&lt;br /&gt;
* Fix for recent matching questions display bug in Quiz&lt;br /&gt;
* Language editor no longer creates empty files when not necessary (caused country list bug)&lt;br /&gt;
* Fixed some manifest parsing problems in SCORM module&lt;br /&gt;
* Multilang filter now deals with pack names that contain numbers&lt;br /&gt;
* Files are now force-downloaded (fixes IE problems and some security issues)&lt;br /&gt;
* Relinking debugging output is escaped&lt;br /&gt;
* Large MP3 player now displays ID3 tags properly again&lt;br /&gt;
* Some chat daemon improvements&lt;br /&gt;
&lt;br /&gt;
=== Some new things ===&lt;br /&gt;
&lt;br /&gt;
* Orangewhite theme optimised for use on PDA&lt;br /&gt;
* Forum user posts page can be called without userid&lt;br /&gt;
* Altavista BabelFish now allowed in as guest when Google is&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.5.1==&lt;br /&gt;
&lt;br /&gt;
8th July, 2005&lt;br /&gt;
&lt;br /&gt;
===Various fixes===&lt;br /&gt;
&lt;br /&gt;
* Several potential security problems solved&lt;br /&gt;
* Allowobjectembed setting now works correctly&lt;br /&gt;
* Speed problem on IE, caused by tab hover fixed.&lt;br /&gt;
* Cut and paste in editor on Firefox has a more helpful warning message&lt;br /&gt;
* Fixed a session problem when logged on as admin during upgrade from very old Moodle version&lt;br /&gt;
* Fixed editing problem in Main menu of site&lt;br /&gt;
* Minor CSS display problems in a few areas were fixed&lt;br /&gt;
* Fixed the adding of a single discussion forum&lt;br /&gt;
* Fixed Lesson problems with calculating grades, and dates&lt;br /&gt;
* Fixed Lesson problems with entering a cluster after a page&lt;br /&gt;
* Censor filter was fixed to make it work better with old themes&lt;br /&gt;
&lt;br /&gt;
===Some new things===&lt;br /&gt;
&lt;br /&gt;
* New theme: Wood&lt;br /&gt;
* Metal theme updated for 1.5&lt;br /&gt;
* Many language updates for most languages, including a new language: Khmer&lt;br /&gt;
* Block classes can now run custom code when an instance is created/deleted (this is useful for blocks that need to set up non-trivial data structures)&lt;br /&gt;
* Wizard for Calculated Questions in Quiz was rewritten&lt;br /&gt;
* Backup/Restore module selection is now improved and much easier&lt;br /&gt;
* Backup/Restore module has much improved relinking support, it&#039;s now faster and easier to implement in new modules&lt;br /&gt;
&lt;br /&gt;
==Moodle 1.5==&lt;br /&gt;
&lt;br /&gt;
5th June, 2005&lt;br /&gt;
&lt;br /&gt;
Here you can find the release notes of the current stable version of Moodle. &#039;&#039;&#039;If you experience any bugs in this release, please report them at [http://moodle.org/bugs moodle.org/bugs] so we can fix them in the next release.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Headline features ===&lt;br /&gt;
&lt;br /&gt;
* Web pages are compliant with XHTML Transitional 1.0&lt;br /&gt;
* Improved &#039;&#039;&#039;Accessibility&#039;&#039;&#039;, aiming for compliance with WAI (W3C), SENDA (UK) and Section 508 (US) criteria.&lt;br /&gt;
* Very strong &#039;&#039;&#039;new Themes system&#039;&#039;&#039;, allowing cascading themes, user themes, course themes, with very fine control of every page in Moodle via CSS.&lt;br /&gt;
* Integrated &#039;&#039;&#039;Messaging&#039;&#039;&#039; feature for direct communication between all users in the site, featuring realtime popup windows, notification, email copies, blocking, history, WYSIWYG editor, etc&lt;br /&gt;
* Forum read/unread tracking with highlights allows you to see new postings at a glance and to control how these are displayed (per forum, per user or per site).&lt;br /&gt;
* New &#039;&#039;&#039;Blocks&#039;&#039;&#039; system, allowing multiple copies of blocks and better block configuration&lt;br /&gt;
* Full support for &#039;&#039;&#039;Daylight Savings Time&#039;&#039;&#039; in every locality around the globe, so everyone always see the correct local time for all events.&lt;br /&gt;
* New &#039;&#039;&#039;extended gradebook&#039;&#039;&#039; allowing custom weighting of different activities, setting extra grades (or taking out others) and improved display and sorting options&lt;br /&gt;
* Users can be required to agree to a &#039;&#039;&#039;Site Policy&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Other major system-wide improvements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Admin&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* New &amp;quot;maintenance mode&amp;quot; allows the admin to temporarily disable a site (during upgrades, for example).&lt;br /&gt;
* Moodle can automatically download a new list of timezones from moodle.org or elsewhere and install it to the database (Olson files are supported too)&lt;br /&gt;
* New version of Moodle MySQL Admin module (available separately)&lt;br /&gt;
* New calendar options page provides user interface to configure the behavior of the calendar&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Authentication&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* New Shibboleth Support&lt;br /&gt;
* New CAS Support&lt;br /&gt;
* New PAM Support&lt;br /&gt;
* Improved LDAP integration, so that LDAP can now control course creation, group assignments. Increased performance and scalability performing user synchronisation.&lt;br /&gt;
* Certain user fields can be locked by the admin when using external authentication&lt;br /&gt;
* Improved session handling now detects &amp;quot;crossover&amp;quot; sessions that we have found in some buggy PHP installations and prevents them&lt;br /&gt;
* Sessions can now be stored in the database (good for clustered installations!)&lt;br /&gt;
* Users can be forced to change their password&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Files&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Standardised file browsing in all areas&lt;br /&gt;
* Improved uploading, with support for automated Virus scanning of new documents using ClamAV.&lt;br /&gt;
* Slasharguments now work also on IIS (upgrade to PHP 4.3.11 needed for ISAPI)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Filters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Standardised filter library makes it trivial to write new filters that require searching and highlighting of text.&lt;br /&gt;
* Huge efficiency improvements for complex filters like the Glossary filter&lt;br /&gt;
* New Tidy filter uses the W3C Tidy program to (optionally) clean all user-entered texts throughout the site and convert it to valid XHTML code&lt;br /&gt;
* Improved censorship filter, now &amp;quot;blacks out&amp;quot; words using styles and uses a word list from the language packs.&lt;br /&gt;
* Improved Flash MP3 player, now shows progress bar while downloading and playing&lt;br /&gt;
* Improved Multi-language filter is faster, more forgiving of syntax errors, and uses new editor-friendly syntax: &amp;lt;span lang=&amp;quot;en&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
* Auto-linking filters (glossary, activities) can work to link all the occurrences (old behaviour), once for each text block or only once for the whole page ($CFG-&amp;gt;filtermatchonepertext, $CFG-&amp;gt;filtermatchoneperpage).&lt;br /&gt;
* More text can now be filtered in Moodle, including activity names, headings and other such small texts. This makes it possible to design completely multi-lingual sites in Moodle that fully appears in the user&#039;s chosen language.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Themes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Modules can provide standard styles&lt;br /&gt;
* Themes can override required styles of other themes&lt;br /&gt;
* Users and courses can choose their own themes if the admin allows it&lt;br /&gt;
* Implementation of tabs interface on many pages&lt;br /&gt;
* Modules, Blocks and Languages can define their own standard styles&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;HTML Editor&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The toolbuttons offered in the editor toolbar are now configurable by the admin&lt;br /&gt;
* Search and Replace text within the editor text area (with optional use of regular expressions)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Course management&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Transparent Blackboard 5.5 course importing (partial 6.0 support)&lt;br /&gt;
* The new meta-courses allow to get users automatically enroled in a general course (the metacourse) when enroled in any of the metacourse-linked courses&lt;br /&gt;
* New tool to copy content from a course to other.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;New blocks&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* HTML block: allowing to place arbitrary content (text, images links) in any course mainpage&lt;br /&gt;
* Remote RSS feed: allows to display external news channels inside a Moodle course&lt;br /&gt;
* Glossary Selection: to choose and display content from a Moodle glossary in course mainpage&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Calendar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Major speed improvements for sites with a large number of courses using groups&lt;br /&gt;
* Repeating events can now be modified or deleted all at the same time or separately as before&lt;br /&gt;
* New &amp;quot;remember filter settings&amp;quot; preference that allows calendar filters to remember their status between logins&lt;br /&gt;
&lt;br /&gt;
=== Activity module improvements ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Assignment&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Completely refactored into a new class-based design, allowing new plugin-assignment types&lt;br /&gt;
* New Online Text assignment type that doesn&#039;t require files and allows inline comments when grading - this new type effectively replaces the old Journal module&lt;br /&gt;
* Vastly improved grading interface for handling large classes&lt;br /&gt;
* New configuration options to disable late submission and to e-mail alerts to teachers when students submit new work&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Chat&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Streamlined interface looks smoother, works faster, even without using the optional server daemon&lt;br /&gt;
* Blocks can now be added to chat pages (e.g. for additional information)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Choice&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Rewritten to allow any number of choices&lt;br /&gt;
* The number of users per choice can be limited, which allows it to be used as tool for &amp;quot;signing up&amp;quot; to an array of options.&lt;br /&gt;
* You can now download the results of the choice to XLS or a TXT file&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Forum&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Powerful new Google-like forum searching tools&lt;br /&gt;
* Forum read/unread tracking - unread messages are highlighted on the course page, forum page, discussion listing and the discussion view&lt;br /&gt;
* The tracking system may be disabled by teachers/users&lt;br /&gt;
* User profiles show all posts by a user, as well as all discussions&lt;br /&gt;
* When admins edit user messages, a notice is attached&lt;br /&gt;
* Discussion listing shows the last user who posted to each discussion and when it was, with a direct link to that post&lt;br /&gt;
* In group-enabled forums the discussion listing shows the group the thread applies to, with a link to the group description page.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Glossary&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* New setting to enable/disable the print view of each glossary.&lt;br /&gt;
* New search system looks for words everywhere (instead of doing exact phrase match).&lt;br /&gt;
* More information is sent to logs to be able to track activity better.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Journal&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The Journal module has not changed since 1.4, and is now deprecated. The upgrade procedure will convert all your Journal activities into Online Assignments, and hide all the old Journal activities. If you don&#039;t want this to happen, then define this in your config.php: $CFG-&amp;gt;noconvertjournals = true;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Lesson&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Now supports timed Lessons&lt;br /&gt;
* Can create practice Lessons (grades are not stored)&lt;br /&gt;
* Option for students to view points earned while taking the Lesson&lt;br /&gt;
* Allow students to review their answers before submitting the Lesson&lt;br /&gt;
* New Slide Show Mode (only branch tables are displayed as slides)&lt;br /&gt;
* New Left Menu (for enabled branch tables only)&lt;br /&gt;
* Lessons can now be Password Protected&lt;br /&gt;
* A Tree View can be used for the Lesson creation screen&lt;br /&gt;
* Students can post their high scores&lt;br /&gt;
* New option to save a Lesson&#039;s settings as defaults for new lessons in the same course&lt;br /&gt;
* Can delete a student&#039;s attempts&lt;br /&gt;
* New page Jumps:&lt;br /&gt;
** Previous Page&lt;br /&gt;
** Unseen question within a branch&lt;br /&gt;
** Random question within a branch&lt;br /&gt;
** Unseen question within a cluster&lt;br /&gt;
* Added functionality to view Lesson statistics&lt;br /&gt;
* New question type: Essay. Teachers can view each essay and write comments, assign a grade, and then email it all to the student&lt;br /&gt;
* New question creation interface&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Quiz&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Can handle adaptive questions, i.e., questions that allow the student to interact with them repeatedly within the same quiz attempt and that can change in response to student answers.&lt;br /&gt;
* Student can be allowed to try a question again immediately within the same quiz attempt until they get the answer right.&lt;br /&gt;
* There is a penalty mechanism that deducts a specified fraction of the mark for each wrong attempt at a question.&lt;br /&gt;
* Allows questions rendered and scored externally (e.g., by mathematical assessment engines) to be integrated seamlessly into Moodle quizzes via the RQP web services protocol.&lt;br /&gt;
* Is prepared for the handling of IMS QTI questions once web services for these become available.&lt;br /&gt;
* New tabbed teacher interface for previewing, editing, and reviewing quizzes.&lt;br /&gt;
* New &amp;quot;improved security&amp;quot; mode shows quiz in a separate full-screen window, with many browser features disabled&lt;br /&gt;
* Quizzes can be presented to students in several pages. The number of questions per page is selectable by the teacher.&lt;br /&gt;
* Blocks can now be added to quiz pages (to show results table, or additional information etc)&lt;br /&gt;
* Better and cleaner interface for question selection and management in the database. Selected questions can be added to quiz, moved to other categories or deleted en mass.&lt;br /&gt;
* Random questions are now added to the quiz question list with a dedicated button, leaving a cleaner interface at questions database without phantom placeholders&lt;br /&gt;
* Final grade can be a fractional number, with teacher-defined decimal figures&lt;br /&gt;
* Improved results page with user-selectable display of columns, cleaner sorting and new mark display options&lt;br /&gt;
* Questions can be edited with one click from the improved quiz preview and question preview screens.&lt;br /&gt;
* Questions can be copied with one click, to allow question variations to be created with ease.&lt;br /&gt;
* Revamped question categories structures and editing interface.&lt;br /&gt;
* Categories now can contain nested subcategories and can be re-ordered.&lt;br /&gt;
* It is possible to select whether questions from categories, and or their subcategories are displayed on the question edit page.&lt;br /&gt;
* It is now possible to select whether to add random questions from a parent category alone, or from a parent category and its sub-categories.&lt;br /&gt;
* Quiz creators are prevented from changing the question set of quizes that have had student responses.&lt;br /&gt;
* Recognition, and rejection, of overlapping/redundant questions has been improved.&lt;br /&gt;
* The display of questions in longer quiz categories on the quiz editing page is now paginated.&lt;br /&gt;
* New export types - IMS QTI (2.0) and xhtml. Improvements &amp;amp; fixes to others.&lt;br /&gt;
* New import type - Hot Potato. Improvements &amp;amp; fixes to others.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Scorm&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The module is now fully conformant with the SCORM 1.2 standard.&lt;br /&gt;
* User result data storage and reporting was improved.&lt;br /&gt;
* AICC packages can now be imported.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Survey&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Graph formatting has been improved (labels are more readable)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wiki&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Changes to wiki pages are now monitored and displayed in Recent Activity block&lt;br /&gt;
* Several under the hood improvements to backup/restore and other routines that enhance the reliability of wikis&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
*[[Old releases|1.4.5 release notes]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Core]]&lt;br /&gt;
[[Category:Administrator]]&lt;br /&gt;
&lt;br /&gt;
[[pt:Versões do Moodle]]&lt;br /&gt;
[[es:Notas de versiones]]&lt;br /&gt;
[[fr:Notes de mise à jour]]&lt;/div&gt;</summary>
		<author><name>Bushido</name></author>
	</entry>
</feed>