Docs:Filtering

From DevWiki
Jump to navigation Jump to search
IMPORTANT: This page contains specification information. You should read it carefully, and periodically verify that your work conforms to the specification if appropriate.


It is occasionally necessary to create course CBT packages that share a substantial amount of common material, but which must be tailored specifically to include or exclude material, depending upon the intended audience. This is exemplified by the C Programming course, where the 'Java to C' material is provided for the School of CS online C material, but it is not needed or included in the APEcs C Programming course. Conversely, the Overview theme is needed for the APEcs C course, but not for the School of CS version. It would clearly be wasteful to create multiple copies of the same course with audience-specific variations in each copy. Doing so is also likely to be the source of bugs, and the sort of 'which version is up to date' problems this wiki was created to address. There needs to be a solution that supports these different requirements easily and with a minimum of duplication.

One method is to perform widespread transclusion: have a 'master' course that contains everything, and then separate courses that transclude content from the master course to produce different versions of the course. This is can be a viable option, provided that the only variation in content is the inclusion or exclusion of entire themes or modules. However, if the tailoring of the content needs to happen at the step level, this system will not work, and more seriously it introduces problems when dealing with media and pre-made theme maps.

Another alternative is given here: filtering, which provides the means to include or exclude content down to the step level, overcomes media issues, and keeps all material related to a given course in one place.

Filtering overview

The basic idea behind the filtering system is the marking of pre-defined course and theme maps, themes, modules, and even steps (henceforth, all of these will be referred to as 'resources') as being included in, or excluded from, a generated course depending on whether or not a filter keyword (also referred to as a 'filter name') was specified when invoking the processor. The marking portion of this approach fits naturally into the metadata framework, and metadata elements provided for this purpose are documented below and on the metadata documentation page.

When the user starts the processor, they have the option of providing one or more --filter arguments, each followed by a comma-separated list of one or more filter keywords. If no --filter arguments are provided by the user, the course generated by the processor contains all resources in the source material that have no filtering options set, and includes all resources that only have exclude filters (see below for more on this). If a --filter argument is specified, the resulting course contains all unmarked resources, any resources that are marked as being included by the specified filter keywords, and excludes any resources that are marked as such by the specified filter keywords. By providing more than one filter keyword in the --filter argument, the user can create 'compound' courses - courses that contain resources tailored to several specific audiences - or create specially cut-down versions of tailored courses for demo purposes.

Marking resources in the metadata

In the metadata, the following elements can be specified to mark a resource for filtering:

The filters element

The filters element can be added to the metadata for any theme, module, or step that needs to be included or excluded depending on the filtering option passed to the processor by the user. If a theme, module, or step has no filters element, or an empty filters element, then it will always be included in the course regardless of the filters specified by the user on the command line.

Attributes
None. This element is a container only.
Example
<filters>
    <include>socs</include>
</filters>

The include element

The include element is a filter selector that can only appear within a filters element. The include element acts as a marker that says "Only include this resource in the course if one or more of the specified include filter keywords matches one or more of the keywords in the list passed to the processor, otherwise do not include this resource in the course". When a resource has a filters element that contains one or more include elements, the resource will only be included in the course when at least one of the filter keywords in the includes appears in the list of keywords provided via the processor's --filter argument. This is the only situation in which a resource with one or more include elements in its filters element will be generated: if the processor is run without a --filter argument, or with a --filter argument whose list of filter keywords does not include one of the keywords set in the resource's includes, the resource will not be included. For example, a resource that has the following filters element will only be generated when the filter list provided to the processor includes 'socs', otherwise it will not be included:

Attributes
None. This element is a container only.
Example
In this example, the resource will only be added to the generated course if the list of filter keywords passed to the processor includes the keyword "socs".
<filters>
    <include>socs</include>
</filters>

The exclude element

The exclude element is a filter selector that can appear inside a filters element. The exclude element acts as a marker that says "If a resource can be included (subject to any restrictions imposed by any include elements) always include it, unless the filter keyword matches any of the keywords in the list passed to the processor". When a resource has a filters element that contains one or more exclude elements, the resource will always be included in the course unless:

  1. The filters element for the resource contains one or more include elements, and none of the filter keywords specified in the resource's include elements appear in the list of keywords the processor was given on the command line.
  2. One or more of the filter keywords specified in the exclude elements are present in the list of filter keywords the processor was given on the command line.
Attributes
None. This element is a container only.
Example
In this example, a resource with the following filters element will always be included in the generated course, unless the filter list provided to the processor includes 'socs', in which case it will not be included:
<filters>
    <exclude>socs</exclude>
</filters>
This is a more complicated example, where the resource will only be included in the generated course if the filter list provided to the processor includes 'socs', and it does not also include 'demo':
<filters>
    <include>socs</include>
    <exclude>demo</exclude>
</filters>

