Skip to content

Backend support for Markdown descriptions and migration from bleach to nh3#2140

Open
Frenzy-code wants to merge 8 commits intowger-project:masterfrom
Frenzy-code:markdown
Open

Backend support for Markdown descriptions and migration from bleach to nh3#2140
Frenzy-code wants to merge 8 commits intowger-project:masterfrom
Frenzy-code:markdown

Conversation

@Frenzy-code
Copy link
Copy Markdown

Proposed Changes

  • Replace the deprecated bleach library with nh3 for HTML sanitization and add markdown-it-py for Markdown rendering and markdownify for HTML to Markdown conversion.
  • Add description_source field to the ExerciseTranslation model to store raw Markdown input.
  • Update ExerciseTranslation.save() to render Markdown to description. So now New Markdown input is stored in description_source and automatically rendered to HTML for the legacy description field. This way it preserves compatibility while also sanitizing all HTML inputs using nh3 library.
  • Add migrate_descriptions_to_markdown management command to convert existing HTML descriptions to Markdown using markdownify.
  • Update ExerciseTranslationSerializer to expose the new description_source field for editing, while keeping description read-only for backward compatibility with existing clients.
  • Add wger/wger/utils/markdown.py to modularly handle rendering logic only for ('b' / 'strong', 'em' / 'i', 'ul', 'ol', 'li', 'p').
  • Note: This PR implements the backend and API changes only. React and Flutter clients are not updated in this PR and will continue to function using the cached HTML description.

Related Issue(s)

Closes #1240 (but not the Flutter and React sub-issues)

Please check that the PR fulfills these requirements

  • Tests for the changes have been added (for bug fixes / features)
  • Code has been formatted to avoid unnecessary diffs (ruff format && isort .)

Other questions

  • Do users need to run some commands in their local instances due to this PR
    (e.g. database migration, deployment changes)?

Yes. After applying standard django migrations (python manage.py migrate), administrators should run the following command to generate Markdown sources for existing exercises:

python manage.py migrate_descriptions_to_markdown

This command has a --dry-run flag, which is recommended for testing the conversion before making permanent changes:

python manage.py migrate_descriptions_to_markdown --dry-run

Mannai and others added 4 commits December 10, 2025 00:55
- Remove  dependency (deprecated).
- Add  and  dependencies.
- Add  field to ExerciseTranslation model.
- Update API serializers to handle markdown input.
- Create  for rendering and sanitization.
- Added `migrate_descriptions_to_markdown` command to convert legacy `description` (HTML) content to `description_source` (Markdown) using `markdownify`.
- Migrated to add the `description_source` field to `ExerciseTranslation` and `HistoricalTranslation`.
- Updated `ExerciseTranslation.save()` logic to handle both Markdown source input AND legacy raw HTML input, ensuring the strict `nh3` sanitization is applied in both cases to maintain data integrity.
- Adjusted test expectations (`test_command_migrate_descriptions`, `test_patch_clean_html`) to correctly reflect the strict CommonMark rendering (`<strong>`, `<em>`) and the secure content-stripping behavior of the `nh3` sanitizer.

Now the backend completely replaced `bleach` and adopted Markdown descriptions.
@rolandgeider
Copy link
Copy Markdown
Member

NB: I'm planning to finish implementing the UI for the trophies, doing a release, and then merging this for the next one

This make the migration happen automatically, and makes sure the exercises don't
end up in a half migrated step or so.
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.

Move exercise description to markdown

2 participants