question type plug in template, thoughts

question type plug in template, thoughts

by Jamie Pratt -
Number of replies: 14

I liked very much the idea of having a tool to automate some programming tasks as Thomasz took the initiative to create. And spurred by this and his automation of creating blocks and module from templates, I had a think about what might be useful for someone getting started on a new question plug in. I thought I would post my thoughts here.

I am developing another new question type the 'combined' question type and I thought the code I started with might be a good model as an up to date question type plug in template. See the commit on my gitub account here.

It is a copy of the shortanswer question type with everything unnecessary removed and :

  • countback grading
  • hints
  • question text
  • no grading implemented at all
  • no input controls at all in question as yet
  • it doesn't install any new tables

Import / export are not implemented.

Backup and restore are not implemented.

But it is an alternative start for devloping a question type plug in and is working code as is. Although it doesn't do any actual grading or collect student input at all.

Depending on what type of question plug in you want to develope it might be good to either :

  • use one of the existing question types that is doing something similar to what you want to do as a base, copy that, have fun deleting no longer needed code and you then have a template to start from.
  • or if possible to avoid code duplication it is better to extend existing classes, particularly for the question type and question classes. There are quite a few examples of queston types that do this at https://github.com/moodleou/.
    • for example classes in ddimageortext and ddmarker both inherit from common code in ddimageortext and those inherit code from the gapselect question type
  • or the above code might be useful

It would seem to me that the existing plug ins and contributed plug ins are already templates and benefit from the fact that they are going to be updated regularly and that even in the most basic question type template you have already had to make quite a few design decisions.

I guess it might be possible to start a github repo with a template with the aim eventually of having one with branches for each design decision eg. for the type of grading strategy used, whether to support hints etc.

We do have some existing question type template code in the cvs contrib but it seems it hasn't been worked on in over 5 years. It might be better to let that code rest and start afresh.

Average of ratings: Useful (1)
In reply to Jamie Pratt

