263 lines
8.1 KiB
Plaintext
263 lines
8.1 KiB
Plaintext
{{ define "title" }}Update Blog{{ end }}
|
|
{{ define "content" }}
|
|
<form name="blog-edit" action="/blog/edit" method="POST">
|
|
<input type="hidden" name="_csrf" value="{{ .CSRF }}">
|
|
{{ if .Data.preview }}
|
|
<div class="card mb-5">
|
|
<div class="card-header">
|
|
Preview
|
|
</div>
|
|
<div class="card-body">
|
|
<h1 class="blog-title">{{ .Data.post.Title }}</h1>
|
|
|
|
{{ .Data.preview }}
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
|
|
<style type="text/css" media="screen">
|
|
#editor-box {
|
|
position: relative;
|
|
display: none;
|
|
width: 100%;
|
|
height: 500px;
|
|
}
|
|
#ace-editor {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
}
|
|
</style>
|
|
|
|
{{ with .Data.post }}
|
|
<input type="hidden" name="id" value="{{ .ID }}">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<h3>Update Blog</h3>
|
|
|
|
<div class="form-group">
|
|
<label for="title">Title</label>
|
|
<input type="text"
|
|
class="form-control"
|
|
name="title"
|
|
value="{{ .Title }}"
|
|
placeholder="Post Title"
|
|
autocomplete="off">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="fragment">URL Fragment</label>
|
|
<small class="text-muted">
|
|
You can leave this blank if this is a new post. It will pick a
|
|
default value based on the title.
|
|
</small>
|
|
<input type="text"
|
|
class="form-control"
|
|
name="fragment"
|
|
value="{{ .Fragment }}"
|
|
placeholder="url-fragment-for-blog-entry"
|
|
autocomplete="false">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="body">Body</label>
|
|
|
|
<div class="form-check form-check-inline">
|
|
<label class="form-check-label">
|
|
<input type="radio"
|
|
class="form-check-input"
|
|
name="content-type"
|
|
value="markdown"
|
|
onChange="setSyntax(this.value)"
|
|
{{ if eq .ContentType "markdown" }}checked{{ end }}
|
|
> Markdown
|
|
</label>
|
|
</div>
|
|
<div class="form-check form-check-inline">
|
|
<label class="form-check-label">
|
|
<input type="radio"
|
|
class="form-check-input"
|
|
name="content-type"
|
|
value="html"
|
|
onChange="setSyntax(this.value)"
|
|
{{ if eq .ContentType "html" }}checked{{ end }}
|
|
> Raw HTML
|
|
</label>
|
|
</div>
|
|
|
|
<div id="editor-box">
|
|
<div id="ace-editor">{{ .Body }}</div>
|
|
</div>
|
|
|
|
<textarea class="form-control"
|
|
cols="80"
|
|
rows="12"
|
|
name="body"
|
|
id="body"
|
|
placeholder="Post body goes here">{{ .Body }}</textarea>
|
|
|
|
<div class="mt-2">
|
|
<button id="ace-toggle-button" type="button" class="btn btn-sm btn-secondary">
|
|
Toggle Rich Code Editor
|
|
</button>
|
|
|
|
<span class="ml-2">Attach a file:</span>
|
|
<input type="file" id="attach-file-button" onChange="uploadFile()">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="tags">Tags</label>
|
|
<input type="text"
|
|
class="form-control"
|
|
name="tags"
|
|
placeholder="Comma, Separated, List"
|
|
value="{{ StringsJoin .Tags ", " }}"
|
|
autocomplete="off">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="privacy">Privacy</label>
|
|
<select name="privacy" class="form-control">
|
|
<option value="public"{{ if eq .Privacy "public" }} selected{{ end }}>Public: everybody can see this post</option>
|
|
<option value="private"{{ if eq .Privacy "private" }} selected{{ end }}>Private: only site admins can see this post</option>
|
|
<option value="unlisted"{{ if eq .Privacy "unlisted" }} selected{{ end }}>Unlisted: only those with the direct link can see it</option>
|
|
<option value="draft"{{ if eq .Privacy "draft" }} selected{{ end }}>Draft: don't show this post on the blog anywhere</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Options</label>
|
|
<div class="form-check">
|
|
<label class="form-check-label">
|
|
<input type="checkbox"
|
|
class="form-check-label"
|
|
name="sticky"
|
|
value="true"
|
|
{{ if .Sticky }}checked{{ end }}
|
|
> Make this post sticky (always on top)
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<label class="form-check-label">
|
|
<input type="checkbox"
|
|
class="form-check-label"
|
|
name="enable-comments"
|
|
value="true"
|
|
{{ if .EnableComments }}checked{{ end }}
|
|
> Enable comments on this post
|
|
</label>
|
|
</div>
|
|
{{ if .ID }}
|
|
<div class="form-check">
|
|
<label class="form-check-label">
|
|
<input type="checkbox"
|
|
class="form-check-label"
|
|
name="no-update"
|
|
value="true"
|
|
> <strong>Editing:</strong> do not show a "last updated" label.
|
|
</label>
|
|
</div>
|
|
{{ end }}
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<button type="submit"
|
|
class="btn btn-success"
|
|
name="submit"
|
|
value="preview">
|
|
Preview
|
|
</button>
|
|
<button type="submit"
|
|
class="btn btn-primary"
|
|
name="submit"
|
|
value="post">
|
|
Publish
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{ end }}
|
|
|
|
</form>
|
|
|
|
<script src="/js/ace-toggle.js"></script>
|
|
<script src="/js/ace-editor/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
|
|
<script>
|
|
var ACE;
|
|
(function() {
|
|
if (DISABLE_ACE_EDITOR) {
|
|
return;
|
|
}
|
|
|
|
var editor = ace.edit("ace-editor");
|
|
ACE = editor;
|
|
document.querySelector("#editor-box").style.display = "block";
|
|
document.querySelector("#body").style.display = "none";
|
|
|
|
// Default editor settings
|
|
editor.setTheme("ace/theme/monokai");
|
|
var ses = editor.getSession();
|
|
ses.setTabSize(4);
|
|
ses.setUseSoftTabs(false);
|
|
ses.setUseWrapMode(true);
|
|
|
|
// On save.
|
|
ses.on("change", function() {
|
|
document.getElementById("body").value = editor.getValue();
|
|
});
|
|
|
|
setSyntax("markdown");
|
|
})();
|
|
|
|
function uploadFile() {
|
|
let $input = document.querySelector("#attach-file-button");
|
|
let syntax = document.querySelector("input[name='content-type']:checked").value;
|
|
let file = $input.files[0];
|
|
|
|
var data = new FormData();
|
|
data.append("file", file);
|
|
data.append("_csrf", "{{ .CSRF }}");
|
|
|
|
fetch("/admin/upload", {
|
|
method: "POST",
|
|
body: data,
|
|
credentials: "same-origin",
|
|
cache: "no-cache"
|
|
}).then(resp => resp.json()).then(resp => {
|
|
if (!resp.success) {
|
|
window.alert(resp.error);
|
|
return;
|
|
}
|
|
|
|
let filename = resp.filename;
|
|
let uri = resp.uri;
|
|
let insert = `![${filename}](${uri})\n`;
|
|
if (syntax === "html") {
|
|
insert = `<img alt="${filename}" src="${uri}" class="portrait">\n`;
|
|
}
|
|
|
|
if (DISABLE_ACE_EDITOR) {
|
|
document.querySelector("#body").value += insert;
|
|
} else {
|
|
ACE.insert(insert);
|
|
}
|
|
|
|
$input.value = "";
|
|
});
|
|
}
|
|
|
|
function setSyntax(lang) {
|
|
if (typeof(ACE) !== undefined) {
|
|
ACE.getSession().setMode("ace/mode/"+lang);
|
|
if (lang === "markdown") {
|
|
ACE.getSession().setTabSize(2);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
</script>
|
|
{{ end }}
|