共用 md_editor 于发帖/改帖/评论,扩展 ComposeBodyToHTML,并提供 /compose/preview。 Co-authored-by: Cursor <cursoragent@cursor.com>
106 lines
5.1 KiB
Cheetah
106 lines
5.1 KiB
Cheetah
{{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>选项(每行一项,2–10 个)
|
||
<textarea name="poll_options" rows="6" placeholder="选项 A 选项 B 选项 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">门控:选中正文后点按钮包裹;积分可见会询问价格(1–9999)。含门控时正文以 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}}
|