You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Introduce frontend-app-sample/ next to the existing frontend-plugin-sample/.
The new directory is a frontend-base app, written in TypeScript, that
contributes a widgetReplace operation against the learner-dashboard's
CourseList slot on the bundled tutor-mfe site. The legacy directory stays
put, unchanged, and keeps targeting the per-MFE env.config.jsx flow.
Have tutor-contrib-sample register both. The operator picks which one
fires by enabling (or not) the frontend-base learner-dashboard app in
tutor-mfe.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CLAUDE.md
+12-6Lines changed: 12 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,8 +14,9 @@ This is a **sample plugin repository** that demonstrates all major Open edX plug
14
14
15
15
**Repository Structure:**
16
16
-`backend-plugin-sample/` - Django app plugin with models, APIs, events, and filters
17
-
-`frontend-plugin-sample/` - React component for MFE slot customization
18
-
-`tutor-contrib-sample/` - Tutor plugin for easy deployment
17
+
-`frontend-plugin-sample/` - React component plugged in via the legacy `frontend-plugin-framework` (FPF) and `env.config.jsx`
18
+
-`frontend-app-sample/` - frontend-base `App` (sibling of `frontend-plugin-sample/`) that registers slot operations on the bundled site
19
+
-`tutor-contrib-sample/` - Tutor plugin that installs one or the other depending on tutor-mfe's `FRONTEND_APPS` state
19
20
- Each directory has comprehensive README.md files with TOCs
20
21
21
22
**When Making Changes:**
@@ -24,14 +25,19 @@ This is a **sample plugin repository** that demonstrates all major Open edX plug
24
25
- Maintain working integration between all plugin types
25
26
- Keep examples realistic but not overly complex
26
27
28
+
**Branch context:**
29
+
This branch ships *both* frontend stacks side by side: `frontend-plugin-sample/` (legacy FPF, identical to `main`) and `frontend-app-sample/` (frontend-base App). The Tutor plugin registers both unconditionally; each one self-no-ops when its target stack isn't in play. The FPF `PLUGIN_SLOTS` contribution only renders into the legacy learner-dashboard MFE (which tutor-mfe skips when the frontend-base learner-dashboard App is enabled), and the frontend-base App's slot operation targets a slot that only exists when the frontend-base learner-dashboard App is loaded. The operator picks the active path by flipping `apps["learner-dashboard"]["enabled"]` in tutor-mfe's `FRONTEND_APPS` filter. See [Port a Frontend Plugin from frontend-plugin-framework to frontend-base](https://docs.openedx.org/en/latest/site_ops/how-tos/port-frontend-plugin-to-frontend-base.html) for the conceptual differences between the two stacks.
30
+
27
31
**Key Files and Their Relationships:**
28
32
-`backend-plugin-sample/openedx_plugin_sample/apps.py` - Plugin registration and Django integration
29
33
-`backend-plugin-sample/openedx_plugin_sample/signals.py` - Open edX Events handlers
30
34
-`backend-plugin-sample/openedx_plugin_sample/pipeline.py` - Open edX Filters implementation
31
35
-`backend-plugin-sample/openedx_plugin_sample/models.py` - CourseArchiveStatus model (business logic)
32
-
-`backend-plugin-sample/openedx_plugin_sample/views.py` - REST API endpoints consumed by frontend
33
-
-`frontend-plugin-sample/src/plugin.jsx` - React component that replaces course list slot
-`backend-plugin-sample/openedx_plugin_sample/views.py` - REST API endpoints consumed by either frontend
37
+
-`frontend-plugin-sample/src/plugin.jsx` - Legacy FPF React component (imports from `@edx/frontend-platform`)
38
+
-`frontend-app-sample/src/CourseList.tsx` - frontend-base React component, TypeScript (imports from `@openedx/frontend-base`)
39
+
-`frontend-app-sample/src/app.tsx` - frontend-base `App` with slot operations targeting the learner-dashboard, TypeScript
40
+
-`tutor-contrib-sample/tutorsample/plugin.py` - Tutor plugin: backend pip install + unconditional registration of both frontend paths (FPF via `PLUGIN_SLOTS` and frontend-base via `FRONTEND_APPS` + site-config patches); each path self-no-ops when its target stack isn't active
35
41
36
42
## Build/Lint/Test Commands
37
43
- Make sure to set the following so that test output is not too verbose: `export PYTEST_ADDOPTS="--disable-warnings --no-header --tb=short"`
@@ -69,6 +75,6 @@ Always run `make quality` and fix issues before creating a PR to ensure consiste
69
75
### Open edX Plugin Patterns
70
76
-**API Development**: Use `perform_create()`/`perform_update()` in viewsets for business logic
71
77
-**Settings**: Use additive approach for `OPEN_EDX_FILTERS_CONFIG` to avoid plugin conflicts
72
-
-**Frontend**: Use Paragon components and `getAuthenticatedHttpClient()` for platform integration
78
+
-**Frontend**: Use Paragon components and import `getAuthenticatedHttpClient`/`getSiteConfig` from `@openedx/frontend-base` (not `@edx/frontend-platform`). The package's default export is the frontend-base `App`.
73
79
-**Events**: Import signal handlers in `apps.py ready()` method for proper registration
74
80
-**Filters**: Return dictionaries with same parameter names as input, handle all scenarios
Copy file name to clipboardExpand all lines: README.md
+35-14Lines changed: 35 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,8 @@ This sample plugin showcases the **Open edX Hooks Extension Framework**, which a
32
32
|**Django App Plugin**| Add models, APIs, views, and business logic |[How to create a plugin app](https://docs.openedx.org/projects/edx-django-utils/en/latest/plugins/how_tos/how_to_create_a_plugin_app.html)|[`backend-plugin-sample/`](./backend-plugin-sample/)| Adding new functionality, APIs, or data models |
33
33
|**Events (Signals)**| React to platform events |[Open edX Events Guide](https://docs.openedx.org/projects/openedx-events/en/latest/)|[`backend-plugin-sample/openedx_plugin_sample/signals.py`](./backend-plugin-sample/openedx_plugin_sample/signals.py)| Integrating with external systems, audit logging |
34
34
|**Filters**| Modify platform behavior |[Using Open edX Filters](https://docs.openedx.org/projects/openedx-filters/en/latest/how-tos/using-filters.html)|[`backend-plugin-sample/openedx_plugin_sample/pipeline.py`](./backend-plugin-sample/openedx_plugin_sample/pipeline.py)| Customizing business logic, URL redirects |
|**Frontend Plugin (FPF)**| Customize MFE interfaces via [frontend-plugin-framework](https://github.com/openedx/frontend-plugin-framework)|[Frontend Plugin Slots](https://docs.openedx.org/en/latest/site_ops/how-tos/use-frontend-plugin-slots.html)|[`frontend-plugin-sample/`](./frontend-plugin-sample/)| UI customization on legacy per-MFE images |
36
+
|**Frontend App (frontend-base)**| Customize MFE interfaces via the [frontend-base](https://github.com/openedx/frontend-base) Apps model |[tutor-mfe Frontend-base site](https://github.com/overhangio/tutor-mfe#frontend-base-site)|[`frontend-app-sample/`](./frontend-app-sample/)| UI customization on the bundled frontend-base site |
# in your own Tutor plugin, set up a fork of frontend-template-site
65
+
# with frontend-app-sample in packages/ (see frontend-app-sample/README.md
66
+
# for details), then:
67
+
cd path/to/frontend-site && npm i && npm run dev:packages
58
68
```
59
69
70
+
> [!NOTE]
71
+
> This carries both the legacy `frontend-plugin-sample/` (frontend-plugin-framework) and a `frontend-app-sample/` sibling that targets tutor-mfe's [frontend-base site](https://github.com/overhangio/tutor-mfe#frontend-base-site). The Tutor plugin in `tutor-contrib-sample/` registers both. For the conceptual differences between the two stacks, see [Port a Frontend Plugin from frontend-plugin-framework to frontend-base](https://docs.openedx.org/en/latest/site_ops/how-tos/port-frontend-plugin-to-frontend-base.html).
72
+
60
73
### Option 2: Development without Tutor
61
74
62
75
```bash
@@ -91,7 +104,8 @@ Use the table above to identify which type of plugin matches your needs. You can
91
104
-**Backend**: Start with [`backend-plugin-sample/openedx_plugin_sample/apps.py`](./backend-plugin-sample/openedx_plugin_sample/apps.py) to understand plugin registration
92
105
-**Events**: Examine [`backend-plugin-sample/openedx_plugin_sample/signals.py`](./backend-plugin-sample/openedx_plugin_sample/signals.py) for event handling patterns
93
106
-**Filters**: Review [`backend-plugin-sample/openedx_plugin_sample/pipeline.py`](./backend-plugin-sample/openedx_plugin_sample/pipeline.py) for behavior modification
94
-
-**Frontend**: Explore [`frontend-plugin-sample/src/plugin.jsx`](./frontend-plugin-sample/src/plugin.jsx) for UI customization
107
+
-**Frontend (FPF)**: Explore [`frontend-plugin-sample/src/plugin.jsx`](./frontend-plugin-sample/src/plugin.jsx) for the legacy React component plugged into `env.config.jsx`
108
+
-**Frontend (frontend-base)**: Explore [`frontend-app-sample/src/app.tsx`](./frontend-app-sample/src/app.tsx) for the App declaration and [`frontend-app-sample/src/CourseList.tsx`](./frontend-app-sample/src/CourseList.tsx) for the React component
95
109
96
110
### 4. Run This Sample
97
111
Follow the [Quick Start Guide](#quick-start-guide) to see everything working together.
@@ -115,15 +129,22 @@ sample-plugin/
115
129
│ │ ├── settings/ # Plugin settings configuration
116
130
│ │ └── urls.py # URL routing
117
131
│ └── tests/ # Comprehensive test examples
118
-
├── frontend-plugin-sample/
119
-
│ ├── README.md # Frontend plugin detailed guide
132
+
├── frontend-plugin-sample/ # Legacy FPF version (env.config.jsx)
133
+
│ ├── README.md
134
+
│ ├── src/
135
+
│ │ ├── plugin.jsx # React component for the FPF slot
136
+
│ │ └── index.jsx # Named exports
137
+
│ └── package.json
138
+
├── frontend-app-sample/ # frontend-base version (site config; TypeScript)
139
+
│ ├── README.md
120
140
│ ├── src/
121
-
│ │ ├── plugin.jsx # React component for MFE slot
122
-
│ │ └── index.jsx # Export configuration
123
-
│ └── package.json # NPM package configuration
124
-
└── tutor-contrib-sample/
141
+
│ │ ├── CourseList.tsx # React component
142
+
│ │ ├── app.tsx # frontend-base App with slot operations
143
+
│ │ └── index.ts # Default-exports the App
144
+
│ └── package.json
145
+
└── tutor-contrib-sample/ # Registers both siblings; each self-no-ops when inactive
0 commit comments