AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Moodle Accessibility

skill-saadrahman01-claude-moodle-dev-moodle-accessibility · by SaadRahman01

Use when ensuring Moodle plugin UI meets WCAG 2.1 AA — semantic HTML in Mustache, ARIA via core helpers, keyboard navigation, color contrast in SCSS, focus management in modals, screen reader testing, and Pa11y/axe automation.

No reviews yet
0 installs
31 views
0.0% view→install

Install

$ agentstack add skill-saadrahman01-claude-moodle-dev-moodle-accessibility

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-saadrahman01-claude-moodle-dev-moodle-accessibility)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Moodle Accessibility? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Moodle Accessibility (WCAG 2.1 AA)

Overview

Moodle targets WCAG 2.1 AA. UI in plugins must follow same standard for inclusion. Boost theme + Bootstrap 5 + Moodle's component library do most of the heavy lifting — your job is to use them correctly.

When to Use

  • Building any UI (Mustache template, modal, custom form element)
  • Reviewing PR for accessibility regression
  • Submission to moodle.org plugin directory (a11y is reviewed)
  • Responding to a user-reported a11y bug

Top rules

  1. Use semantic HTML: ` for actions, for navigation, ` in order
  2. Every interactive element keyboard-reachable with visible :focus
  3. Every image has alt; decorative images: alt=""
  4. Color contrast ≥ 4.5:1 (text), 3:1 (UI components)
  5. Forms: `` linked to every input
  6. Don't use color alone to convey meaning
  7. Modals trap focus, restore on close

Semantic Mustache

{{! BAD }}
Save

{{! GOOD }}
{{#str}}save, core{{/str}}

Headings:

{{#str}}announcements, local_example{{/str}}
...

Skip levels = WCAG fail. ` then ` is wrong.

Forms — formslib

MoodleQuickForm outputs `` automatically. Don't bypass:

$mform->addElement('text', 'name', get_string('name', 'local_example'));
$mform->setType('name', PARAM_TEXT);
$mform->addRule('name', null, 'required', null, 'client');

// Help button — adds aria-described relationship
$mform->addHelpButton('name', 'name', 'local_example');

For required fields, addRule('required') adds aria-required="true".

Buttons / links

| Element | Use for | |---------|---------| | ` | Form submit | | | JS action | | ` | Navigation to a URL |

Never ` — use . Never ` unless you also handle keyboard (Enter + Space) and focus.

Icons

{{#pix}}t/edit, core, {{#str}}edit, core{{/str}}{{/pix}}

Pix renderer outputs `` with the title as alt. For decorative icons accompanying visible text:


  {{#pix}}t/edit, core{{/pix}}
  {{#str}}edit, core{{/str}}

Bootstrap 5: .visually-hidden (was .sr-only in BS4).

Color contrast

Boost defines $primary, $secondary, etc. Don't override to low-contrast values.

// theme/yourtheme/scss/post.scss
$primary: #0f6fc5;     // contrast vs white = 5.13:1 ✓
$danger:  #d9534f;     // contrast vs white = 3.34:1 ✗ — fails AA for text

Test: https://webaim.org/resources/contrastchecker/

Don't rely on color only:

{{! BAD — color only }}
{{name}}

{{! GOOD — icon + color }}

  {{#pix}}t/error, core, {{#str}}invalid, local_example{{/str}}{{/pix}}
  {{name}}

Tables


  {{#str}}attendance, local_example{{/str}}
  
    
      {{#str}}user, core{{/str}}
      {{#str}}status, core{{/str}}
    
  
  
    {{#rows}}
    
      {{name}}
      {{status}}
    
    {{/rows}}
  

html_table from lib/outputcomponents.php renders accessibly:

$table = new \html_table();
$table->head = [get_string('name'), get_string('status')];
$table->headspan = [1, 1];
$table->caption = get_string('attendance', 'local_example');
echo \html_writer::table($table);

ARIA — minimal use

Native HTML > ARIA. Only add ARIA when no native equivalent.

{{! tab pattern — needs ARIA }}

  One
  Two

...

Bootstrap 5 tab JS handles arrow keys. Don't reimplement.

Modals

Use core/modal — handles focus trap, ESC key, focus restore on close.

import Modal from 'core/modal';

const modal = await Modal.create({
    title: await getString('confirm', 'core'),
    body: await Templates.render('local_example/confirm', {}),
    show: true,
    removeOnClose: true,
});
// focus auto-traps inside; on close, focus returns to trigger element

Custom focus management:

import {trapFocus} from 'core/local/aria/focusmanager';
const release = trapFocus(modalEl);
// ... when closing:
release();
triggerEl.focus();

Live regions (toasts, async updates)

import {add as addToast} from 'core/toast';
addToast('Saved', {type: 'success'});

core/toast uses aria-live="polite". For urgent alerts: aria-live="assertive" (sparingly — interrupts screen readers).

Keyboard

Every interactive control:

  • Focusable in source order (don't tabindex="0" everything)
  • Activated with Enter / Space
  • Visible focus ring (don't outline: 0 without replacement)
  • Custom widgets follow WAI-ARIA Authoring Practices

Screen reader testing

| OS | SR | Browser | |----|----|---------| | Windows | NVDA (free) | Firefox | | macOS | VoiceOver | Safari | | Linux | Orca | Firefox | | iOS | VoiceOver | Safari | | Android | TalkBack | Chrome |

Quick checks:

  • Tab through entire UI — every interactive element reachable
  • Use SR-only — does the experience make sense?
  • Resize text 200% — layout still works?
  • Disable CSS — content order still meaningful?

Automation

# axe-core via Puppeteer
npm install -g @axe-core/cli
axe http://localhost:8000/local/example/

# Pa11y
npm install -g pa11y
pa11y --standard WCAG2AA http://localhost:8000/local/example/

CI integration: run on PRs against staging.

Common Mistakes

| Mistake | Fix | |---------|-----| | ` | | | Missing alt on | Add — alt="" if decorative | | placeholder as label | Add real | | outline: 0 no replacement | Restore visible focus indicator | | Heading level skip | Sequential // | | Link text "click here" / "more" | Descriptive (Edit user "Alice") | | role="button" without keyboard | Use instead | | Color-only error indication | Add icon + text | | Color contrast with no role | Either add role or use text instead | | aria-hidden="true" on focusable element | Either unhide or remove from tab order |

Plugin directory review

moodle.org reviewers run a11y checks. Common rejection reasons:

  • New custom modal without focus trap
  • Hard-coded colors failing AA contrast
  • Custom widgets without ARIA / keyboard
  • Missing `` on form fields

References

  • Accessibility: https://moodledev.io/general/development/policies/accessibility
  • WCAG 2.1: https://www.w3.org/TR/WCAG21/
  • WAI-ARIA APG: https://www.w3.org/WAI/ARIA/apg/
  • Boost a11y: https://docs.moodle.org/dev/Boost-Accessibility
  • pix renderer: https://moodledev.io/docs/apis/subsystems/output#pix-icons

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.