feat: Markdown 工具栏编辑器与服务端预览
共用 md_editor 于发帖/改帖/评论,扩展 ComposeBodyToHTML,并提供 /compose/preview。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -63,20 +63,21 @@
|
||||
<label>标签
|
||||
<input name="tags" maxlength="{{.TagsMax}}" value="{{.Tags}}" placeholder="逗号分隔,可选"/>
|
||||
</label>
|
||||
<label>正文
|
||||
<textarea name="content" id="compose-content" rows="16" required maxlength="{{.ContentMax}}" placeholder="支持纯文本;图片上传后插入 Markdown 图片语法">{{.Content}}</textarea>
|
||||
</label>
|
||||
<div class="j13-compose__tools">
|
||||
<label class="j13-btn-secondary j13-filebtn">
|
||||
插入图片
|
||||
<input type="file" id="compose-image" accept="image/*" hidden/>
|
||||
</label>
|
||||
<button type="button" class="j13-btn-secondary" id="compose-gate-login" data-gate="login">登录可见</button>
|
||||
<button type="button" class="j13-btn-secondary" id="compose-gate-reply" data-gate="reply">回复可见</button>
|
||||
<button type="button" class="j13-btn-secondary" id="compose-gate-points" data-gate="points">积分可见</button>
|
||||
<span class="j13-muted" id="compose-upload-status"></span>
|
||||
</div>
|
||||
<p class="j13-muted">门控:选中正文后点按钮包裹;积分可见会询问价格(1–9999)。含门控时正文以 HTML 提交。</p>
|
||||
<label>正文</label>
|
||||
{{template "shared/md_editor" (dict
|
||||
"Name" "content"
|
||||
"ID" "compose-content"
|
||||
"Content" .Content
|
||||
"Rows" 16
|
||||
"MaxLength" .ContentMax
|
||||
"Placeholder" "支持 Markdown:标题/粗斜体/列表/代码块/链接;可用工具栏插入图片与门控块"
|
||||
"CSRF" .CSRF
|
||||
"ShowGates" 1
|
||||
"ShowUpload" 1
|
||||
"Unsaved" 1
|
||||
"Required" 1
|
||||
)}}
|
||||
<p class="j13-muted">门控:选中正文后点按钮包裹;积分可见会询问价格(1–9999)。含门控时正文以 HTML 提交。Tab 缩进,可切换预览。</p>
|
||||
<button type="submit">{{if .IsEdit}}保存{{else}}发布{{end}}</button>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
@@ -218,7 +218,19 @@
|
||||
<input type="hidden" name="reply_to" id="comment-reply-to" value=""/>
|
||||
<p class="j13-muted j13-comment-reply-hint" id="comment-reply-hint" hidden></p>
|
||||
<label for="comment-content">发表评论</label>
|
||||
<textarea id="comment-content" name="content" rows="4" required maxlength="8000"></textarea>
|
||||
{{template "shared/md_editor" (dict
|
||||
"Name" "content"
|
||||
"ID" "comment-content"
|
||||
"Content" ""
|
||||
"Rows" 5
|
||||
"MaxLength" 8000
|
||||
"Placeholder" "支持 Markdown;可回复楼上"
|
||||
"CSRF" .CSRF
|
||||
"ShowGates" 0
|
||||
"ShowUpload" 1
|
||||
"Unsaved" 0
|
||||
"Required" 1
|
||||
)}}
|
||||
<label class="j13-check">
|
||||
<input type="checkbox" name="is_private" value="1"/>
|
||||
私密评论(仅相关可见)
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
<form method="post" action="/post/{{.PostID}}/comments/{{.CommentID}}/edit" class="j13-form j13-comment-form">
|
||||
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
|
||||
<label for="comment-edit-content">内容</label>
|
||||
<textarea id="comment-edit-content" name="content" rows="6" required maxlength="8000">{{.Content}}</textarea>
|
||||
{{template "shared/md_editor" (dict
|
||||
"Name" "content"
|
||||
"ID" "comment-edit-content"
|
||||
"Content" .Content
|
||||
"Rows" 8
|
||||
"MaxLength" 8000
|
||||
"Placeholder" "支持 Markdown"
|
||||
"CSRF" .CSRF
|
||||
"ShowGates" 0
|
||||
"ShowUpload" 1
|
||||
"Unsaved" 1
|
||||
"Required" 1
|
||||
)}}
|
||||
<div class="j13-form__row">
|
||||
<button type="submit">保存</button>
|
||||
<a class="j13-btn-secondary" href="/post/{{.PostID}}#floor-{{.Floor}}">取消</a>
|
||||
|
||||
52
templates/shared/md_editor.tmpl
Normal file
52
templates/shared/md_editor.tmpl
Normal file
@@ -0,0 +1,52 @@
|
||||
{{define "shared/md_editor"}}
|
||||
{{/* 期望:.Name .ID .Content .Rows .MaxLength .Placeholder .CSRF .ShowGates .ShowUpload .Unsaved .Required */}}
|
||||
<div class="j13-md-editor"
|
||||
data-j13-md-editor
|
||||
data-csrf="{{.CSRF}}"
|
||||
data-upload="/compose/upload"
|
||||
data-preview="/compose/preview"
|
||||
data-gates="{{if .ShowGates}}1{{else}}0{{end}}"
|
||||
data-upload-enabled="{{if .ShowUpload}}1{{else}}0{{end}}"
|
||||
data-unsaved="{{if .Unsaved}}1{{else}}0{{end}}">
|
||||
<div class="j13-md-editor__toolbar" role="toolbar" aria-label="Markdown 工具栏">
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="bold" title="粗体">B</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="italic" title="斜体"><em>I</em></button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="strike" title="删除线"><s>S</s></button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="code" title="行内代码"></></button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="link" title="链接">链接</button>
|
||||
<span class="j13-md-editor__sep" aria-hidden="true"></span>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="h2" title="标题 2">H2</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="h3" title="标题 3">H3</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="ul" title="无序列表">• 列表</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="ol" title="有序列表">1. 列表</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="quote" title="引用">引用</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="fence" title="代码块">代码块</button>
|
||||
{{if .ShowUpload}}
|
||||
<span class="j13-md-editor__sep" aria-hidden="true"></span>
|
||||
<label class="j13-md-editor__btn j13-md-editor__filebtn">
|
||||
图片
|
||||
<input type="file" accept="image/*" data-md-upload hidden/>
|
||||
</label>
|
||||
{{end}}
|
||||
{{if .ShowGates}}
|
||||
<span class="j13-md-editor__sep" aria-hidden="true"></span>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="gate-login">登录可见</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="gate-reply">回复可见</button>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="gate-points">积分可见</button>
|
||||
{{end}}
|
||||
<span class="j13-md-editor__sep" aria-hidden="true"></span>
|
||||
<button type="button" class="j13-md-editor__btn" data-md-cmd="preview" data-md-preview-toggle>预览</button>
|
||||
</div>
|
||||
<textarea
|
||||
name="{{.Name}}"
|
||||
id="{{.ID}}"
|
||||
class="j13-md-editor__input"
|
||||
rows="{{.Rows}}"
|
||||
{{if .Required}}required{{end}}
|
||||
{{if .MaxLength}}maxlength="{{.MaxLength}}"{{end}}
|
||||
placeholder="{{.Placeholder}}"
|
||||
data-md-input>{{.Content}}</textarea>
|
||||
<div class="j13-md-editor__preview j13-post__body" data-md-preview hidden></div>
|
||||
<p class="j13-muted j13-md-editor__status" data-md-status></p>
|
||||
</div>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user