A filter, useful in a page or block, for showing and storing a button state (once). Such as when you want to enter a draw, or vote for one thing. Probably not a lot of use-cases for this one.

html can go here before


Put in the stuff you want to appear when the button hasn't been pushed

[[ENTERDRAW:BUTTON The button text goes here]]


Your vote counts! Get your socks on, it's going to be a wild ride.


html can go here too

Logs an event when the user clicks the button, and stores the state in the user preferences.

How does the user or the teacher reset or unsubmit the link? ¯\_(ツ)_/¯


The ‘One Topic’ course format displays one topic at a time, with each topic appearing as a tab

The ‘Topic Activity Cards’ course format displays activities as cards.

What if we were to smoosh them together? What if you wanted:

  • Tabs to appear on mobile but not on desktop and have one of those hamburger menu things to show the sections?
  • An picture for each activity (not an icon) that you could pull from (say) the activity description, or a custom field? Or turn off the icon for each activity and just have raw links?
  • Some way to list TAGS for each activity, rather than the ‘tag cloud’ block? Or some way of listing custom fields that might be defined for activity modules?
  • Other semi-useful features like bookmarking activites using a star, different shape tile layouts, too many options?

Well, you would have OneTopicPlus:

linkedin badge

You have earned a badge and now want to post it on your profile on LinkedIn to show it off. Easy right?

Well, no. LinkedIn doesn’t have an easy API to posting external images or pages, but they do have a ‘add certification’ custom popup that you can include into a page that allows you to post the image – as long as the image is accessible to the general (un-authenticated) internet. That isn’t something Moodle lets you do – it makes the badge information page publically accessible but the badge itself is rendered at a tiny size (internally hard-coded too).

moodle is suposedly a modular environment that lets you extend and override a whole bunch of pages and areas using custom php or local plugins. except for the Badge page which is linked from the user profile page – it is effectively hard coded and isn’t part of the normal page render cycle. To change the Badge page you have to use a combination of two features:

  • custom scripts
  • overridden renderer in your theme

This is because a local plugin can’t override the renderer used by this page. So if you already have a custom theme, you have to modify it to patch in a renderer for the badge page and render the standard page plus your own modifications.

I’ve added a github repository which describes how to make the required changes and come sample code. unfortuantely I can’t supply a standalone plugin for just showing the button because of the way both linkedin and moodle have structured their systems.

arid theme

a moodle 3.11+ Boost ‘extension’ theme that turns off all the navigation, blocks, breadcrumbs and plugin outputs (alerts, notifications). for use when you want to show a single-activity type course (often a page, survey, or custom activity type) without any of the standard design.

it is expected that this is a course or category-specific theme, not a site theme.



for when ‘guest’ access just isn’t quite enough.

This is a moodle auth plugin to log in as an anonymous user who is then able to interact and save data without being identifiable. It is intended to be used when paired with courses containing a survey, feedback form, or other self-assessment-type activity.

About the Guest role

The guest role is great. It lets you expose courses or pages as if you were logged on. You can interact with items, watch videos, whatever. But at no point will the underlying system let you save anything at all back to the database. It’s a read-only role.


it’s available on my github.

Course Units

Core Units example

This filter will display a list of courses in the current category as a linked list, filtered to the courses that contain a specific custom attribute value. It automatically excludes a link to the current course.

It can display courses that have one of these custom attribute values:

  • Core
  • Elective
  • Optional
  • Introduction

It is a filter rather than a course format, activity type or block simply so that it can be used inside an activity such as a page or label. This is especially helpful for single-activity courses such as course homepages or standalone information pages.

The custom attribute value is currently hardcoded with the name ‘unittype’ of type ‘dropdown’ with the values shown in the list above in that order, but this will be made configurable in a future version.

Example scenario

Set up a single-activity course that is a page, then in the page description or content use the filter to link to your grouped courses. Use the shortcode shown below to list courses matching the attribute filter:

Welcome to the XYZ Doohickey Course. Click on the units below to get started.

Core units


Elective units



Each figure is rendered using the classnames ‘coursebox’ and the value of the custom attribute. For instance, <figure class='coursebox elective'>... This allows you to apply different styling based on the type of figure rendered. For instance, you could recolour the images based on the unit type:

/* assumes <div class='unit-list'>[[units::Core]]</div> */
.unit-list {
    display: grid;
    grid-template-columns: repeat(3,minmax(250px,1fr));
    grid-template-rows: auto;
    grid-template-areas: ". . .";
    width: 100%;
    gap: 1rem;
.unit-list>.elective img {
    filter: sepia(1) hue-rotate(135deg); /* blueish tint */
.unit-list>.core img {
    filter: sepia(1); /* yellowish tint */


You can download this plugin on my Github page.

Nosey Notifications

Leverages Moodle events for some common events within courses such as enrolling, unenrolling, completing activities and courses, creating updating and deleting courses. It notifies an external URL and posts the record that changed.

Open Sesame

Send in the [encrypted] user id, the user will be logged on and the first course this user is enrolled in will open. Handy for launching courses from an external management portal.


A local plugin for executing artbitary SQL statements (not just SELECT’s) through the cron. Relies on the DB permissions to execute/insert to be set for the moodle db user.