Snapshot - flat HTML export of complete course

From MoodleDocs
Warning: This page is no longer in use. The information contained on the page should NOT be seen as relevant or reliable.


If you want to retain a completed Moodle course for future reference the only way, currently, to keep it visible is to leave it in place on a Moodle site. If the institution has a policy of having course material available to students for a number of years (as is often the case) this can effectively multiply the number of Moodle courses by a factor of as much as five or six. As Moodle has no concept of versions of a course this, at best, adds to the clutter and confusion for students. At worst it may impose a serious performance and resources problem for the site.

There is really no requirement for these courses to remain active in the sense that interactive portions of the course still operate. In fact it is actually a benefit that the interactive activities in archived courses are *not* operational (ie, are read only).

This proposal, therefore, is to explore a system for generating "flat" HTML files of a course at a particular point in time. This could typically be at the end of a course when the active Moodle course is removed but the snapshot will remain available in an archive area. There are other benefits; the code to generate HTML representations of each activity is likely to have other applications, e.g., material for ePortfolio inclusion. Indeed, it would be relatively straightforward to include on the bottom of each activity page a "Portfolio this" button (although I'm sure there's a better name out there)

Technical Overview

The basic idea is that the user will click the Snapshot button (probably) in the Course Administration menu and this will generate a zip file containing a set of HTML pages and files. The representation of the course page will be the index.html file. Each resource or activity will have its own HTML page (or pages where required). The course files will be copied into the zip file as required.

The intention is that the output HTML will be fairly lightweight (in comparison to the normal screen output), have abundant CSS identifiers and be styled by an included CSS page. It is not currently envisioned that additional features like blocks be included although some provision could be added to the API for blocks that wish to participate.

In organisational terms the main script will probably live in the course subdirectory accepting the course id as its input parameter. This script will be responsible for handling the enclosing zip file and generating the course page contents. Every module will have an optional method added to its library to handle this functionality. This function will generate the HTML snapshot for a particular instance of the module. If the module does not participate (i.e., does not implement the function) its entry in the course page will not be a clickable link and its contents will not be included.

Detailed Implementation

very much work in progress

This section describes the proposal in more detail in respect of how it could be implemented.


The main entry point is course/snapshot.php. This accepts a required parameter 'id', which defines the course. The user must be logged on and have the required capability in their role to perform this function. My current view is that the functionality is mostly defined by a class, 'Snapshot', within this file. It is possible that development may dictate that this is moved to a library function - probably in the lib directory. The other responsibility of this script is to create the HTML code for the course page and build the zip file.

The functionality for each activity or resource will be handled in the module code. A new function in the module library (mod/xxxx/lib.php) will be defined - function snapshot( $instance ). For non core modules this will be optional. The course snapshot code will check that this function is defined before calling it. Modules that themselves define further plugins (for example, question types, assignment types) may themselves require to define an addition to their API to support this.


This script has the following functionality...

  • Read the 'id' parameter - the course id
  • Check the user is logged on and has the appropriate role capability
  • Create the receiving zip file. The format will probably be something like "". It may also be subject to some sort of caching arrangement but this will be a "phase 2" development. It is likely that the PHP Zip functions [1] will be used as they can create files within the zip archive directly from a string, which is useful in this case
  • Build an object image of the course
  • Build the image of the index.php file. This is simply a snapshot of the course page. This is added to the zip file. Links are converted appropriately using an algorithm (to be described)
  • For modules that define the snapshot function in their library call them to define the pages for the instance of that module. Add each to the archive.
  • Add the files area, minus any restricted folders (e.g., backups) to the archive

function snapshot in mod/xxx/lib.php

This function is optional (certainly for optional modules). The course/snapshot.php will generate links to activities/resources only when the module supports the snapshot functionality. If not, a non clickable 'link' will be substituted (even, possibly, an actual link to a "this activity is not supported" page.

The function takes as a parameter the instance id of the module and the module name in order to indentify the instance. The function is then expected to generate a flat HTML representation of the page which it returns as a string. Some modules will need to return multiple pages of HTML. These may return an array of strings, the names of each page being defined by the array keys. The main script will identify the difference and create the pages in the zip file accordingly.

Naming conventions for links and archive files

Clearly within the archive the links will need to be regenerated with more sensible names. The general convention for resources and activities is proposed to be:


So, for example, a URL of http://my.domain/moodle/course/view.php?id=12345 which points to a forum will be now relate to an archive file forum_12345. All basic HTML files will be in the top level of the archive hierarchy.

The contents of the files area will be copied over into the archive into a folder called files. Therefore any references to files in the course materials will simply require the path files/ to be prepended.

A css file will automatically be provided called snapshot.css. It is envisaged that in the future alternative css files could be available and/or special printing alternatives could be created.

Issues to be resolved

Who can use this/Performance

This could turn out to be a fairly intensive process performance wise which may be an issue if it is available to all comers. The simplest solution is to simply make its available a permission in the roles infrastructure which is not available to students by default.

As, by definition, it generates a zip file it would need to be decided if that zip files persists after it has been downloaded. If so part of the cron structure could remove old files but this is probably starting to involve creating an options page.

Variable student views

Students can, most due to groups, have entirely different views on the contents of a course. In fact, this may even involve serious confidentiality implications. It is easy enough to allow a student the simply grab 'their' view of the current course. Similarly, it is easy enough for a teacher to grab a snapshot of the entire course with all groups included. However, it is much less obvious how a teacher could take a snapshot intended to be viewed by all students in all groups. Perhaps this is simply not possible and the tool would be ineffective in this mode.

How to link to ePortfolio options

Moodle currently has no standard portfolio module and there are a number out there. As has been described earlier, it would be very nice to be able to add Moodle content (for example the current view of a forum discussion) to a portfolio as a snapshot. As the library function in the modules more-or-less does exactly what is required this should be an easy add on. What is less clear is how to interface, in the general case, with external options. A published API would clearly be needed. This would likely require some sort of "callback" arrangement, where the portfolio system (or anything else that wants to do this) would "register" its interest.