PhoenixKitComments.Web.Markdown (PhoenixKitComments v0.4.0)

Copy Markdown View Source

Shared markdown rendering for comment content.

Comments are authored as markdown in the Leaf composer (which renders with MDEx); rendering with the same engine and render options on display keeps the two consistent. Output is sanitised by MDEx's allow-list for XSS protection. Used by both the public comments component and the admin moderation page so bold/italics/lists/etc. show formatted instead of raw.

Summary

Functions

Renders a comment's markdown content to sanitized HTML inside a pk-comment-md block. The .pk-comment-md class (styled by comment_markdown_styles/1) restores list/block spacing without depending on the @tailwindcss/typography (prose) plugin being present in the host — render comment_markdown_styles once on any page that uses this.

One-off <style> block with the .pk-comment-md rules. Render it ONCE per page that uses comment_markdown/1 (Tailwind's preflight zeroes list/block margins; this restores them without the typography plugin). Bold/italic render via <strong>/<em> already.

Renders markdown to sanitised HTML (or escaped text on a parse error). Blank input returns an empty string.

Functions

comment_markdown(assigns)

Renders a comment's markdown content to sanitized HTML inside a pk-comment-md block. The .pk-comment-md class (styled by comment_markdown_styles/1) restores list/block spacing without depending on the @tailwindcss/typography (prose) plugin being present in the host — render comment_markdown_styles once on any page that uses this.

Named comment_markdown (not markdown) to avoid clashing with core's PhoenixKitWeb.Components.Core.Markdown.markdown/1, which is imported wherever use PhoenixKitWeb is in play.

Attributes

  • content (:string) (required) - The markdown content to render.
  • class (:string) - Additional CSS classes. Defaults to "".
  • compact (:boolean) - Use smaller (text-sm) text for previews. Defaults to false.

comment_markdown_styles(assigns)

One-off <style> block with the .pk-comment-md rules. Render it ONCE per page that uses comment_markdown/1 (Tailwind's preflight zeroes list/block margins; this restores them without the typography plugin). Bold/italic render via <strong>/<em> already.

render_markdown(content)

Renders markdown to sanitised HTML (or escaped text on a parse error). Blank input returns an empty string.

Why sanitize: and not a regex pass afterwards

unsafe: true is what lets a comment contain real markdown-adjacent HTML, and it disables MDEx's own escaping — so everything downstream of it is the security boundary. That used to be a handful of regexes over the rendered string, which is a blocklist, and a blocklist over HTML loses:

  • &lt;script&gt;alert(1) with NO closing tag survived — the pattern required a matching &lt;/script&gt;.
  • &lt;a href=javascript:alert(1)&gt; survived — the pattern required the value to be quoted.

Both were verified against the real renderer, and both execute for every reader of a thread and again in the admin moderation list, which renders the same component. MDEx's :sanitize is ammonia, an allow-list: unknown tags and every attribute outside the allowed set are dropped rather than matched against, and it rewrites rel on links for free. There is no opt-out.