Skip to content

Reveal teacher content via eXeLearning's ?exe-teacher URL param, retire CSS injection#65

Open
erseco wants to merge 5 commits into
mainfrom
fix/teacher-mode-url-param
Open

Reveal teacher content via eXeLearning's ?exe-teacher URL param, retire CSS injection#65
erseco wants to merge 5 commits into
mainfrom
fix/teacher-mode-url-param

Conversation

@erseco

@erseco erseco commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Do not merge until exelearning/exelearning#1972 is merged. This PR depends on the core ?exe-teacher=1 contract introduced there; merging earlier would break teacher-mode reveal in the embed.

Why this simplifies the plugin (and where it's heading). Teacher-mode visibility is now driven purely by the package's own ?exe-teacher=1 URL parameter, so the host plugin no longer injects CSS/JS into the embedded package to control it. Beyond removing that injection, this advances the longer-term goal of isolating embedded resource content from the host: because the host no longer reaches into the package DOM, the resource can later be sandboxed / served cross-origin without losing teacher-mode control.

What

eXeLearning core now hides teacher-only content by default and exposes an in-package selector to show it via the ?exe-teacher=1 URL parameter (upstream exelearning/exelearning#1972, fixes exelearning/exelearning#1772). This consumes that contract and retires the plugin's parent-side teacher-mode CSS injection. Mirrors the mod_exelearning (#86) change.

Changes

  • locallib.php: removed exeweb_require_teacher_mode_hider_for_iframe() (injected CSS into the embedded iframe). exeweb_display_embed() now appends ?exe-teacher=1 to the iframe content URL whenever exeweb_is_teacher_mode_visible($exeweb) is true — for every viewer.
  • The teachermodevisible setting keeps its original "Show teacher layer selector" label/help (en/es), homogeneous with the other plugins.

Notes

  • The setting alone controls the selector — no capability gate. When on, the in-package selector is available to every viewer; it is OFF by default and the viewer activates it. Presentation mode, not access control.
  • Branches off main. No schema change, no version bump.

Testing

  • php -l clean. Unit + Behat updated: the iframe src carries exe-teacher=1 when the setting is on (including for a student) and omits it when off. PHPUnit/Behat need a Moodle CI site.

Moodle Playground Preview

The changes in this pull request can be previewed and tested using a Moodle Playground instance.

Preview in Moodle Playground

ℹ️ The eXeLearning editor is fetched from the shared release and unpacked into the plugin when the playground boots, so the first load may take a few extra seconds. ELPX upload, viewer and preview work normally.

erseco added 3 commits June 19, 2026 06:09
… of CSS injection

eXeLearning core now hides teacher-only content by default and reveals it via
the package's own ?exe-teacher=1 URL parameter (upstream exelearning#1772).
Consume that contract here and retire the plugin's parent-side teacher-mode CSS
injection, which coupled the plugin to the package internals.

exeweb_display_embed() now appends ?exe-teacher=1 to the iframe content URL only
for users who can manage the activity AND when the per-activity setting opts in;
students never receive the parameter and always see the student view. The decision
is a pure, unit-tested helper, exeweb_should_reveal_teacher_content().

Removed:
- exeweb_require_teacher_mode_hider_for_iframe() and its call in
  exeweb_display_embed() (injected CSS into the embedded iframe contentDocument
  to hide #teacher-mode-toggler-wrapper).

The teachermodevisible field is kept (mod_form default 1, lib.php displayoptions)
and repurposed: it now gates whether teachers see eXeLearning's teacher content
revealed in the embedded view (combined with the manageactivities capability).
Updated the lang help (en + the hand-maintained es) to the new meaning; the
exeweb_is_teacher_mode_visible() docblock too.

Tests:
- tests/locallib_test.php covers the new helper across the truth table and
  exeweb_is_teacher_mode_visible() default/stored behaviour.
- tests/behat/teacher_mode.feature adds server-rendered scenarios asserting the
  iframe src contains/omits exe-teacher for teacher (on/off) and student.
Drop the capability gate. The per-activity teachermodevisible setting alone
controls whether the package's own ?exe-teacher=1 selector is offered, and it
is offered to every viewer (students included) when on. Remove the now-trivial
exeweb_should_reveal_teacher_content() helper and its unit test, restore the
original "Show teacher layer selector" translations, and update the Behat
scenario (a student also gets the parameter when the setting is on).
@erseco erseco self-assigned this Jun 28, 2026
@erseco erseco requested a review from ignaciogros June 28, 2026 07:06

@ignaciogros ignaciogros left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although the "Show teacher layer selector" option is enabled, the content URL, whether opened in an iframe, a new window, or a popup, does not include the exe-teacher=1 parameter.

The same result occurs for both administrator and student roles.

Could you please check the solution?

Thanks.

…ot only embed

PR #65 flagged only the embedded-iframe URL with eXeLearning's ?exe-teacher=1
reveal parameter. The popup, open and direct-redirect paths build the package
content URL separately and dropped it, so the in-package teacher-layer selector
never appeared in those display modes (reported by @ignaciogros).

Centralize the rule in exeweb_apply_teacher_mode_param() and apply it at every
content-URL build site:
- exeweb_display_embed() embed iframe (routed through the helper, unchanged)
- exeweb_get_clicktoopen() popup/open links (new optional $exeweb argument)
- exeweb_print_workaround() popup window.open() URL
- view.php redirect block (student popup/open path)

Tests:
- locallib_test: unit-test the helper and the click-to-open link
- teacher_mode.feature: add popup scenarios and fix the embed scenarios to use
  the real display value (1 = embed; 5 is open, which renders no iframe)
@erseco

erseco commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks @ignaciogros — you were right that the parameter was missing outside the embedded iframe.

Root cause: ?exe-teacher=1 was only appended in exeweb_display_embed(). The popup, open and the student redirect paths build the content URL separately (exeweb_get_clicktoopen(), exeweb_print_workaround() and the view.php redirect block) and dropped it.

Fix (912e8dd): centralized the rule in exeweb_apply_teacher_mode_param() and applied it at every content-URL build site — the embed iframe (now routed through the helper), the popup/open click-to-open links, the popup window.open() URL, and the view.php redirect students hit for popup/open.

Verified on a local Moodle 5.0, setting on vs off, content URL in each display mode:

Display Setting ON Setting OFF
Embed (1) iframe src has exe-teacher=1 absent
Popup (6) link href + window.open() URL have it absent
Open (5) redirect → …/index.html?exe-teacher=1 absent

On the embed/iframe case specifically: it was already appending the parameter (the renderer passes $fullurl->out() straight to the iframe src), so I couldn't reproduce a missing param there — the real gap was the non-embed modes. If it still looks missing in embed on your side, worth checking the activity's "Show teacher layer selector" is actually saved on (it now defaults to off).

I also fixed the Behat scenarios, which used display=5 for the "embed" cases — 5 is Open (no iframe), so those assertions couldn't have passed. Embed scenarios now use display=1, plus new popup scenarios. PHPUnit/Behat still need a Moodle CI site to run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invert Teacher Mode default in exports: hidden by default, opt-in to reveal

2 participants