Skip to content

[16.0][ADD] document_page_markdown: add new module - #654

Open
CristianoMafraJunior wants to merge 1 commit into
OCA:16.0from
Escodoo:16.0-add-new-module-document_page_markdown
Open

CristianoMafraJunior wants to merge 1 commit into
OCA:16.0from
Escodoo:16.0-add-new-module-document_page_markdown

Conversation

@CristianoMafraJunior

Copy link
Copy Markdown
Member

Markdown in the Knowledge Base

Document Page Markdown (document_page_markdown) lets you write knowledge
base content in Markdown, the same way you write a pull request description on
GitHub: you type Markdown, check the formatted result in the Preview tab, and
insert it in the page.

Requirement: the markdown Python library must be installed on the server.
The module cannot be installed without it.


How to use it

1. Open the structure menu

Go to Knowledge > Pages, open or create a page, and type / in the page
content. Pick Markdown from the menu — it sits in the Structure section,
next to Bulleted list, Table, Separator, Code and the others.

Captura de tela 2026-10-19 154919

2. Write the Markdown

The Markdown box opens with two tabs, Write and Preview. You write in the
Write tab, either typing the syntax yourself or using the toolbar above the
field.

Captura de tela 2026-10-19 155004

Each toolbar button applies its syntax to the selection, or to the line the
cursor is on:

Button What it inserts
H / smaller H Heading (#) and subheading (##)
B / I / S Bold (**), italic (*), strikethrough (~~)
</> Inline code (backticks)
❞ Quote (>)
Lists Bulleted (-), numbered (1.) and checklist (- [ ])
🔗 Link ([text](url))
▦ Table (header plus separator row)
▬ Separator (---)

3. Check the Preview tab

The Preview tab shows the formatted text, exactly as it will look in the page.
It is rendered server side by the very same function that produces the inserted
content, so what you see in the preview is what gets inserted.

Captura de tela 2026-10-19 155010

4. Insert it in the page

Click INSERT. The formatted content is added at the cursor position, as
regular editor content. DISCARD closes the box without inserting anything.

From there, fill in the revision Name and Summary and save the page as usual.

Captura de tela 2026-10-19 155004

What you can write

On top of the basics (headings, lists, bold, italic, links, quotes), these
extensions are enabled:

  • Tables — | A | B | with a | --- | --- | row.
  • Fenced code blocks — triple backticks, with an optional language.
  • Footnotes, definition lists and abbreviations.
  • Single line breaks — one Enter is already a line break, no need for the two
    trailing spaces.
  • Admonitions (!!! note, !!! warning) for callouts.

Need another extension? You can add it without touching this module: inherit
document.page and extend the _markdown_extensions() method.


Good to know

What gets stored in the page is the rendered content, not the original
Markdown source. When you reopen the page, you edit it with the usual rich text
editor — Markdown is the way in, not the storage format.

In practice:

  • Revision history, version diffs, PDF printing and the approval workflow keep
    working exactly as before.
  • To rewrite a section in Markdown, use / → Markdown again and insert the new
    version in place of the old one.

Quick reference

  1. / in the page content → Markdown
  2. Write in the Write tab
  3. Check the Preview tab
  4. INSERT → save the page
Captura de tela 2026-10-19 155026

cc @etobella @rvalyi @marcelsavegnago @BhaveshHeliconia

@OCA-git-bot OCA-git-bot added series:16.0 mod:document_page_markdown Module document_page_markdown labels Oct 19, 2026
import markdown

from odoo import api, models

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
from odoo.tools import html_sanitize

"""Render a Markdown source into the HTML inserted in a page."""
if not source:
return ""
return markdown.markdown(source, extensions=self._markdown_extensions())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
return markdown.markdown(source, extensions=self._markdown_extensions())
html = markdown.markdown(source, extensions=self._markdown_extensions())
return html_sanitize(html)

Python's markdown library allows raw HTML by default. Without html_sanitize(), someone pasting <script> or will execute arbitrary JavaScript in the preview dialog and in the page (Stored XSS).



@tagged("post_install", "-at_install")
@tagged("post_install", "-at_install")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
@tagged("post_install", "-at_install")

duplicate code

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

Labels

mod:document_page_markdown Module document_page_markdown series:16.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants