Files
jiang13-forum/templates/compose.tmpl
freefire 1f777eebb1 feat: Markdown 工具栏编辑器与服务端预览
共用 md_editor 于发帖/改帖/评论,扩展 ComposeBodyToHTML,并提供 /compose/preview。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 04:50:07 +08:00

106 lines
5.1 KiB
Cheetah
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{define "compose"}}
{{template "base/head" .}}
{{template "base/navbar" .}}
{{if .Flash}}<div class="j13-flash" role="status">{{.Flash}}</div>{{end}}
<main class="j13-main j13-main--solo j13-compose">
<h1>{{if .IsEdit}}编辑帖子{{else}}发帖{{end}}</h1>
{{template "base/alert" .}}
<form method="post" action="{{.FormAction}}" class="j13-form" id="compose-form" data-csrf="{{.CSRF}}" data-upload="/compose/upload">
<input type="hidden" name="_csrf" value="{{.CSRF}}"/>
<label>板块
<select name="board_id" required>
<option value="">请选择</option>
{{range .Boards}}
<option value="{{.ID}}" {{if eq $.BoardID .ID}}selected{{end}}>{{.Name}}</option>
{{end}}
</select>
</label>
{{if .IsEdit}}
<p class="j13-muted">类型:{{if eq .PostType "poll"}}投票{{else if eq .PostType "question"}}问答{{else if eq .PostType "bounty"}}悬赏{{else if eq .PostType "lottery"}}抽奖{{else}}普通讨论{{end}}(不可更改)</p>
<input type="hidden" name="post_type" value="{{.PostType}}"/>
{{else}}
<label>类型
<select name="post_type" id="compose-post-type">
<option value="normal"{{if or (eq .PostType "normal") (eq .PostType "")}} selected{{end}}>普通讨论</option>
<option value="question"{{if eq .PostType "question"}} selected{{end}}>问答</option>
<option value="poll"{{if eq .PostType "poll"}} selected{{end}}>投票</option>
<option value="bounty"{{if eq .PostType "bounty"}} selected{{end}}>悬赏</option>
<option value="lottery"{{if eq .PostType "lottery"}} selected{{end}}>抽奖</option>
</select>
</label>
<p class="j13-muted" id="compose-question-hint"{{if ne .PostType "question"}} hidden{{end}}>问答帖无额外字段;解决状态可在帖详情由作者或管理员切换。</p>
<fieldset class="j13-poll-fields" id="compose-poll-fields"{{if ne .PostType "poll"}} hidden{{end}}>
<legend>投票设置</legend>
<label class="j13-check"><input type="checkbox" name="poll_multi" value="1"{{if .PollMulti}} checked{{end}}/> 允许多选</label>
<label>最多可选
<input name="poll_max_choices" type="number" min="1" max="10" value="{{.PollMaxChoices}}"/>
</label>
<label>截止时间(可选)
<input name="poll_ends_at" type="datetime-local" value="{{.PollEndsAt}}"/>
</label>
<label>选项每行一项210 个)
<textarea name="poll_options" rows="6" placeholder="选项 A&#10;选项 B&#10;选项 C">{{.PollOptions}}</textarea>
</label>
</fieldset>
<fieldset class="j13-bounty-fields" id="compose-bounty-fields"{{if ne .PostType "bounty"}} hidden{{end}}>
<legend>悬赏设置</legend>
<p class="j13-muted">当前积分:{{.ViewerPoints}}。发帖时立即托管,采纳或退款前不可收回(有他人回复后作者不可自行退款)。</p>
<label>悬赏积分
<input name="bounty_points" type="number" min="1" value="{{.BountyPoints}}"/>
</label>
</fieldset>
<fieldset class="j13-lottery-fields" id="compose-lottery-fields"{{if ne .PostType "lottery"}} hidden{{end}}>
<legend>抽奖设置</legend>
<p class="j13-muted">参与者:已发布评论且非楼主(按用户去重)。人数足够后可由作者或管理员开奖。</p>
<label>中奖人数
<input name="lottery_winner_count" type="number" min="1" max="20" value="{{.LotteryWinners}}"/>
</label>
</fieldset>
{{end}}
<label>标题
<input name="title" required maxlength="{{.TitleMax}}" value="{{.Title}}"/>
</label>
<label>标签
<input name="tags" maxlength="{{.TagsMax}}" value="{{.Tags}}" placeholder="逗号分隔,可选"/>
</label>
<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">门控选中正文后点按钮包裹积分可见会询问价格19999。含门控时正文以 HTML 提交。Tab 缩进,可切换预览。</p>
<button type="submit">{{if .IsEdit}}保存{{else}}发布{{end}}</button>
</form>
</main>
{{template "base/footer" .}}
{{if not .IsEdit}}
<script>
(function () {
var sel = document.getElementById('compose-post-type');
var box = document.getElementById('compose-poll-fields');
var bounty = document.getElementById('compose-bounty-fields');
var lottery = document.getElementById('compose-lottery-fields');
var qHint = document.getElementById('compose-question-hint');
if (!sel) return;
function sync() {
if (box) box.hidden = sel.value !== 'poll';
if (bounty) bounty.hidden = sel.value !== 'bounty';
if (lottery) lottery.hidden = sel.value !== 'lottery';
if (qHint) qHint.hidden = sel.value !== 'question';
}
sel.addEventListener('change', sync);
sync();
})();
</script>
{{end}}
{{end}}