journal: real markdown editor (EasyMDE) with live preview toggle, fix default template
- Replace the plain textarea with EasyMDE (vendored locally, no CDN) for markdown authoring: syntax highlighting, smart list continuation, and a custom text-based toolbar (built-in EasyMDE toolbar icons require Font Awesome from a CDN, which this app doesn't use). unorderedListStyle is set to "-" to match the app's own template convention. - Add a preview/edit toggle button that swaps the editor for the exact same server-rendered markdown (via /journal/preview) shown after saving, instead of always showing both. - Fix create/edit entry routes to verify the submitted category_id actually belongs to the current user before inserting -- every other write path in this app already checked ownership; this one didn't (found while manually testing the new editor with a typo'd category id that happened to belong to someone else's category, which surfaced as an IntegrityError 500 instead of a clean 404-equivalent). - Fix the default "일상" category template: bare "-" bullet lines don't parse as list items in the markdown renderer (they need a trailing space), and the content_template validator was silently stripping that trailing space off on every save. Backfill migration updates any category still holding the old, broken template text. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
import bleach
|
||||
import markdown
|
||||
from markupsafe import Markup
|
||||
|
||||
# nl2br: 빈 줄 없이 그냥 엔터만 쳐도 줄바꿈되게 한다 — 지금까지 백엔드가 순수 텍스트를
|
||||
# white-space: pre-wrap으로 보여주던 것과 체감이 최대한 비슷하도록.
|
||||
_MARKDOWN_EXTENSIONS = ["nl2br", "sane_lists"]
|
||||
|
||||
_ALLOWED_TAGS = [
|
||||
"p", "br", "strong", "em", "del",
|
||||
"h1", "h2", "h3", "h4",
|
||||
"ul", "ol", "li",
|
||||
"blockquote", "code", "pre", "hr", "a",
|
||||
]
|
||||
_ALLOWED_ATTRS = {"a": ["href", "title"]}
|
||||
|
||||
|
||||
def render_markdown(text: str) -> Markup:
|
||||
"""저널 기록 내용을 마크다운 HTML로 렌더링한다. markdown 라이브러리는 기본적으로 원본 HTML을
|
||||
그대로 통과시키므로(<script> 등 포함) bleach로 허용 태그만 남기고 나머지는 전부 지운다 —
|
||||
이 함수가 반환하는 Markup만 템플릿에서 이스케이프 없이(그대로 안전하게) 렌더링해야 한다."""
|
||||
html = markdown.markdown(text, extensions=_MARKDOWN_EXTENSIONS)
|
||||
return Markup(bleach.clean(html, tags=_ALLOWED_TAGS, attributes=_ALLOWED_ATTRS, strip=True))
|
||||
Reference in New Issue
Block a user