In addition to the above elements, some metadata elements (the map and resource elements, for example) provide similarly operating attributes when using a filters element is not a viable option. These attributes may contain a comma separated list of filter keywords to apply to the element.

Filtering operation details

The filtering process

When the processor is deciding whether or not to include a resource in the generated CBT package, it follows the stages shown in the flowchart to the right. The process can be summarised as follows:

If a resource does not have a filters element in its metadata (or has a filters element that does not contain any include or exclude elements), it will always be included in the course, regardless of any values provided via the --filter argument.

If a resource has a filters element that only contains exclude elements it will be included in the output as long as none of the filter keywords in the exclude elements match any of the filter keywords passed to the processor via the --filter argument. Similarly, any map or resource elements that have no include attribute and specify one or more filter keywords in their exclude attribute will be included as long as none of the keywords in the attribute match the keywords passed to the processor.

If a resource has a filters element in its metadata that contains one or more include elements, it will only be included in the output if at least one of the keywords specified in the include elements matches a filter keyword passed to the processor via the --filter argument and it does not have an exclude element containing a filter keyword that also matches a keyword passed to the processor. That is, it will only be included if any of its includes matches a provided filter keyword, but it can then be excluded again if any of its excludes match one too.

Filtering Example

The following is an example of several filtering features, based around a modified version of the Java to C module in the C course. An explanation follows the example xml:

<theme name="java_c" title="Java to C" indexorder="1">
    <module title="Java to C introduction" name="introduction" level="green" indexorder="1">
        <leadsto>
            <target>similarities</target>
            <target>differences</target>
        </leadsto>
    </module>
    <module title="Similarities between Java and C" name="similarities" level="yellow" indexorder="2">
        <leadsto>
            <target>warnings</target>
        </leadsto>
    </module>
    <module title="Differences between Java and C" name="differences" level="yellow" indexorder="3">
        <leadsto>
            <target>warnings</target>
        </leadsto>
    </module>
    <module title="Final notes and Warnings" name="warnings" level="yellow" indexorder="4">
        <leadsto>
            <target>more</target>
        </leadsto>
    </module>
    <module title="More Warnings" name="more" level="red" indexorder="5">
        <filters>
            <include>extrawarn</include>
        </filters>
    </module>
    <maps>
        <map exclude="extrawarn"><![CDATA[
<img src="../media/C_Theme6_map.png" width="687" height="480" border="0" alt="" usemap="#Theme6_map_Map">
<map name="Theme6_map_Map">
<area shape="poly" alt="" coords="285,315, 407,315, 408,365, 285,365" href="warnings/step01.html">
<area shape="poly" alt="" coords="443,241, 559,241, 558,315, 445,315" href="differences/step01.html">
<area shape="poly" alt="" coords="125,241, 240,241, 242,315, 130,314" href="similarities/step01.html">
<area shape="poly" alt="" coords="286,186, 394,187, 396,241, 285,239" href="introduction/step01.html">
</map>
        ]]></map>
        <maps include="extrawarn"><![CDATA[
<img src="../media/C_Theme6_map_Extra.png" width="687" height="480" border="0" alt="" usemap="#Theme6_map_Map">
<map name="Theme6_map_Map">
<area shape="poly" alt="" coords="285,218, 407,218, 408,268, 285,268" href="more/step01.html">
<area shape="poly" alt="" coords="285,315, 407,315, 408,365, 285,365" href="warnings/step01.html">
<area shape="poly" alt="" coords="443,241, 559,241, 558,315, 445,315" href="differences/step01.html">
<area shape="poly" alt="" coords="125,241, 240,241, 242,315, 130,314" href="similarities/step01.html">
<area shape="poly" alt="" coords="286,186, 394,187, 396,241, 285,239" href="introduction/step01.html">
</map>
        ]]></map>
    </maps>
    <filters>
        <include>socs</include>
        <include>java</include>
        <exclude>apecs</exclude>
    </filters>
</theme>

If a course contains a theme with the above metadata then:

  • The entire theme will only be included in the generated course if the list of filter keywords provided when starting the processor contains "socs" or "java", and 'does not contain "apecs". That is, invoking the processor with --filter=socs or --filter=java will result in the theme being included in the course, but --filter=apecs will prevent the theme and all its contents from being added to the output, even if "socs" or "java" have been specified as well.
  • Assuming that the theme will be included in the generated course, the "More Warnings" module will only be added to the generated course if the "extrawarn" keyword is included in the list of filter keywords passed to the processor, ie: --filter=socs,extrawarn. If the "extrawarn" keyword does not appear in the list passed to the processor, the "More Warnings" module will not be included in the course.
  • If the "extrawarn" keyword is included in the list of filter keywords passed to the processor, the first resource block will be excluded and the second will be included. If the "extrawarn" keyword is not included, the first resource block will be used, and the second will not.