All of the proposed changes are meant to be done in a general fashion to allow backwards compatibility and for extension by formats and activities.
Please note that this proposal is not designed to solve all format issues, but rather a single step of many in the right direction.
Let me know what you think about the changes and the possibility of including them into the core Moodle code.
Cheers,
Mark
PS: I tried to attach a PDF version of the proposal, but it is 176KB and the max upload size is 100KB.
Start of the proposal:
Currently, all course formats are limited to a single set of left and right column blocks. The goal of the below changes is to allow formats to define their own columns and to create multiple set of blocks. To do this, the core code needs to be as flexible as the current block API and the backup code needs to allow the backup and restore of multiple sets of blocks.
Code Changes
All of the following proposed code changes are not specific to the Page Format, but instead are generalizations of the code so it can be more easily extended by the course formats.
Remove any hard coded references to block positions
In library code, remove directly referenced left and right block positions. This prevents formats from creating new columns for blocks. At first look, this appears to be resolved in the Moodle 1.9 code base.
Allow formats to declare their own pagelib.php
This will allow formats to extend the base course page definition and give them more control over layout and presentation. To make this possible, the following areas would need to be modified: /course/view.php, backup routine and areas that directly reference the course-view page type. This change only seems natural since modules can already define their own pagelib.php to extend the base activity page definition.
Allow formats to backup their blocks
The current routine for backing up blocks is to backup all blocks that relate directly to the course. However, if we have multiple sets of blocks, meaning the pageid field is not set to the course ID, then those blocks are not backed up. During the backup routine, a page object method could be called that returns all blocks that should be backed up. The following would be added to the page_base class definition in lib/pagelib.php:
/** * Gets all of the blocks that should be backed up * during the backup routine. * * @param object $preferences Backup preferences * @return array **/ function blocks_get_backup_set($preferences) { return blocks_get_by_page($this); }
The above method would ensure backwards compatibility with current course-view page types and activity page types.
Since the pageid is not necessarily the course ID, then the pageid needs to be remapped during restore. Currently, the pageid is remapped somewhat manually during restore. Instead, let's define a method in the page class definition to remap the pageid field. The following method would be added to the page_course class definition in lib/pagelib.php:
/** * Remap the block_instance table's pageid field. Return * false on failure. * * @param int $pageid The current value for pageid that needs to be remapped * @param object $restore Restore object * @return mixed **/ function restore_pageid($pageid, $restore) { return $restore->course_id; }
And then for activities, the following would be added to page_generic_activity class definition in lib/pagelib.php:
/** * Remap the block_instance table's pageid field. Return * false on failure. * * @param int $pageid The current value for pageid that needs to be remapped * @param object $restore Restore object * @return mixed **/ function restore_pageid($pageid, $restore) { if ($restore->mods[$this->activityname]->restore) { $getid = backup_getid($restore->backup_unique_code, $this->activityname, $pageid); if (!empty($getid->new_id)) { return $getid->new_id; } } return false; }
The above methods would ensure the backwards compatibility with current activity and course page definitions.
The last change to the restore routine is that blocks should be restored after any other plugin that could potentially add them. In backup/restorelib.php, the block restore code needs to be moved down after the format restore code in the method restore_execute().
Remove reference to $this->instance->pageid
Right now, a majority of blocks reference $this->instance->pageid as the course ID. This means that those blocks can only be added to a page that belongs directly to the course. This is not ideal as it makes blocks less usable since they are programmatically restricted to be related to a course instead of logically restricted based on context by using the block method applicable_formats(). To get around this, blocks could instead use the global $COURSE to get the current course ID.
For backwards compatibility, formats that have multiple pages might be able to use a different page type from course-view so that older blocks that expect the $this->instance->pageid to be the course ID are not added. It would be best though to update all of the blocks to use the global $COURSE when possible.
Finally, the block development guide should be updated so that future blocks use $this->instance->pageid appropriatley. In particular, the following section:
End result
In the end, formats will be able to define multiple pages that relate to a single course and each page could have its own set of blocks. Also, formats could extend the default course page definition to customize layout and design. These code changes would not only benefit formats, but also modules. For example, the lesson module could have a page of blocks that relate to an actual lesson page. This would allow lesson builders to define sets of blocks for each lesson page that may accompany the question content.