mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-07-04 02:32:50 +00:00
Reimplement editor
This commit is contained in:
parent
472aea92f8
commit
a9c72d91be
@ -16,6 +16,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
DescribeHyphaHerePattern = "Describe %s here"
|
||||||
WikiDir string
|
WikiDir string
|
||||||
TemplatesDir string
|
TemplatesDir string
|
||||||
configJsonPath string
|
configJsonPath string
|
||||||
|
54
fs/html.go
Normal file
54
fs/html.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package fs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gomarkdown/markdown"
|
||||||
|
"github.com/gomarkdown/markdown/html"
|
||||||
|
"github.com/gomarkdown/markdown/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func markdownToHtml(md string) string {
|
||||||
|
extensions := parser.CommonExtensions | parser.AutoHeadingIDs
|
||||||
|
p := parser.NewWithExtensions(extensions)
|
||||||
|
|
||||||
|
htmlFlags := html.CommonFlags | html.HrefTargetBlank
|
||||||
|
opts := html.RendererOptions{Flags: htmlFlags}
|
||||||
|
renderer := html.NewRenderer(opts)
|
||||||
|
|
||||||
|
return string(markdown.ToHTML([]byte(md), p, renderer))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Hypha) asHtml() (string, error) {
|
||||||
|
rev := h.actual
|
||||||
|
ret := `<article class="page">
|
||||||
|
<h1 class="page__title">` + rev.FullName + `</h1>
|
||||||
|
`
|
||||||
|
// What about using <figure>?
|
||||||
|
if h.hasBinaryData() {
|
||||||
|
ret += fmt.Sprintf(`<img src="/%s?action=binary&rev=%d" class="page__amnt"/>`, rev.FullName, rev.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
contents, err := ioutil.ReadFile(rev.TextPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to render", rev.FullName, ":", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: support more markups.
|
||||||
|
// TODO: support mycorrhiza extensions like transclusion.
|
||||||
|
switch rev.TextMime {
|
||||||
|
case "text/markdown":
|
||||||
|
html := markdown.ToHTML(contents, nil, nil)
|
||||||
|
ret += string(html)
|
||||||
|
default:
|
||||||
|
ret += fmt.Sprintf(`<pre>%s</pre>`, contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret += `
|
||||||
|
</article>`
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
60
fs/hypha.go
60
fs/hypha.go
@ -9,9 +9,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/bouncepaw/mycorrhiza/cfg"
|
"github.com/bouncepaw/mycorrhiza/cfg"
|
||||||
"github.com/gomarkdown/markdown"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Hypha struct {
|
type Hypha struct {
|
||||||
@ -27,6 +27,32 @@ func (h *Hypha) TextPath() string {
|
|||||||
return h.actual.TextPath
|
return h.actual.TextPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Hypha) TagsJoined() string {
|
||||||
|
if h.Exists {
|
||||||
|
return strings.Join(h.actual.Tags, ", ")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Hypha) TextMime() string {
|
||||||
|
if h.Exists {
|
||||||
|
return h.actual.TextMime
|
||||||
|
}
|
||||||
|
return "text/markdown"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Hypha) TextContent() string {
|
||||||
|
if h.Exists {
|
||||||
|
contents, err := ioutil.ReadFile(h.TextPath())
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Could not read", h.FullName)
|
||||||
|
return "Error: could not hypha text content file. It is recommended to cancel editing. Please contact the wiki admin. If you are the admin, see the logs."
|
||||||
|
}
|
||||||
|
return string(contents)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(cfg.DescribeHyphaHerePattern, h.FullName)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Storage) Open(name string) (*Hypha, error) {
|
func (s *Storage) Open(name string) (*Hypha, error) {
|
||||||
h := &Hypha{
|
h := &Hypha{
|
||||||
Exists: true,
|
Exists: true,
|
||||||
@ -123,38 +149,6 @@ func (h *Hypha) hasBinaryData() bool {
|
|||||||
return h.actual.BinaryMime != ""
|
return h.actual.BinaryMime != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Hypha) asHtml() (string, error) {
|
|
||||||
rev := h.actual
|
|
||||||
ret := `<article class="page">
|
|
||||||
<h1 class="page__title">` + rev.FullName + `</h1>
|
|
||||||
`
|
|
||||||
// What about using <figure>?
|
|
||||||
if h.hasBinaryData() {
|
|
||||||
ret += fmt.Sprintf(`<img src="/%s?action=binary&rev=%d" class="page__amnt"/>`, rev.FullName, rev.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
contents, err := ioutil.ReadFile(rev.TextPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("Failed to render", rev.FullName, ":", err)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: support more markups.
|
|
||||||
// TODO: support mycorrhiza extensions like transclusion.
|
|
||||||
switch rev.TextMime {
|
|
||||||
case "text/markdown":
|
|
||||||
html := markdown.ToHTML(contents, nil, nil)
|
|
||||||
ret += string(html)
|
|
||||||
default:
|
|
||||||
ret += fmt.Sprintf(`<pre>%s</pre>`, contents)
|
|
||||||
}
|
|
||||||
|
|
||||||
ret += `
|
|
||||||
</article>`
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActionRaw is used with `?action=raw`.
|
// ActionRaw is used with `?action=raw`.
|
||||||
// It writes text content of the revision without any parsing or rendering.
|
// It writes text content of the revision without any parsing or rendering.
|
||||||
func (h *Hypha) ActionRaw(w http.ResponseWriter) {
|
func (h *Hypha) ActionRaw(w http.ResponseWriter) {
|
||||||
|
16
handlers.go
16
handlers.go
@ -29,8 +29,6 @@ func HandlerBase(w http.ResponseWriter, rq *http.Request) (*fs.Hypha, bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println(*h)
|
|
||||||
return h, true
|
return h, true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,14 +58,20 @@ func HandlerView(w http.ResponseWriter, rq *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func HandlerEdit(w http.ResponseWriter, rq *http.Request) {
|
func HandlerEdit(w http.ResponseWriter, rq *http.Request) {
|
||||||
vars := mux.Vars(rq)
|
vars := mux.Vars(rq)
|
||||||
ActionEdit(vars["hypha"], w)
|
h, err := fs.Hs.Open(vars["hypha"])
|
||||||
|
// How could this happen?
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.OnRevision("0")
|
||||||
|
w.Header().Set("Content-Type", "text/html;charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte(render.HyphaEdit(h)))
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// makeTagsSlice turns strings like `"foo,, bar,kek"` to slice of strings that represent tag names. Whitespace around commas is insignificant.
|
// makeTagsSlice turns strings like `"foo,, bar,kek"` to slice of strings that represent tag names. Whitespace around commas is insignificant.
|
||||||
// Expected output for string above: []string{"foo", "bar", "kek"}
|
// Expected output for string above: []string{"foo", "bar", "kek"}
|
||||||
|
4
main.go
4
main.go
@ -63,10 +63,10 @@ func main() {
|
|||||||
r.Queries("action", "view").Path(cfg.HyphaUrl).
|
r.Queries("action", "view").Path(cfg.HyphaUrl).
|
||||||
HandlerFunc(HandlerView)
|
HandlerFunc(HandlerView)
|
||||||
|
|
||||||
/*
|
r.Queries("action", "edit").Path(cfg.HyphaUrl).
|
||||||
r.Queries("action", "edit").Path(hyphaUrl).
|
|
||||||
HandlerFunc(HandlerEdit)
|
HandlerFunc(HandlerEdit)
|
||||||
|
|
||||||
|
/*
|
||||||
r.Queries("action", "update").Path(hyphaUrl).Methods("POST").
|
r.Queries("action", "update").Path(hyphaUrl).Methods("POST").
|
||||||
HandlerFunc(HandlerUpdate)
|
HandlerFunc(HandlerUpdate)
|
||||||
*/
|
*/
|
||||||
|
@ -26,6 +26,21 @@ func EditHyphaPage(name, textMime, content, tags string) string {
|
|||||||
return renderBase(renderFromMap(page, "Hypha/edit/index.html"), keys)
|
return renderBase(renderFromMap(page, "Hypha/edit/index.html"), keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HyphaEdit(h *fs.Hypha) string {
|
||||||
|
page := map[string]string{
|
||||||
|
"Name": h.FullName,
|
||||||
|
"Tags": h.TagsJoined(),
|
||||||
|
"TextMime": h.TextMime(),
|
||||||
|
"Text": h.TextContent(),
|
||||||
|
}
|
||||||
|
keys := map[string]string{
|
||||||
|
"Title": fmt.Sprintf(cfg.TitleEditTemplate, h.FullName),
|
||||||
|
"Header": renderFromString(h.FullName, "Hypha/edit/header.html"),
|
||||||
|
"Sidebar": renderFromMap(page, "Hypha/edit/sidebar.html"),
|
||||||
|
}
|
||||||
|
return renderBase(renderFromMap(page, "Hypha/edit/index.html"), keys)
|
||||||
|
}
|
||||||
|
|
||||||
// Hypha404 returns 404 page for nonexistent page.
|
// Hypha404 returns 404 page for nonexistent page.
|
||||||
func Hypha404(name, _ string) string {
|
func Hypha404(name, _ string) string {
|
||||||
return HyphaGeneric(name, name, "Hypha/view/404.html")
|
return HyphaGeneric(name, name, "Hypha/view/404.html")
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"address": "127.0.0.1:1737",
|
"address": "127.0.0.1:1737",
|
||||||
"theme": "default-light",
|
"theme": "default-dark",
|
||||||
"site-title": "🍄 MycorrhizaWiki",
|
"site-title": "🍄 MycorrhizaWiki",
|
||||||
"title-templates": {
|
"title-templates": {
|
||||||
"edit-hypha": "Edit %s at MycorrhizaWiki",
|
"edit-hypha": "Edit %s at MycorrhizaWiki",
|
||||||
|
@ -9,8 +9,7 @@
|
|||||||
<h4 class="">Edit box</h4>
|
<h4 class="">Edit box</h4>
|
||||||
<!-- It is important that there is no indent ↓ -->
|
<!-- It is important that there is no indent ↓ -->
|
||||||
<textarea class="edit-box__text" name="text" cols="80" rows="25">
|
<textarea class="edit-box__text" name="text" cols="80" rows="25">
|
||||||
{{ .Text }}
|
{{ .Text }}</textarea>
|
||||||
</textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,34 +3,16 @@
|
|||||||
method="POST"
|
method="POST"
|
||||||
enctype="multipart/form-data"
|
enctype="multipart/form-data"
|
||||||
action="?action=update">
|
action="?action=update">
|
||||||
<div class="naviwrapper__buttons">
|
|
||||||
<input type="submit" value="update"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="edit-box__left">
|
<div class="edit-box__left">
|
||||||
<h4>Edit box</h4>
|
<h4>Edit box</h4>
|
||||||
<!-- It is important that there is no indent ↓ -->
|
<!-- It is important that there is no indent ↓ -->
|
||||||
<textarea class="edit-box__text" name="text" cols="80" rows="25">
|
<textarea class="edit-box__text" name="text" cols="80" rows="25">
|
||||||
{{ .Text }}
|
{{ .Text }}</textarea>
|
||||||
</textarea>
|
|
||||||
|
|
||||||
<h4>Upload file</h4>
|
<h4>Upload file</h4>
|
||||||
<p>If this hypha has a file like that, the text above is meant to be a description of it</p>
|
<p>If this hypha has a file like that, the text above is meant to be a description of it</p>
|
||||||
<input type="file" name="binary"/>
|
<input type="file" name="binary"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="edit-box__right">
|
|
||||||
<h4>Text MIME-type</h4>
|
|
||||||
<p>Good types are <code>text/markdown</code> and <code>text/plain</code></p>
|
|
||||||
<input type="text" name="text_mime" value="{{ .TextMime }}"/>
|
|
||||||
|
|
||||||
<h4>Revision comment</h4>
|
|
||||||
<p>Please make your comment helpful</p>
|
|
||||||
<input type="text" name="comment" value="Update {{ .Name }}"/>
|
|
||||||
|
|
||||||
<h4>Edit tags</h4>
|
|
||||||
<p>Tags are separated by commas, whitespace is ignored</p>
|
|
||||||
<input type="text" name="tags" value="{{ .Tags }}"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
19
w/m/Templates/default-light/Hypha/edit/sidebar.html/1.html
Normal file
19
w/m/Templates/default-light/Hypha/edit/sidebar.html/1.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<div style=""><h4>Text MIME-type</h4>
|
||||||
|
<p>Good types are <code>text/markdown</code> and <code>text/plain</code></p>
|
||||||
|
<input type="text" name="text_mime" value="{{ .TextMime }}"/>
|
||||||
|
|
||||||
|
<h4>Revision comment</h4>
|
||||||
|
<p>Please make your comment helpful</p>
|
||||||
|
<input type="text" name="comment" value="Update {{ .Name }}"/>
|
||||||
|
|
||||||
|
<h4>Edit tags</h4>
|
||||||
|
<p>Tags are separated by commas, whitespace is ignored</p>
|
||||||
|
<input type="text" name="tags" value="{{ .Tags }}"/>
|
||||||
|
|
||||||
|
<h4>Upload file</h4>
|
||||||
|
<p>If this hypha has a file like that, the text above is meant to be a description of it</p>
|
||||||
|
<input type="file" name="binary"/>
|
||||||
|
|
||||||
|
|
||||||
|
<p><input type="submit" value="update"/></p>
|
||||||
|
</div>
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"views": 0,
|
||||||
|
"deleted": false,
|
||||||
|
"revisions": {
|
||||||
|
"1": {
|
||||||
|
"tags": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"name": "sidebar.html",
|
||||||
|
"comment": "Create Templates/default-dark/Hypha/edit/sidebar.html",
|
||||||
|
"author": "",
|
||||||
|
"time": 1593003792,
|
||||||
|
"text_mime": "text/html",
|
||||||
|
"binary_mime": "",
|
||||||
|
"text_name": "1.html",
|
||||||
|
"binary_name": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user