diff --git a/categories/view_card.html b/categories/view_card.html
index f2ea7c8..e69de29 100644
--- a/categories/view_card.html
+++ b/categories/view_card.html
@@ -1,37 +0,0 @@
-{{define "category card"}}
-{{if or .GivenPermissionToModify (len .Categories)}}
- {{$hyphaName := .HyphaName}}
- {{$givenPermission := .GivenPermissionToModify}}
-
-{{end}}{{end}}
\ No newline at end of file
diff --git a/hypview/hypview.go b/hypview/hypview.go
index 55d5763..5ec43f1 100644
--- a/hypview/hypview.go
+++ b/hypview/hypview.go
@@ -4,7 +4,7 @@ import (
"embed"
"github.com/bouncepaw/mycorrhiza/internal/backlinks"
"github.com/bouncepaw/mycorrhiza/internal/cfg"
- viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
+ "github.com/bouncepaw/mycorrhiza/web/viewutil"
"html/template"
"log"
"strings"
@@ -14,57 +14,6 @@ var (
//go:embed *.html
fs embed.FS
ruTranslation = `
-{{define "editing hypha"}}Редактирование {{beautifulName .}}{{end}}
-{{define "editing [[hypha]]"}}Редактирование {{beautifulName .}}{{end}}
-{{define "creating [[hypha]]"}}Создание {{beautifulName .}}{{end}}
-{{define "you're creating a new hypha"}}Вы создаёте новую гифу.{{end}}
-{{define "describe your changes"}}Опишите ваши правки{{end}}
-{{define "save"}}Сохранить{{end}}
-{{define "preview"}}Предпросмотр{{end}}
-{{define "previewing hypha"}}Предпросмотр «{{beautifulName .}}»{{end}}
-{{define "preview tip"}}Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:{{end}}
-
-{{define "markup"}}Разметка{{end}}
-{{define "link"}}Ссылка{{end}}
-{{define "link title"}}Текст{{end}}
-{{define "heading"}}Заголовок{{end}}
-{{define "bold"}}Жирный{{end}}
-{{define "italic"}}Курсив{{end}}
-{{define "highlight"}}Выделение{{end}}
-{{define "underline"}}Подчеркивание{{end}}
-{{define "mono"}}Моноширинный{{end}}
-{{define "super"}}Надстрочный{{end}}
-{{define "sub"}}Подстрочный{{end}}
-{{define "strike"}}Зачёркнутый{{end}}
-{{define "rocket"}}Ссылка-ракета{{end}}
-{{define "transclude"}}Трансклюзия{{end}}
-{{define "hr"}}Гориз. черта{{end}}
-{{define "code"}}Код-блок{{end}}
-{{define "bullets"}}Маркир. список{{end}}
-{{define "numbers"}}Нумер. список{{end}}
-{{define "mycomarkup help"}}Подробнее о Микоразметке{{end}}
-{{define "actions"}}Действия{{end}}
-{{define "current date"}}Текущая дата{{end}}
-{{define "current time"}}Текущее время{{end}}
-{{define "selflink"}}Ссылка на вас{{end}}
-
-{{define "empty heading"}}Эта гифа не существует{{end}}
-{{define "empty no rights"}}У вас нет прав для создания новых гиф. Вы можете:{{end}}
-{{define "empty log in"}}Войти в свою учётную запись, если она у вас есть{{end}}
-{{define "empty register"}}Создать новую учётную запись{{end}}
-{{define "write a text"}}Написать текст{{end}}
-{{define "write a text tip"}}Напишите заметку, дневник, статью, рассказ или иной текст с помощью Микоразметки. Сохраняется полная история правок документа.{{end}}
-{{define "write a text writing conventions"}}Не забывайте следовать правилам оформления этой вики, если они имеются.{{end}}
-{{define "write a text btn"}}Создать{{end}}
-{{define "upload a media"}}Загрузить медиа{{end}}
-{{define "upload a media tip"}}Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.{{end}}
-{{define "upload a media btn"}}Загрузить{{end}}
-
-{{define "delete hypha?"}}Удалить {{beautifulName .}}?{{end}}
-{{define "delete [[hypha]]?"}}Удалить {{beautifulName .}}?{{end}}
-{{define "want to delete?"}}Вы действительно хотите удалить эту гифу?{{end}}
-{{define "delete tip"}}Нельзя отменить удаление гифы, но её история останется доступной.{{end}}
-
{{define "rename hypha?"}}Переименовать {{beautifulName .}}?{{end}}
{{define "rename [[hypha]]?"}}Переименовать {{beautifulName .}}?{{end}}
{{define "new name"}}Новое название:{{end}}
@@ -72,59 +21,26 @@ var (
{{define "rename tip"}}Переименовывайте аккуратно. Документация на английском.{{end}}
{{define "leave redirection"}}Оставить перенаправление{{end}}
-{{define "remove media from x?"}}Убрать медиа у {{beautifulName .}}?{{end}}
-{{define "remove media from [[x]]?"}}Убрать медиа у {{beautifulName .MatchedHyphaName}}?{{end}}
-{{define "remove media for real?"}}Вы точно хотите убрать медиа у гифы «{{beautifulName .MatchedHyphaName}}»?{{end}}
+
`
- chainNaviTitle viewutil2.Chain
- chainEditHypha viewutil2.Chain
- chainEmptyHypha viewutil2.Chain
- chainDeleteHypha viewutil2.Chain
- chainRenameHypha viewutil2.Chain
- chainRemoveMedia viewutil2.Chain
+ chainNaviTitle viewutil.Chain
+ chainRenameHypha viewutil.Chain
)
func Init() {
- chainNaviTitle = viewutil2.CopyEnRuWith(fs, "view_navititle.html", "")
- chainEditHypha = viewutil2.CopyEnRuWith(fs, "view_edit.html", ruTranslation)
- chainEmptyHypha = viewutil2.CopyEnRuWith(fs, "view_empty_hypha.html", ruTranslation)
- chainDeleteHypha = viewutil2.CopyEnRuWith(fs, "view_delete.html", ruTranslation)
- chainRenameHypha = viewutil2.CopyEnRuWith(fs, "view_rename.html", ruTranslation)
- chainRemoveMedia = viewutil2.CopyEnRuWith(fs, "view_remove_media.html", ruTranslation)
-}
-
-type editData struct {
- *viewutil2.BaseData
- HyphaName string
- IsNew bool
- Content string
- Message string
- Preview template.HTML
-}
-
-func EditHypha(meta viewutil2.Meta, hyphaName string, isNew bool, content string, message string, preview template.HTML) {
- viewutil2.ExecutePage(meta, chainEditHypha, editData{
- BaseData: &viewutil2.BaseData{
- Addr: "/edit/" + hyphaName,
- EditScripts: cfg.EditScripts,
- },
- HyphaName: hyphaName,
- IsNew: isNew,
- Content: content,
- Message: message,
- Preview: preview,
- })
+ chainNaviTitle = viewutil.CopyEnRuWith(fs, "view_navititle.html", "")
+ chainRenameHypha = viewutil.CopyEnRuWith(fs, "view_rename.html", ruTranslation)
}
type renameData struct {
- *viewutil2.BaseData
+ *viewutil.BaseData
HyphaName string
LeaveRedirectionDefault bool
}
-func RenameHypha(meta viewutil2.Meta, hyphaName string) {
- viewutil2.ExecutePage(meta, chainRenameHypha, renameData{
- BaseData: &viewutil2.BaseData{
+func RenameHypha(meta viewutil.Meta, hyphaName string) {
+ viewutil.ExecutePage(meta, chainRenameHypha, renameData{
+ BaseData: &viewutil.BaseData{
Addr: "/rename/" + hyphaName,
},
HyphaName: hyphaName,
@@ -132,37 +48,14 @@ func RenameHypha(meta viewutil2.Meta, hyphaName string) {
})
}
-type deleteRemoveMediaData struct {
- *viewutil2.BaseData
- HyphaName string
-}
-
-func DeleteHypha(meta viewutil2.Meta, hyphaName string) {
- viewutil2.ExecutePage(meta, chainDeleteHypha, deleteRemoveMediaData{
- BaseData: &viewutil2.BaseData{
- Addr: "/delete/" + hyphaName,
- },
- HyphaName: hyphaName,
- })
-}
-
-func RemoveMedia(meta viewutil2.Meta, hyphaName string) {
- viewutil2.ExecutePage(meta, chainRemoveMedia, deleteRemoveMediaData{
- BaseData: &viewutil2.BaseData{
- Addr: "/remove-media/" + hyphaName,
- },
- HyphaName: hyphaName,
- })
-}
-
type emptyHyphaData struct {
- Meta viewutil2.Meta
+ Meta viewutil.Meta
HyphaName string
AllowRegistration bool
UseAuth bool
}
-func EmptyHypha(meta viewutil2.Meta, hyphaName string) string {
+func EmptyHypha(meta viewutil.Meta, hyphaName string) string {
var buf strings.Builder
if err := chainEmptyHypha.Get(meta).ExecuteTemplate(&buf, "empty hypha card", emptyHyphaData{
Meta: meta,
@@ -182,7 +75,7 @@ type naviTitleData struct {
HomeHypha string
}
-func NaviTitle(meta viewutil2.Meta, hyphaName string) string {
+func NaviTitle(meta viewutil.Meta, hyphaName string) template.HTML {
parts, partsWithParents := naviTitleify(hyphaName)
var buf strings.Builder
err := chainNaviTitle.Get(meta).ExecuteTemplate(&buf, "navititle", naviTitleData{
diff --git a/hypview/readers.qtpl b/hypview/readers.qtpl
index 922cc68..136e42d 100644
--- a/hypview/readers.qtpl
+++ b/hypview/readers.qtpl
@@ -82,66 +82,6 @@
{% endfunc %}
-If `contents` == "", a helpful message is shown instead.
-
-If you rename .prevnext, change the docs too.
-{% func Hypha(meta viewutil.Meta, h hyphae.Hypha, contents string) %}
-{% code
- subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
- lc := meta.Lc
-%}
-
-
- {% if meta.U.CanProceed("edit") %}
-
- {% endif %}
-
- {% if cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && meta.U.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha + "/") %}
-
- {% if meta.U.Group == "admin" %}
-
- {% endif %}
- {% endif %}
-
- {%s= NaviTitle(meta, h.CanonicalName()) %}
- {% switch h.(type) %}
- {% case *hyphae.EmptyHypha %}
- {%s= EmptyHypha(meta, h.CanonicalName()) %}
- {% default %}
- {%s= contents %}
- {% endswitch %}
-
-
-{% if strings.TrimSpace(subhyphae) != "" %}
-
- {%s lc.Get("ui.subhyphae") %}
-
-
-{% endif %}
-
- {%= hyphaInfo(meta, h) %}
-
-
-{%s= categories.CategoryCard(meta, h.CanonicalName()) %}
-{%= viewScripts() %}
-{% endfunc %}
{% func Revision(meta viewutil.Meta, h hyphae.Hypha, contents, revHash string) %}
@@ -151,10 +91,6 @@ If you rename .prevnext, change the docs too.
{%s= contents %}
-{%= viewScripts() %}
-{% endfunc %}
-
-{% func viewScripts() %}
{% for _, scriptPath := range cfg.ViewScripts %}
{% endfor %}
diff --git a/hypview/view_remove_media.html b/hypview/view_remove_media.html
deleted file mode 100644
index 3edd8d8..0000000
--- a/hypview/view_remove_media.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{{define "remove media from x?"}}Remove media from {{beautifulName .}}?{{end}}
-{{define "title"}}{{template "remove media from x?" .HyphaName}}{{end}}
-{{define "body"}}
-
-
-
-{{end}}
\ No newline at end of file
diff --git a/internal/tree/tree.go b/internal/tree/tree.go
index a5aa1b2..05d9ad8 100644
--- a/internal/tree/tree.go
+++ b/internal/tree/tree.go
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/util"
+ "html/template"
"io"
"path"
"sort"
@@ -11,7 +12,7 @@ import (
)
// Tree returns the subhypha matrix as HTML and names of the next and previous hyphae (or empty strings).
-func Tree(hyphaName string) (childrenHTML, prev, next string) {
+func Tree(hyphaName string) (childrenHTML template.HTML, prev, next string) {
var (
root = child{hyphaName, true, make([]child, 0)}
descendantPrefix = hyphaName + "/"
diff --git a/web/mutators.go b/web/mutators.go
index 5502356..75e13ae 100644
--- a/web/mutators.go
+++ b/web/mutators.go
@@ -2,10 +2,10 @@ package web
import (
"git.sr.ht/~bouncepaw/mycomarkup/v5"
- hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
- shroom2 "github.com/bouncepaw/mycorrhiza/internal/shroom"
+ "github.com/bouncepaw/mycorrhiza/internal/hyphae"
+ "github.com/bouncepaw/mycorrhiza/internal/shroom"
"github.com/bouncepaw/mycorrhiza/internal/user"
- viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
+ "github.com/bouncepaw/mycorrhiza/web/viewutil"
"html/template"
"log"
"net/http"
@@ -24,7 +24,7 @@ func initMutators(r *mux.Router) {
r.PathPrefix("/edit/").HandlerFunc(handlerEdit)
r.PathPrefix("/rename/").HandlerFunc(handlerRename).Methods("GET", "POST")
r.PathPrefix("/delete/").HandlerFunc(handlerDelete).Methods("GET", "POST")
- r.PathPrefix("/remove-media/").HandlerFunc(handlerRemoveMedia).Methods("GET", "POST")
+ r.PathPrefix("/remove-media/").HandlerFunc(handlerRemoveMedia).Methods("POST")
r.PathPrefix("/upload-binary/").HandlerFunc(handlerUploadBinary)
r.PathPrefix("/upload-text/").HandlerFunc(handlerUploadText)
}
@@ -35,24 +35,20 @@ func handlerRemoveMedia(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
u = user.FromRequest(rq)
- h = hyphae2.ByName(util.HyphaNameFromRq(rq, "remove-media"))
- meta = viewutil2.MetaFrom(w, rq)
+ h = hyphae.ByName(util.HyphaNameFromRq(rq, "remove-media"))
+ meta = viewutil.MetaFrom(w, rq)
)
if !u.CanProceed("remove-media") {
- viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no rights")
- return
- }
- if rq.Method == "GET" {
- hypview.RemoveMedia(viewutil2.MetaFrom(w, rq), h.CanonicalName())
+ viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no rights")
return
}
switch h := h.(type) {
- case *hyphae2.EmptyHypha, *hyphae2.TextualHypha:
- viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no media to remove")
+ case *hyphae.EmptyHypha, *hyphae.TextualHypha:
+ viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "no media to remove")
return
- case *hyphae2.MediaHypha:
- if err := shroom2.RemoveMedia(u, h); err != nil {
- viewutil2.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
+ case *hyphae.MediaHypha:
+ if err := shroom.RemoveMedia(u, h); err != nil {
+ viewutil.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
return
}
}
@@ -63,32 +59,36 @@ func handlerDelete(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
u = user.FromRequest(rq)
- h = hyphae2.ByName(util.HyphaNameFromRq(rq, "delete"))
- meta = viewutil2.MetaFrom(w, rq)
+ h = hyphae.ByName(util.HyphaNameFromRq(rq, "delete"))
+ meta = viewutil.MetaFrom(w, rq)
)
if !u.CanProceed("delete") {
log.Printf("%s has no rights to delete ‘%s’\n", u.Name, h.CanonicalName())
- viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
+ viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
return
}
switch h.(type) {
- case *hyphae2.EmptyHypha:
+ case *hyphae.EmptyHypha:
log.Printf("%s tries to delete empty hypha ‘%s’\n", u.Name, h.CanonicalName())
// TODO: localize
- viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha")
+ viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot delete an empty hypha")
return
}
if rq.Method == "GET" {
- hypview.DeleteHypha(meta, h.CanonicalName())
+ _ = pageHyphaDelete.RenderTo(
+ viewutil.MetaFrom(w, rq),
+ map[string]any{
+ "HyphaName": h.CanonicalName(),
+ })
return
}
- if err := shroom2.Delete(u, h.(hyphae2.ExistingHypha)); err != nil {
+ if err := shroom.Delete(u, h.(hyphae.ExistingHypha)); err != nil {
log.Println(err)
- viewutil2.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
+ viewutil.HttpErr(meta, http.StatusInternalServerError, h.CanonicalName(), err.Error())
return
}
http.Redirect(w, rq, "/hypha/"+h.CanonicalName(), http.StatusSeeOther)
@@ -99,25 +99,25 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) {
var (
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
- h = hyphae2.ByName(util.HyphaNameFromRq(rq, "rename"))
- meta = viewutil2.MetaFrom(w, rq)
+ h = hyphae.ByName(util.HyphaNameFromRq(rq, "rename"))
+ meta = viewutil.MetaFrom(w, rq)
)
switch h.(type) {
- case *hyphae2.EmptyHypha:
+ case *hyphae.EmptyHypha:
log.Printf("%s tries to rename empty hypha ‘%s’", u.Name, h.CanonicalName())
- viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot rename an empty hypha") // TODO: localize
+ viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "Cannot rename an empty hypha") // TODO: localize
return
}
if !u.CanProceed("rename") {
log.Printf("%s has no rights to rename ‘%s’\n", u.Name, h.CanonicalName())
- viewutil2.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
+ viewutil.HttpErr(meta, http.StatusForbidden, h.CanonicalName(), "No rights")
return
}
var (
- oldHypha = h.(hyphae2.ExistingHypha)
+ oldHypha = h.(hyphae.ExistingHypha)
newName = util.CanonicalName(rq.PostFormValue("new-name"))
recursive = rq.PostFormValue("recursive") == "true"
leaveRedirections = rq.PostFormValue("redirection") == "true"
@@ -128,9 +128,9 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) {
return
}
- if err := shroom2.Rename(oldHypha, newName, recursive, leaveRedirections, u); err != nil {
+ if err := shroom.Rename(oldHypha, newName, recursive, leaveRedirections, u); err != nil {
log.Printf("%s tries to rename ‘%s’: %s", u.Name, oldHypha.CanonicalName(), err.Error())
- viewutil2.HttpErr(meta, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize
+ viewutil.HttpErr(meta, http.StatusForbidden, oldHypha.CanonicalName(), lc.Get(err.Error())) // TODO: localize
return
}
http.Redirect(w, rq, "/hypha/"+newName, http.StatusSeeOther)
@@ -142,33 +142,41 @@ func handlerEdit(w http.ResponseWriter, rq *http.Request) {
var (
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
- meta = viewutil2.MetaFrom(w, rq)
+ meta = viewutil.MetaFrom(w, rq)
hyphaName = util.HyphaNameFromRq(rq, "edit")
- h = hyphae2.ByName(hyphaName)
+ h = hyphae.ByName(hyphaName)
isNew bool
content string
err error
)
- if err := shroom2.CanEdit(u, h, lc); err != nil {
- viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
+ if err := shroom.CanEdit(u, h, lc); err != nil {
+ viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
return
}
switch h.(type) {
- case *hyphae2.EmptyHypha:
+ case *hyphae.EmptyHypha:
isNew = true
default:
- content, err = hyphae2.FetchMycomarkupFile(h)
+ content, err = hyphae.FetchMycomarkupFile(h)
if err != nil {
log.Println(err)
- viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch"))
+ viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch"))
return
}
}
- hypview.EditHypha(meta, hyphaName, isNew, content, "", "")
+ _ = pageHyphaEdit.RenderTo(
+ viewutil.MetaFrom(w, rq),
+ map[string]any{
+ "HyphaName": hyphaName,
+ "Content": content,
+ "IsNew": isNew,
+ "Message": "",
+ "Preview": "",
+ })
}
// handlerUploadText uploads a new text part for the hypha.
@@ -176,11 +184,11 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
u = user.FromRequest(rq)
- meta = viewutil2.MetaFrom(w, rq)
+ meta = viewutil.MetaFrom(w, rq)
hyphaName = util.HyphaNameFromRq(rq, "upload-text")
- h = hyphae2.ByName(hyphaName)
- _, isNew = h.(*hyphae2.EmptyHypha)
+ h = hyphae.ByName(hyphaName)
+ _, isNew = h.(*hyphae.EmptyHypha)
textData = rq.PostFormValue("text")
action = rq.PostFormValue("action")
@@ -190,12 +198,21 @@ func handlerUploadText(w http.ResponseWriter, rq *http.Request) {
if action == "preview" {
ctx, _ := mycocontext.ContextFromStringInput(textData, mycoopts.MarkupOptions(hyphaName))
preview := template.HTML(mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx)))
- hypview.EditHypha(meta, hyphaName, isNew, textData, message, preview)
+
+ _ = pageHyphaEdit.RenderTo(
+ viewutil.MetaFrom(w, rq),
+ map[string]any{
+ "HyphaName": hyphaName,
+ "Content": textData,
+ "IsNew": isNew,
+ "Message": message,
+ "Preview": preview,
+ })
return
}
- if err := shroom2.UploadText(h, []byte(textData), message, u); err != nil {
- viewutil2.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error())
+ if err := shroom.UploadText(h, []byte(textData), message, u); err != nil {
+ viewutil.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error())
return
}
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
@@ -207,17 +224,17 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
rq.ParseMultipartForm(10 << 20) // Set upload limit
var (
hyphaName = util.HyphaNameFromRq(rq, "upload-binary")
- h = hyphae2.ByName(hyphaName)
+ h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
file, handler, err = rq.FormFile("binary")
- meta = viewutil2.MetaFrom(w, rq)
+ meta = viewutil.MetaFrom(w, rq)
)
if err != nil {
- viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
+ viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
}
- if err := shroom2.CanAttach(u, h, lc); err != nil {
- viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
+ if err := shroom.CanAttach(u, h, lc); err != nil {
+ viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
}
// If file is not passed:
@@ -234,8 +251,8 @@ func handlerUploadBinary(w http.ResponseWriter, rq *http.Request) {
mime = handler.Header.Get("Content-Type")
)
- if err := shroom2.UploadBinary(h, mime, file, u); err != nil {
- viewutil2.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
+ if err := shroom.UploadBinary(h, mime, file, u); err != nil {
+ viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error())
return
}
http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther)
diff --git a/web/pages.go b/web/pages.go
index dc9f8aa..57b1879 100644
--- a/web/pages.go
+++ b/web/pages.go
@@ -3,23 +3,23 @@ package web
import (
"embed"
"github.com/bouncepaw/mycorrhiza/web/newtmpl"
- viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
+ "github.com/bouncepaw/mycorrhiza/web/viewutil"
)
//go:embed views/*.html
var fs embed.FS
var pageOrphans, pageBacklinks, pageUserList, pageChangePassword *newtmpl.Page
-
-var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil2.Chain
+var pageHyphaDelete, pageHyphaEdit, pageHyphaEmpty, pageHypha *newtmpl.Page
+var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil.Chain
func initPages() {
- panelChain = viewutil2.CopyEnRuWith(fs, "views/admin-panel.html", adminTranslationRu)
- listChain = viewutil2.CopyEnRuWith(fs, "views/admin-user-list.html", adminTranslationRu)
- newUserChain = viewutil2.CopyEnRuWith(fs, "views/admin-new-user.html", adminTranslationRu)
- editUserChain = viewutil2.CopyEnRuWith(fs, "views/admin-edit-user.html", adminTranslationRu)
- deleteUserChain = viewutil2.CopyEnRuWith(fs, "views/admin-delete-user.html", adminTranslationRu)
+ panelChain = viewutil.CopyEnRuWith(fs, "views/admin-panel.html", adminTranslationRu)
+ listChain = viewutil.CopyEnRuWith(fs, "views/admin-user-list.html", adminTranslationRu)
+ newUserChain = viewutil.CopyEnRuWith(fs, "views/admin-new-user.html", adminTranslationRu)
+ editUserChain = viewutil.CopyEnRuWith(fs, "views/admin-edit-user.html", adminTranslationRu)
+ deleteUserChain = viewutil.CopyEnRuWith(fs, "views/admin-delete-user.html", adminTranslationRu)
pageOrphans = newtmpl.NewPage(fs, "views/orphans.html", map[string]string{
"orphaned hyphae": "Гифы-сироты",
@@ -45,4 +45,59 @@ func initPages() {
"password": "Пароль",
"submit": "Поменять",
})
+ pageHyphaDelete = newtmpl.NewPage(fs, "views/hypha-delete.html", map[string]string{
+ "delete hypha?": "Удалить {{beautifulName .}}?",
+ "delete [[hypha]]?": "Удалить {{beautifulName .}}?",
+ "want to delete?": "Вы действительно хотите удалить эту гифу?",
+ "delete tip": "Нельзя отменить удаление гифы, но её история останется доступной.",
+ })
+ pageHyphaEdit = newtmpl.NewPage(fs, "views/hypha-edit.html", map[string]string{
+ "editing hypha": `Редактирование {{beautifulName .}}`,
+ "editing [[hypha]]": `Редактирование {{beautifulName .}}`,
+ "creating [[hypha]]": `Создание {{beautifulName .}}`,
+ "you're creating a new hypha": `Вы создаёте новую гифу.`,
+ "describe your changes": `Опишите ваши правки`,
+ "save": `Сохранить`,
+ "preview": `Предпросмотр`,
+ "previewing hypha": `Предпросмотр «{{beautifulName .}}»`,
+ "preview tip": `Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:`,
+
+ "markup": `Разметка`,
+ "link": `Ссылка`,
+ "link title": `Текст`,
+ "heading": `Заголовок`,
+ "bold": `Жирный`,
+ "italic": `Курсив`,
+ "highlight": `Выделение`,
+ "underline": `Подчеркивание`,
+ "mono": `Моноширинный`,
+ "super": `Надстрочный`,
+ "sub": `Подстрочный`,
+ "strike": `Зачёркнутый`,
+ "rocket": `Ссылка-ракета`,
+ "transclude": `Трансклюзия`,
+ "hr": `Гориз. черта`,
+ "code": `Код-блок`,
+ "bullets": `Маркир. список`,
+ "numbers": `Нумер. список`,
+ "mycomarkup help": `Подробнее о Микоразметке`,
+ "actions": `Действия`,
+ "current date": `Текущая дата`,
+ "current time": `Текущее время`,
+ "selflink": `Ссылка на вас`,
+ })
+ pageHyphaEmpty = newtmpl.NewPage(fs, "views/hypha-empty.html", map[string]string{
+ "empty heading": `Эта гифа не существует`,
+ "empty no rights": `У вас нет прав для создания новых гиф. Вы можете:`,
+ "empty log in": `Войти в свою учётную запись, если она у вас есть`,
+ "empty register": `Создать новую учётную запись`,
+ "write a text": `Написать текст`,
+ "write a text tip": `Напишите заметку, дневник, статью, рассказ или иной текст с помощью Микоразметки. Сохраняется полная история правок документа.`,
+ "write a text writing conventions": `Не забывайте следовать правилам оформления этой вики, если они имеются.`,
+ "write a text btn": `Создать`,
+ "upload a media": `Загрузить медиа`,
+ "upload a media tip": `Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.`,
+ "upload a media btn": `Загрузить`,
+ })
+ pageHypha = newtmpl.NewPage(fs, "views/hypha.html", map[string]string{})
}
diff --git a/web/readers.go b/web/readers.go
index 27f79fd..16a058c 100644
--- a/web/readers.go
+++ b/web/readers.go
@@ -4,14 +4,17 @@ import (
"fmt"
"git.sr.ht/~bouncepaw/mycomarkup/v5"
"github.com/bouncepaw/mycorrhiza/categories"
- views2 "github.com/bouncepaw/mycorrhiza/hypview"
+ "github.com/bouncepaw/mycorrhiza/hypview"
"github.com/bouncepaw/mycorrhiza/internal/backlinks"
+ "github.com/bouncepaw/mycorrhiza/internal/cfg"
"github.com/bouncepaw/mycorrhiza/internal/files"
- hyphae2 "github.com/bouncepaw/mycorrhiza/internal/hyphae"
+ "github.com/bouncepaw/mycorrhiza/internal/hyphae"
"github.com/bouncepaw/mycorrhiza/internal/mimetype"
+ "github.com/bouncepaw/mycorrhiza/internal/tree"
"github.com/bouncepaw/mycorrhiza/internal/user"
"github.com/bouncepaw/mycorrhiza/mycoopts"
- viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
+ "github.com/bouncepaw/mycorrhiza/web/viewutil"
+ "html/template"
"io"
"log"
"net/http"
@@ -59,15 +62,15 @@ func handlerMedia(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
hyphaName = util.HyphaNameFromRq(rq, "media")
- h = hyphae2.ByName(hyphaName)
+ h = hyphae.ByName(hyphaName)
u = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
)
util.HTTP200Page(w,
- viewutil2.Base(
- viewutil2.MetaFrom(w, rq),
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
lc.Get("ui.media_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName)}),
- views2.MediaMenu(rq, h, u),
+ hypview.MediaMenu(rq, h, u),
map[string]string{},
))
}
@@ -85,11 +88,11 @@ func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
}
var (
hyphaName = util.CanonicalName(slug)
- h = hyphae2.ByName(hyphaName)
+ h = hyphae.ByName(hyphaName)
)
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
switch h := h.(type) {
- case *hyphae2.EmptyHypha:
+ case *hyphae.EmptyHypha:
var mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco")
var textContents, err = history.FileAtRevision(mycoFilePath, revHash)
@@ -102,7 +105,7 @@ func handlerRevisionText(w http.ResponseWriter, rq *http.Request) {
log.Printf("Serving text of ‘%s’ from ‘%s’ at revision ‘%s’\n", hyphaName, mycoFilePath, revHash)
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, textContents)
- case hyphae2.ExistingHypha:
+ case hyphae.ExistingHypha:
if !h.HasTextFile() {
log.Printf(`Media hypha ‘%s’ has no text`)
w.WriteHeader(http.StatusNotFound)
@@ -133,16 +136,16 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
}
var (
hyphaName = util.CanonicalName(slug)
- h = hyphae2.ByName(hyphaName)
+ h = hyphae.ByName(hyphaName)
contents = fmt.Sprintf(`
%s
`, lc.Get("ui.revision_no_text"))
textContents string
err error
mycoFilePath string
)
switch h := h.(type) {
- case hyphae2.ExistingHypha:
+ case hyphae.ExistingHypha:
mycoFilePath = h.TextFilePath()
- case *hyphae2.EmptyHypha:
+ case *hyphae.EmptyHypha:
mycoFilePath = filepath.Join(files.HyphaeDir(), h.CanonicalName()+".myco")
}
textContents, err = history.FileAtRevision(mycoFilePath, revHash)
@@ -151,8 +154,8 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
contents = mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))
}
- page := views2.Revision(
- viewutil2.MetaFrom(w, rq),
+ page := hypview.Revision(
+ viewutil.MetaFrom(w, rq),
h,
contents,
revHash,
@@ -161,8 +164,8 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = fmt.Fprint(
w,
- viewutil2.Base(
- viewutil2.MetaFrom(w, rq),
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
lc.Get("ui.revision_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName), "rev": revHash}),
page,
map[string]string{},
@@ -174,8 +177,8 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
func handlerText(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
hyphaName := util.HyphaNameFromRq(rq, "text")
- switch h := hyphae2.ByName(hyphaName).(type) {
- case hyphae2.ExistingHypha:
+ switch h := hyphae.ByName(hyphaName).(type) {
+ case hyphae.ExistingHypha:
log.Println("Serving", h.TextFilePath())
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
http.ServeFile(w, rq, h.TextFilePath())
@@ -186,12 +189,12 @@ func handlerText(w http.ResponseWriter, rq *http.Request) {
func handlerBinary(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
hyphaName := util.HyphaNameFromRq(rq, "binary")
- switch h := hyphae2.ByName(hyphaName).(type) {
- case *hyphae2.EmptyHypha:
- case *hyphae2.TextualHypha:
+ switch h := hyphae.ByName(hyphaName).(type) {
+ case *hyphae.EmptyHypha:
+ case *hyphae.TextualHypha:
w.WriteHeader(http.StatusNotFound)
log.Printf("Textual hypha ‘%s’ has no media, cannot serve\n", h.CanonicalName())
- case *hyphae2.MediaHypha:
+ case *hyphae.MediaHypha:
log.Println("Serving", h.MediaFilePath())
w.Header().Set("Content-Type", mimetype.FromExtension(filepath.Ext(h.MediaFilePath())))
http.ServeFile(w, rq, h.MediaFilePath())
@@ -203,22 +206,23 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
var (
hyphaName = util.HyphaNameFromRq(rq, "page", "hypha")
- h = hyphae2.ByName(hyphaName)
+ h = hyphae.ByName(hyphaName)
contents string
openGraph string
lc = l18n.FromRequest(rq)
)
switch h := h.(type) {
- case *hyphae2.EmptyHypha:
+ case *hyphae.EmptyHypha:
+ // contents = hypview.EmptyHypha()
util.HTTP404Page(w,
- viewutil2.Base(
- viewutil2.MetaFrom(w, rq),
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
util.BeautifulName(hyphaName),
- views2.Hypha(viewutil2.MetaFrom(w, rq), h, contents),
+ hypview.Hypha(viewutil.MetaFrom(w, rq), h, ""),
map[string]string{},
openGraph))
- case hyphae2.ExistingHypha:
+ case hyphae.ExistingHypha:
fileContentsT, errT := os.ReadFile(h.TextFilePath())
if errT == nil {
ctx, _ := mycocontext.ContextFromStringInput(string(fileContentsT), mycoopts.MarkupOptions(hyphaName))
@@ -228,17 +232,30 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
openGraph = getOpenGraph()
}
switch h := h.(type) {
- case *hyphae2.MediaHypha:
+ case *hyphae.MediaHypha:
contents = mycoopts.Media(h, lc) + contents
}
+ meta := viewutil.MetaFrom(w, rq)
category_list := ":" + strings.Join(categories.CategoriesWithHypha(h.CanonicalName()), ":") + ":"
+ subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
+ isMyProfile := cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && meta.U.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha+"/")
+ _ = pageHypha.RenderTo(
+ meta,
+ map[string]any{
+ "SubhyphaeHTML": subhyphae,
+ "PrevHyphaName": prevHyphaName,
+ "NextHyphaName": nextHyphaName,
+ "IsMyProfile": isMyProfile,
+ "NaviTitle": hypview.NaviTitle(meta, h.CanonicalName()),
+ "Contents": template.HTML(contents),
+ })
util.HTTP200Page(w,
- viewutil2.Base(
- viewutil2.MetaFrom(w, rq),
+ viewutil.Base(
+ viewutil.MetaFrom(w, rq),
util.BeautifulName(hyphaName),
- views2.Hypha(viewutil2.MetaFrom(w, rq), h, contents),
+ hypview.Hypha(viewutil.MetaFrom(w, rq), h, contents),
map[string]string{"cats": category_list},
openGraph))
}
@@ -248,7 +265,7 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
func handlerBacklinks(w http.ResponseWriter, rq *http.Request) {
hyphaName := util.HyphaNameFromRq(rq, "backlinks")
- _ = pageBacklinks.RenderTo(viewutil2.MetaFrom(w, rq),
+ _ = pageBacklinks.RenderTo(viewutil.MetaFrom(w, rq),
map[string]any{
"Addr": "/backlinks/" + hyphaName,
"HyphaName": hyphaName,
@@ -257,7 +274,7 @@ func handlerBacklinks(w http.ResponseWriter, rq *http.Request) {
}
func handlerOrphans(w http.ResponseWriter, rq *http.Request) {
- _ = pageOrphans.RenderTo(viewutil2.MetaFrom(w, rq),
+ _ = pageOrphans.RenderTo(viewutil.MetaFrom(w, rq),
map[string]any{
"Addr": "/orphans",
"Orphans": backlinks.Orphans(),
diff --git a/web/static/default.css b/web/static/default.css
index b5b833f..50375c9 100644
--- a/web/static/default.css
+++ b/web/static/default.css
@@ -108,11 +108,11 @@ main h1:not(.navi-title) {font-size:1.7rem;}
blockquote { margin: 0; padding-left: .75rem; }
.wikilink_external::before { display: inline-block; width: 18px; height: 16px; vertical-align: sub; }
/* .wikilink_external { padding-left: 16px; } */
-.wikilink_gopher::before { content: url("/staticatic/icon/gopher-proto.svg"); }
-.wikilink_http::before, .wikilink_https::before { content: url("/staticatic/icon/http-proto.svg"); }
+.wikilink_gopher::before { content: url("/static/icon/gopher-proto.svg"); }
+.wikilink_http::before, .wikilink_https::before { content: url("/static/icon/http-proto.svg"); }
/* .wikilink_https { background: transparent url("/static/icon/http-proto.svg") center left no-repeat; } */
-.wikilink_gemini::before { content: url("/staticatic/icon/gemini-proto.svg"); }
-.wikilink_mailto::before { content: url("/staticatic/icon/mailto-proto.svg"); }
+.wikilink_gemini::before { content: url("/static/icon/gemini-proto.svg"); }
+.wikilink_mailto::before { content: url("/static/icon/mailto-proto.svg"); }
article { overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; line-height: 150%; }
main h1 { margin: .5rem 0 0 0; }
diff --git a/hypview/view_delete.html b/web/views/hypha-delete.html
similarity index 100%
rename from hypview/view_delete.html
rename to web/views/hypha-delete.html
diff --git a/hypview/view_edit.html b/web/views/hypha-edit.html
similarity index 100%
rename from hypview/view_edit.html
rename to web/views/hypha-edit.html
diff --git a/hypview/view_empty_hypha.html b/web/views/hypha-empty.html
similarity index 100%
rename from hypview/view_empty_hypha.html
rename to web/views/hypha-empty.html
diff --git a/web/views/hypha.html b/web/views/hypha.html
new file mode 100644
index 0000000..5721245
--- /dev/null
+++ b/web/views/hypha.html
@@ -0,0 +1,98 @@
+{{define "body"}}
+
+
+ {{if .Meta.U.CanProceed "edit"}}
+
+ {{end}}
+
+ {{if .IsMyProfile}}
+
+ {{if eq .Meta.U.Group "admin"}}
+
+ {{end}}
+ {{end}}
+
+ {{.NaviTitle}}
+ {{.Contents}}
+
+
+
+
+ {{ if .SubhyphaeHTML }}
+
+ {%s lc.Get("ui.subhyphae") %}
+
+
+ {{end}}
+
+
+ {{hyphaInfo(meta, h)}}
+
+
+ {{template "category card" .}}
+ {{range .ViewScripts}}
+ {{end}}
+{{end}}
+
+{{define "category card"}}
+ {{if or .GivenPermissionToModify (len .Categories)}}
+ {{$hyphaName := .HyphaName}}
+ {{$givenPermission := .GivenPermissionToModify}}
+
+ {{end}}{{end}}