Re: question type plug in template, thoughts

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I am really glad you have been thinking about this Jamie. It would be really good to have a new question type template. (Also, updated docs at http://docs.moodle.org/dev/Question_types )

You are right that the old template in CVS is now worthless. The sort-of template you did from combined looks about right. I think you should add stubs for Moodle XML import/export and backup restore.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: question type plug in template, thoughts

by Jamie Pratt -

I updated the question type developement docs page. I think I found all the out of date bits and I added a few things I thought might be helpful.

I will add more when I get a chance and will make a new github repository with a question type plug in template based on the code I previously linked to.

In reply to Jamie Pratt

Re: question type plug in template, thoughts

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

This seems an excellent idea. I have been working on exactly the same thing. I started with Tims 1.9 template and then did a combination of lifting out bits of my gapfill question and doing a count of occurances of the methods in existing question types.

It seems very likely that most new question types are going to have additional fields so my approach was to start with 

class qtype_QTYPENAME extends question_type {
public function extra_question_fields() {
return array('question_QTYPENAME', 'additionalfield');
}

And to include import/export for at least xml with code as follows...

public function export_to_xml($question, qformat_xml $format, $extra = null) {
$output = parent::export_to_xml($question, $format);
$output .= ' <extraquestionfieldname>' . $question->options->extraquestionfieldname .
"</extraquestionfieldname>\n";

$output .= $format->write_combined_feedback($question->options, $question->id, $question->contextid);
return $output;
}
public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { if (!isset($data['@']['type']) || $data['@']['type'] != 'QTYPENAME') { return false; } $question = parent::import_from_xml($data, $question, $format, null); $format->import_combined_feedback($question, $data, true); $format->import_hints($question, $data, true, false, $format->get_format($question->questiontextformat)); return $question; }
In reply to Marcus Green

Re: question type plug in template, thoughts

by Jamie Pratt -

I think it would be cool to have different branches with different features. We could have on one branch a template which does not need any extra db tables at all. Then on another branch we introduce an example with extra db tables, including the form fields, question type hooks, import and export and back up and restore. We can link to the diff of the two branches to show the potential developer what is involved in adding extra db tables.

I need to add the functions for import and export and backup and restore to the existing template branch.

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: question type plug in template, thoughts

by Jamie Pratt -

I went ahead and created a github repo with the simple question type template I described above. See https://github.com/jamiepratt/moodle-qtype_TEMPLATE

 

Please see the README on the front page of the repo for more info.

I can maintain the repo, at least for now. And I will try to add to it over time.

I would prefer if we used the issues tracker in github to track bugs. Please feel free to fork the repository and I look forward to getting lots of pull requests with bug fixes and additions to the template.

Average of ratings: Useful (1)
In reply to Jamie Pratt

Re: question type plug in template, thoughts

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

I have just looked at your repository Jamie, nice work. When I was first working with the question code I was confused as to what was the main purpose of the question and questiontype files were and when I came up with a brief description that I thought would be good to include as comments. They were

Questiontype.php
This file contains the static form of the question that reads and writes from 
the database. This is where you account for any new options fields and
customise the import and export code.
Question.php
This is the code for when the question is live, i.e. being answered by a 
student or being graded. It is the backend code that supplies functionality
for the renderer code.


Anyway, let me know if my understanding of the general purpose of these files is incorrect.

 

Average of ratings: Useful (1)
In reply to Marcus Green

Re: question type plug in template, thoughts

by Jamie Pratt -

While I was looking around to see what had been said about question type plug in templates in the past and what was available I came across this post from Tim that does a pretty good job of explaining the difference :

 

https://moodle.org/mod/forum/discuss.php?d=188823#p835598

We could use that as a basis for an addition to the docs page on developing a plug in.

In reply to Jamie Pratt

Re: question type plug in template, thoughts

by Jamie Pratt -

I added the excellent answer from Tim explaining the difference between question type and question definition to the docs page with some minor editing. I hope Tim does not mind! I think the question type plugin developement how to page is now looking a lot better, although it could do with a more thorough rework and some additions still. But soon I hope we can take off the ugly yellow work in progress notice at the top of the page. smile

 

Here is what I just added from Tim's old post :

Question type and question definition classes

[edit] The question definition class is in question.php

This holds the definition of a particular question of this type. For example, an object of type qtype_shortanswer_question is a short-answer question instance. If you load three short-answer questions from the question bank, then you will get three instances of that class. This class is not just the question definition, it can also track the current state of a question as a student attempts it. For example, for a multiple-choice question, the class will store what order the choices have been randomly shuffled into for that student. To put it another way, the question_definition often works with a particular question_attempt.

 

[edit] The question type class is in questiontype.php

In contrast, the question type class represents the question type. For example, the qtype_shortanswer class represents the 'short answer' type of question, and there will normally only be a single instance of this class. It has several responsiblities, including providing meta-data about this question type (e.g. public function name()). It knows how to load, save and delete questions of this type to and from the database (get_question_options and save_question_options, delete_question) and hence how to construct instances of the qtype_shortanswer_question class. It provides methods to help with editing questions of this type. It can also provide the implmentation for import and export in various formats.

In reply to Tim Hunt

Re: question type plug in template, thoughts

by Marcus Green -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers

It would also be good to have a js directory and a test folder, with at least stub code...

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: question type plug in template, thoughts

by Jamie Pratt -

I have done some more work cleaning up and adding to http://docs.moodle.org/dev/Question_types

Have removed the 'work in progress' notice as I think the doc is fairly complete now. Although further additions and revisions would certainly improve it further.

In reply to Jamie Pratt

Re: question type plug in template, thoughts

by Jean-Michel Védrine -

Hello Jamie,

Thanks a lot for contributing to this template and documentation.

There is something to add for absent minded developers like me (if I can be called a developer ?) : the fact that now questions definitions are cached. This can lead to surprising effects if you modify them without purging the cache.

Guess how I know it ... Please don't laugh wink

In reply to Jean-Michel Védrine

Re: question type plug in template, thoughts

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

You are definitely a developer Jean-Michel.

Don't feel bad about that caching mistake. I made exactly the same mistake with STACK. It would be worth adding a warning to the docs. The correct way to un-cache a question when your code alters it is to call question_bank::notify_question_edited($questionid)

Average of ratings: Useful (1)
In reply to Jamie Pratt

Re: question type plug in template, thoughts

by Jean-Michel Védrine -

There is something else to add to documentation for author upgrading a pre-question engine 2 question type : how to write the code in db/upgradelib.php to upgrade legacy attempts.

If I find some time I will try to write something. The master key is to use Tim's advice to adopt a test driven approach extracting data from old attempts using the queupgradehelper tool then writing phpunit tests at the same time you build the upgrade code.

Unless your question is quite similar to an existing one (in that case you can just adapt the existing code) I don't think another method can be easily used.