ACE Code Editor for Pages and Blogs
This commit is contained in:
parent
d8254826c2
commit
9e58456aaa
|
@ -20,11 +20,11 @@ import (
|
|||
|
||||
// AdminRoutes attaches the admin routes to the app.
|
||||
func (b *Blog) AdminRoutes(r *mux.Router) {
|
||||
adminRouter := mux.NewRouter().PathPrefix("/admin").Subrouter().StrictSlash(false)
|
||||
r.HandleFunc("/admin", b.AdminHandler) // so as to not be "/admin/"
|
||||
adminRouter := mux.NewRouter().PathPrefix("/admin").Subrouter().StrictSlash(true)
|
||||
adminRouter.HandleFunc("/", b.AdminHandler)
|
||||
adminRouter.HandleFunc("/settings", b.SettingsHandler)
|
||||
adminRouter.HandleFunc("/editor", b.EditorHandler)
|
||||
adminRouter.PathPrefix("/").HandlerFunc(b.PageHandler)
|
||||
// r.HandleFunc("/admin", b.AdminHandler)
|
||||
r.PathPrefix("/admin").Handler(negroni.New(
|
||||
negroni.HandlerFunc(b.LoginRequired),
|
||||
negroni.Wrap(adminRouter),
|
||||
|
|
|
@ -58,8 +58,9 @@ func (b *Blog) PageHandler(w http.ResponseWriter, r *http.Request) {
|
|||
title, _ := TitleFromMarkdown(body)
|
||||
|
||||
b.RenderTemplate(w, r, ".markdown", NewVars(map[interface{}]interface{}{
|
||||
"Title": title,
|
||||
"HTML": template.HTML(html),
|
||||
"Title": title,
|
||||
"HTML": template.HTML(html),
|
||||
"MarkdownFile": filepath.URI,
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
|
||||
{{ if and .CurrentUser.Admin .Editable }}
|
||||
<p class="mt-4">
|
||||
<strong>Admin:</strong> [<a href="/admin/editor?file={{ TemplateName }}">edit this page</a>]
|
||||
<strong>Admin:</strong> [<a href="/admin/editor?file={{ or .Data.MarkdownFile TemplateName }}">edit this page</a>]
|
||||
</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
@ -197,7 +197,6 @@
|
|||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
|
||||
{{ template "scripts" or "" }}
|
||||
|
||||
</body>
|
||||
|
|
|
@ -9,6 +9,25 @@
|
|||
</p>
|
||||
{{ 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;
|
||||
}
|
||||
#ace-buttons {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<form action="/admin/editor" method="POST">
|
||||
<input type="hidden" name="_csrf" value="{{ .CSRF }}">
|
||||
<input type="hidden" name="save" value="true">
|
||||
|
@ -31,6 +50,18 @@
|
|||
<label for="body">
|
||||
Content:
|
||||
</label>
|
||||
<div id="editor-box">
|
||||
<div id="ace-editor">{{ .Data.Body }}</div>
|
||||
</div>
|
||||
|
||||
<div id="ace-buttons">
|
||||
Syntax:
|
||||
<a href="#" onClick="return setSyntax('html')" class="btn btn-secondary btn-sm">HTML</a>
|
||||
<a href="#" onClick="return setSyntax('markdown')" class="btn btn-secondary btn-sm">Markdown</a>
|
||||
<a href="#" onClick="return setSyntax('javascript')" class="btn btn-secondary btn-sm">JS</a>
|
||||
<a href="#" onClick="return setSyntax('css')" class="btn btn-secondary btn-sm">CSS</a>
|
||||
<a href="#" onClick="return setSyntax('text')" class="btn btn-secondary btn-sm">None</a>
|
||||
</div>
|
||||
<textarea
|
||||
cols="40"
|
||||
rows="12"
|
||||
|
@ -45,4 +76,49 @@
|
|||
<button type="submit" name="action" value="delete" class="btn btn-danger" onClick="return window.confirm('Are you sure?')">Delete Page</button>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<script src="/js/ace-editor/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
var ACE;
|
||||
(function() {
|
||||
var editor = ace.edit("ace-editor");
|
||||
ACE = editor;
|
||||
document.querySelector("#editor-box").style.display = "block";
|
||||
document.querySelector("#ace-buttons").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(true);
|
||||
|
||||
// On save.
|
||||
ses.on("change", function() {
|
||||
document.getElementById("body").value = editor.getValue();
|
||||
});
|
||||
|
||||
var filename = "{{ .Data.File }}";
|
||||
var parts = filename.split(".");
|
||||
var ext = parts.pop().toLowerCase();
|
||||
if (ext === "js") {
|
||||
ses.setMode("ace/mode/javascript");
|
||||
} else if (ext === "gohtml" || ext === "html") {
|
||||
ses.setMode("ace/mode/html");
|
||||
} else if (ext === "md" || ext === "markdown") {
|
||||
ses.setMode("ace/mode/markdown");
|
||||
ses.setTabSize(2);
|
||||
} else if (ext === "css") {
|
||||
ses.setMode("ace/mode/css");
|
||||
}
|
||||
})();
|
||||
|
||||
function setSyntax(lang) {
|
||||
if (typeof(ACE) !== undefined) {
|
||||
ACE.getSession().setMode("ace/mode/"+lang);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
{{ end }}
|
||||
|
|
|
@ -13,6 +13,22 @@
|
|||
</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">
|
||||
|
@ -52,6 +68,7 @@
|
|||
class="form-check-input"
|
||||
name="content-type"
|
||||
value="markdown"
|
||||
onChange="setSyntax(this.value)"
|
||||
{{ if eq .ContentType "markdown" }}checked{{ end }}
|
||||
> Markdown
|
||||
</label>
|
||||
|
@ -62,15 +79,21 @@
|
|||
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>
|
||||
|
||||
|
@ -137,4 +160,38 @@
|
|||
{{ end }}
|
||||
|
||||
</form>
|
||||
|
||||
<script src="/js/ace-editor/src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script>
|
||||
var ACE;
|
||||
(function() {
|
||||
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(true);
|
||||
|
||||
// On save.
|
||||
ses.on("change", function() {
|
||||
document.getElementById("body").value = editor.getValue();
|
||||
});
|
||||
|
||||
setSyntax("markdown");
|
||||
})();
|
||||
|
||||
function setSyntax(lang) {
|
||||
if (typeof(ACE) !== undefined) {
|
||||
ACE.getSession().setMode("ace/mode/"+lang);
|
||||
if (lang === "markdown") {
|
||||
ACE.getSession().setTabSize(2);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
|
|
Loading…
Reference in New Issue
Block a user