From 53ae1a6e7a874989290a3a875ec411c853743a45 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Sun, 11 Jul 2021 01:02:16 +0500 Subject: [PATCH 1/7] Add the help system No documentation yet. This branch will eventually be merged into master --- help/en/index.myco | 7 +++++++ help/help.go | 15 +++++++++++++++ web/stuff.go | 25 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 help/en/index.myco create mode 100644 help/help.go diff --git a/help/en/index.myco b/help/en/index.myco new file mode 100644 index 0000000..90d5dc1 --- /dev/null +++ b/help/en/index.myco @@ -0,0 +1,7 @@ +This is Mycorrhiza Wiki built-in documentation. + +Hope you are doing well ☺️ + +Here are the topics covered by the documentation: + +Thanks for reading! \ No newline at end of file diff --git a/help/help.go b/help/help.go new file mode 100644 index 0000000..06fc6f1 --- /dev/null +++ b/help/help.go @@ -0,0 +1,15 @@ +// Package help contains help messages and the utilities for retrieving them. +package help + +import ( + "embed" +) + +//go:embed en +var fs embed.FS + +// Get determines what help text you need and returns it. The path is a substring from URL, it follows this form: +// / +func Get(path string) ([]byte, error) { + return fs.ReadFile(path + ".myco") +} diff --git a/web/stuff.go b/web/stuff.go index bf9ed49..b757a97 100644 --- a/web/stuff.go +++ b/web/stuff.go @@ -2,6 +2,9 @@ package web // stuff.go is used for meta stuff about the wiki or all hyphae at once. import ( + "github.com/bouncepaw/mycomarkup" + "github.com/bouncepaw/mycomarkup/mycocontext" + "github.com/bouncepaw/mycorrhiza/help" "io" "log" "math/rand" @@ -18,6 +21,7 @@ import ( ) func initStuff() { + http.HandleFunc("/help/", handlerHelp) http.HandleFunc("/list/", handlerList) http.HandleFunc("/reindex/", handlerReindex) http.HandleFunc("/update-header-links/", handlerUpdateHeaderLinks) @@ -28,6 +32,27 @@ func initStuff() { }) } +// handlerHelp gets the appropriate documentation or tells you where you (personally) have failed. +func handlerHelp(w http.ResponseWriter, rq *http.Request) { + if shown := user.FromRequest(rq).ShowLockMaybe(w, rq); shown { + return + } + + content, err := help.Get(rq.URL.Path[6:]) // Drop /help/ + if err != nil { + // TODO: proper error reporting that makes sense + httpErr(w, http.StatusForbidden, cfg.HomeHypha, err.Error(), err.Error()) + return + } + + // TODO: change for the function that uses byte array when there is such function in mycomarkup. + ctx, _ := mycocontext.ContextFromStringInput(rq.URL.Path[1:3], string(content)) + ast := mycomarkup.BlockTree(ctx) + result := mycomarkup.BlocksToHTML(ctx, ast) + // TODO: styled output idk + _, _ = io.WriteString(w, result) +} + // handlerList shows a list of all hyphae in the wiki in random order. func handlerList(w http.ResponseWriter, rq *http.Request) { u := user.FromRequest(rq) From d7d2e851dbb2463425366398c564e09cf60bbdf2 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Sun, 11 Jul 2021 01:31:18 +0500 Subject: [PATCH 2/7] Write the Hypha article --- help/en/hypha.myco | 35 +++++++++++++++++++++++++++++++++++ help/en/index.myco | 1 + 2 files changed, 36 insertions(+) create mode 100644 help/en/hypha.myco diff --git a/help/en/hypha.myco b/help/en/hypha.myco new file mode 100644 index 0000000..51b9cb9 --- /dev/null +++ b/help/en/hypha.myco @@ -0,0 +1,35 @@ +# Hypha +**Hypha** (//plural:// hyphae) is the main content unit used in Mycorrhiza Wiki. + +## The structure of hypha +A hypha consists of two parts: +* **Attachment.** Some form of media. There is only one attachment. See [[/help/en/attachment | Attachment]] for more information about attachments. +* **Text part.** Either a description of the attachment or a stand-alone text unit such as an article, a diary or a poem. It is written in a special markup, called [[/help/en/mycomarkup | Mycomarkup]]. + +Both parts are optional. You can have a picture without description, an article without an attachment, etc. You can have them both. You must have at least one part, though. + +## How to create a hypha? +Some links on wiki are red. It means that they link a hypha that does not exist yet. If you follow this link, you will see a special page where you can upload an attachment or open the text editor. This is how you create hyphae. + +You can create such red links and follow them to create hyphae. + +Alternatively, you can edit your address in browser to jump to such pages directly. + +## Hypha names +Hypha names are case-insensitive. It means that names //amanita muscaria// and //Amanita Muscaria// are the same. Also, space and underscore are also the same (//amanita muscaria// = //amanita_muscaria//). Canonical names are all lowercase and underscored. + +There are some characters that cannot be part of a hypha name: `?!:#@><*|"'&%{}\\` Others can be used. + +## Genealogy +A **subhypha** is a hypha that has a name starting with a name of a different hypha, followed by a slash and by the rest of the name. For example, hypha //Fruit/Apple// is a subhypha of hypha //Fruit//. There can be as many subhyphae as you want. Subhyphae can have subhyphae themselves. + +Thus, a **superhypha** is a reverse of subhypha: //Fruit// is the superhypha of //Fruit/Apple//. There can be only one superhypha. + +**Sister hyphae** are hyphae that are subhyphae of the same hypha. For example, //Fruit/Apple// and //Fruit/Pear// are sister hyphae. + +## Word +Read the word //hypha// as /ˈhaɪfə/. The plural form is //hyphae//. Read it as /ˈhaɪfi/. + +The word is taken from mycology, the study of fungi. In a fungus, hyphae are thin white threads from which the mycelium is made. See [[https://en.wikipedia.org/wiki/Hypha | this Wikipedia article]] for more information about real hyphae. + +Think of Mycorrhiza Wiki hyphae as of small elements that build up your wiki. \ No newline at end of file diff --git a/help/en/index.myco b/help/en/index.myco index 90d5dc1..93d295b 100644 --- a/help/en/index.myco +++ b/help/en/index.myco @@ -3,5 +3,6 @@ This is Mycorrhiza Wiki built-in documentation. Hope you are doing well ☺️ Here are the topics covered by the documentation: +=> /help/en/hypha Hypha Thanks for reading! \ No newline at end of file From 3e13d6a4dbf9cf52f381e69ec091ed3d67fe035f Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Mon, 12 Jul 2021 02:34:00 +0500 Subject: [PATCH 3/7] Write the Attachment article I also included a link to the article in the Attachment tab. --- help/en/attachment.myco | 34 ++++++++++++++++++++++++++++++++++ help/en/index.myco | 3 ++- views/readers.qtpl | 6 +++--- views/readers.qtpl.go | 6 +++--- 4 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 help/en/attachment.myco diff --git a/help/en/attachment.myco b/help/en/attachment.myco new file mode 100644 index 0000000..2f866e9 --- /dev/null +++ b/help/en/attachment.myco @@ -0,0 +1,34 @@ +# Attachment +In hyphae, an **attachment** is some content represented by something that is not [[/help/en/mycomarkup | Mycomarkup]]. Usually, an image, a video, or an audio. + +## Supported attachment types +You can upload any file, but only those listed below will be displayed on the website. You can download unsupported attachments, though. + +* **Images:** jpg, gif, png, webp, svg, ico +* **Video:** ogg, webm, mp4 +* **Audio:** ogg, webm, mp3 + +## How to add an attachment? +For non-existent hyphae, upload a file in the //Upload a media// section. + +For any hyphae, upload a file in the //Attachment// tab. + +## Attachment tab +Every hypha has the //Attachment// tab. Click it to see what is out there. + +You can upload a new file, you can //delete// the attachment (it is called //unattaching//) and see some file stats (size and type). + +## On naming hyphae with attachments +The hypha name should not just copy the file name in most cases. If you are uploading a photo of a rose, do not call it `rose.jpg`, no. Call it `photo of rose` or `rose photo` or whatever. You rarely need to think of file extensions when using Mycorrhiza Wiki. + +This is not a rule, of course, just a convention. + +## What to put in the text part? +If a hypha has an attachment, here is what the text part might be about: +* A textual description or representation of the picture. +* A transcript of the song. +* An analysis of the attachment. +* Some meta data. +* Things above combined. + +The attachment //should not// be an illustration. \ No newline at end of file diff --git a/help/en/index.myco b/help/en/index.myco index 93d295b..c0c5062 100644 --- a/help/en/index.myco +++ b/help/en/index.myco @@ -3,6 +3,7 @@ This is Mycorrhiza Wiki built-in documentation. Hope you are doing well ☺️ Here are the topics covered by the documentation: -=> /help/en/hypha Hypha +* [[/help/en/hypha | Hypha]] +** [[/help/en/attachment | Attachment]] Thanks for reading! \ No newline at end of file diff --git a/views/readers.qtpl b/views/readers.qtpl index e4f3525..bd2c4fe 100644 --- a/views/readers.qtpl +++ b/views/readers.qtpl @@ -13,12 +13,12 @@ {% func AttachmentMenuHTML(rq *http.Request, h *hyphae.Hypha, u *user.User) %} {%= NavHTML(rq, h.Name, "attachment") %}
-
+

Attachment of {%s util.BeautifulName(h.Name) %}

{% if h.BinaryPath == "" %} -

This hypha has no attachment, you can upload it here.

+

This hypha has no attachment, you can upload it here. What are attachments?

{% else %} -

You can manage the hypha's attachment on this page.

+

You can manage the hypha's attachment on this page. What are attachments?

{% endif %}
diff --git a/views/readers.qtpl.go b/views/readers.qtpl.go index aa75361..cf44486 100644 --- a/views/readers.qtpl.go +++ b/views/readers.qtpl.go @@ -57,7 +57,7 @@ func StreamAttachmentMenuHTML(qw422016 *qt422016.Writer, rq *http.Request, h *hy //line views/readers.qtpl:14 qw422016.N().S(`
-
+

Attachment of `) //line views/readers.qtpl:17 qw422016.E().S(util.BeautifulName(h.Name)) @@ -68,13 +68,13 @@ func StreamAttachmentMenuHTML(qw422016 *qt422016.Writer, rq *http.Request, h *hy if h.BinaryPath == "" { //line views/readers.qtpl:18 qw422016.N().S(` -

This hypha has no attachment, you can upload it here.

+

This hypha has no attachment, you can upload it here. What are attachments?

`) //line views/readers.qtpl:20 } else { //line views/readers.qtpl:20 qw422016.N().S(` -

You can manage the hypha's attachment on this page.

+

You can manage the hypha's attachment on this page. What are attachments?

`) //line views/readers.qtpl:22 } From bea80887f45d5930e293cb34dee62ce885428b59 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Mon, 12 Jul 2021 14:58:20 +0500 Subject: [PATCH 4/7] Add some styling to help Now it looks more like usual hyphae --- help/en/attachment.myco | 2 +- help/en/hypha.myco | 4 +- help/en/index.myco | 11 +- views/stuff.qtpl | 36 ++++ views/stuff.qtpl.go | 413 ++++++++++++++++++++++++++-------------- web/stuff.go | 28 ++- 6 files changed, 346 insertions(+), 148 deletions(-) diff --git a/help/en/attachment.myco b/help/en/attachment.myco index 2f866e9..c55bb14 100644 --- a/help/en/attachment.myco +++ b/help/en/attachment.myco @@ -1,4 +1,4 @@ -# Attachment +# Help: Attachment In hyphae, an **attachment** is some content represented by something that is not [[/help/en/mycomarkup | Mycomarkup]]. Usually, an image, a video, or an audio. ## Supported attachment types diff --git a/help/en/hypha.myco b/help/en/hypha.myco index 51b9cb9..97281da 100644 --- a/help/en/hypha.myco +++ b/help/en/hypha.myco @@ -1,5 +1,5 @@ -# Hypha -**Hypha** (//plural:// hyphae) is the main content unit used in Mycorrhiza Wiki. +# Help: Hypha +A **hypha** (//plural:// hyphae) is the main content unit used in Mycorrhiza Wiki. ## The structure of hypha A hypha consists of two parts: diff --git a/help/en/index.myco b/help/en/index.myco index c0c5062..50a5921 100644 --- a/help/en/index.myco +++ b/help/en/index.myco @@ -1,9 +1,12 @@ +# Help This is Mycorrhiza Wiki built-in documentation. Hope you are doing well ☺️ -Here are the topics covered by the documentation: -* [[/help/en/hypha | Hypha]] -** [[/help/en/attachment | Attachment]] +See the section on the right (if you are on computer) or below (if you are on mobile) to see what topics are covered by the documentation. -Thanks for reading! \ No newline at end of file +Thanks for reading! + +---- + +You might want to contribute to the documentation. Open a pull-request on [[https://github.com/bouncepaw/mycorrhiza | GitHub]] if you know how to. \ No newline at end of file diff --git a/views/stuff.qtpl b/views/stuff.qtpl index 0bc1d0b..ddd18d1 100644 --- a/views/stuff.qtpl +++ b/views/stuff.qtpl @@ -44,6 +44,42 @@ {% endfunc %} +{% func HelpHTML(content string) %} +
+
+
+ {%s= content %} +
+
+{%s= helpTopicsHTML() %} +
+{% endfunc %} + +{% func HelpEmptyErrorHTML() %} +

This entry does not exist!

+

Try finding a different entry that would help you.

+

If you want to write this entry by yourself, consider contributing to Mycorrhiza Wiki directly.

+{% endfunc %} + +{% func helpTopicsHTML() %} + +{% endfunc %} + {% func UserListHTML() %}
diff --git a/views/stuff.qtpl.go b/views/stuff.qtpl.go index ba8a00d..487218f 100644 --- a/views/stuff.qtpl.go +++ b/views/stuff.qtpl.go @@ -142,14 +142,151 @@ func BaseHTML(title, body string, u *user.User, headElements ...string) string { } //line views/stuff.qtpl:47 -func StreamUserListHTML(qw422016 *qt422016.Writer) { +func StreamHelpHTML(qw422016 *qt422016.Writer, content string) { //line views/stuff.qtpl:47 qw422016.N().S(`
+
+
+ `) +//line views/stuff.qtpl:51 + qw422016.N().S(content) +//line views/stuff.qtpl:51 + qw422016.N().S(` +
+
+`) +//line views/stuff.qtpl:54 + qw422016.N().S(helpTopicsHTML()) +//line views/stuff.qtpl:54 + qw422016.N().S(` +
+`) +//line views/stuff.qtpl:56 +} + +//line views/stuff.qtpl:56 +func WriteHelpHTML(qq422016 qtio422016.Writer, content string) { +//line views/stuff.qtpl:56 + qw422016 := qt422016.AcquireWriter(qq422016) +//line views/stuff.qtpl:56 + StreamHelpHTML(qw422016, content) +//line views/stuff.qtpl:56 + qt422016.ReleaseWriter(qw422016) +//line views/stuff.qtpl:56 +} + +//line views/stuff.qtpl:56 +func HelpHTML(content string) string { +//line views/stuff.qtpl:56 + qb422016 := qt422016.AcquireByteBuffer() +//line views/stuff.qtpl:56 + WriteHelpHTML(qb422016, content) +//line views/stuff.qtpl:56 + qs422016 := string(qb422016.B) +//line views/stuff.qtpl:56 + qt422016.ReleaseByteBuffer(qb422016) +//line views/stuff.qtpl:56 + return qs422016 +//line views/stuff.qtpl:56 +} + +//line views/stuff.qtpl:58 +func StreamHelpEmptyErrorHTML(qw422016 *qt422016.Writer) { +//line views/stuff.qtpl:58 + qw422016.N().S(` +

This entry does not exist!

+

Try finding a different entry that would help you.

+

If you want to write this entry by yourself, consider contributing to Mycorrhiza Wiki directly.

+`) +//line views/stuff.qtpl:62 +} + +//line views/stuff.qtpl:62 +func WriteHelpEmptyErrorHTML(qq422016 qtio422016.Writer) { +//line views/stuff.qtpl:62 + qw422016 := qt422016.AcquireWriter(qq422016) +//line views/stuff.qtpl:62 + StreamHelpEmptyErrorHTML(qw422016) +//line views/stuff.qtpl:62 + qt422016.ReleaseWriter(qw422016) +//line views/stuff.qtpl:62 +} + +//line views/stuff.qtpl:62 +func HelpEmptyErrorHTML() string { +//line views/stuff.qtpl:62 + qb422016 := qt422016.AcquireByteBuffer() +//line views/stuff.qtpl:62 + WriteHelpEmptyErrorHTML(qb422016) +//line views/stuff.qtpl:62 + qs422016 := string(qb422016.B) +//line views/stuff.qtpl:62 + qt422016.ReleaseByteBuffer(qb422016) +//line views/stuff.qtpl:62 + return qs422016 +//line views/stuff.qtpl:62 +} + +//line views/stuff.qtpl:64 +func streamhelpTopicsHTML(qw422016 *qt422016.Writer) { +//line views/stuff.qtpl:64 + qw422016.N().S(` + +`) +//line views/stuff.qtpl:81 +} + +//line views/stuff.qtpl:81 +func writehelpTopicsHTML(qq422016 qtio422016.Writer) { +//line views/stuff.qtpl:81 + qw422016 := qt422016.AcquireWriter(qq422016) +//line views/stuff.qtpl:81 + streamhelpTopicsHTML(qw422016) +//line views/stuff.qtpl:81 + qt422016.ReleaseWriter(qw422016) +//line views/stuff.qtpl:81 +} + +//line views/stuff.qtpl:81 +func helpTopicsHTML() string { +//line views/stuff.qtpl:81 + qb422016 := qt422016.AcquireByteBuffer() +//line views/stuff.qtpl:81 + writehelpTopicsHTML(qb422016) +//line views/stuff.qtpl:81 + qs422016 := string(qb422016.B) +//line views/stuff.qtpl:81 + qt422016.ReleaseByteBuffer(qb422016) +//line views/stuff.qtpl:81 + return qs422016 +//line views/stuff.qtpl:81 +} + +//line views/stuff.qtpl:83 +func StreamUserListHTML(qw422016 *qt422016.Writer) { +//line views/stuff.qtpl:83 + qw422016.N().S(` +

List of users

`) -//line views/stuff.qtpl:52 +//line views/stuff.qtpl:88 var ( admins = make([]string, 0) moderators = make([]string, 0) @@ -166,345 +303,345 @@ func StreamUserListHTML(qw422016 *qt422016.Writer) { } } -//line views/stuff.qtpl:67 +//line views/stuff.qtpl:103 qw422016.N().S(`

Admins

    `) -//line views/stuff.qtpl:70 +//line views/stuff.qtpl:106 for _, name := range admins { -//line views/stuff.qtpl:70 +//line views/stuff.qtpl:106 qw422016.N().S(`
  1. `) -//line views/stuff.qtpl:71 +//line views/stuff.qtpl:107 qw422016.E().S(name) -//line views/stuff.qtpl:71 +//line views/stuff.qtpl:107 qw422016.N().S(`
  2. `) -//line views/stuff.qtpl:72 +//line views/stuff.qtpl:108 } -//line views/stuff.qtpl:72 +//line views/stuff.qtpl:108 qw422016.N().S(`

Moderators

    `) -//line views/stuff.qtpl:76 +//line views/stuff.qtpl:112 for _, name := range moderators { -//line views/stuff.qtpl:76 +//line views/stuff.qtpl:112 qw422016.N().S(`
  1. `) -//line views/stuff.qtpl:77 +//line views/stuff.qtpl:113 qw422016.E().S(name) -//line views/stuff.qtpl:77 +//line views/stuff.qtpl:113 qw422016.N().S(`
  2. `) -//line views/stuff.qtpl:78 +//line views/stuff.qtpl:114 } -//line views/stuff.qtpl:78 +//line views/stuff.qtpl:114 qw422016.N().S(`

Editors

    `) -//line views/stuff.qtpl:82 +//line views/stuff.qtpl:118 for _, name := range editors { -//line views/stuff.qtpl:82 +//line views/stuff.qtpl:118 qw422016.N().S(`
  1. `) -//line views/stuff.qtpl:83 +//line views/stuff.qtpl:119 qw422016.E().S(name) -//line views/stuff.qtpl:83 +//line views/stuff.qtpl:119 qw422016.N().S(`
  2. `) -//line views/stuff.qtpl:84 +//line views/stuff.qtpl:120 } -//line views/stuff.qtpl:84 +//line views/stuff.qtpl:120 qw422016.N().S(`
`) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 } -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 func WriteUserListHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 StreamUserListHTML(qw422016) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 } -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 func UserListHTML() string { -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 WriteUserListHTML(qb422016) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 return qs422016 -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:124 } -//line views/stuff.qtpl:90 +//line views/stuff.qtpl:126 func StreamHyphaListHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:90 +//line views/stuff.qtpl:126 qw422016.N().S(`

List of hyphae

This wiki has `) -//line views/stuff.qtpl:94 +//line views/stuff.qtpl:130 qw422016.N().D(hyphae.Count()) -//line views/stuff.qtpl:94 +//line views/stuff.qtpl:130 qw422016.N().S(` hyphae.

    `) -//line views/stuff.qtpl:96 +//line views/stuff.qtpl:132 for h := range hyphae.YieldExistingHyphae() { -//line views/stuff.qtpl:96 +//line views/stuff.qtpl:132 qw422016.N().S(`
  • `) -//line views/stuff.qtpl:98 +//line views/stuff.qtpl:134 qw422016.E().S(util.BeautifulName(h.Name)) -//line views/stuff.qtpl:98 +//line views/stuff.qtpl:134 qw422016.N().S(` `) -//line views/stuff.qtpl:99 +//line views/stuff.qtpl:135 if h.BinaryPath != "" { -//line views/stuff.qtpl:99 +//line views/stuff.qtpl:135 qw422016.N().S(` `) -//line views/stuff.qtpl:100 +//line views/stuff.qtpl:136 qw422016.E().S(filepath.Ext(h.BinaryPath)[1:]) -//line views/stuff.qtpl:100 +//line views/stuff.qtpl:136 qw422016.N().S(` `) -//line views/stuff.qtpl:101 +//line views/stuff.qtpl:137 } -//line views/stuff.qtpl:101 +//line views/stuff.qtpl:137 qw422016.N().S(`
  • `) -//line views/stuff.qtpl:103 +//line views/stuff.qtpl:139 } -//line views/stuff.qtpl:103 +//line views/stuff.qtpl:139 qw422016.N().S(`
`) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 } -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 func WriteHyphaListHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 StreamHyphaListHTML(qw422016) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 } -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 func HyphaListHTML() string { -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 WriteHyphaListHTML(qb422016) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 return qs422016 -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:143 } -//line views/stuff.qtpl:109 +//line views/stuff.qtpl:145 func StreamAboutHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:109 +//line views/stuff.qtpl:145 qw422016.N().S(`

About `) -//line views/stuff.qtpl:113 +//line views/stuff.qtpl:149 qw422016.E().S(cfg.WikiName) -//line views/stuff.qtpl:113 +//line views/stuff.qtpl:149 qw422016.N().S(`

See /list for information about hyphae on this wiki.

`) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 } -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 func WriteAboutHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 StreamAboutHTML(qw422016) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 } -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 func AboutHTML() string { -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 WriteAboutHTML(qb422016) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 return qs422016 -//line views/stuff.qtpl:131 +//line views/stuff.qtpl:167 } -//line views/stuff.qtpl:133 +//line views/stuff.qtpl:169 func StreamCommonScripts(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:133 +//line views/stuff.qtpl:169 qw422016.N().S(` `) -//line views/stuff.qtpl:134 +//line views/stuff.qtpl:170 for _, scriptPath := range cfg.CommonScripts { -//line views/stuff.qtpl:134 +//line views/stuff.qtpl:170 qw422016.N().S(` `) -//line views/stuff.qtpl:136 +//line views/stuff.qtpl:172 } -//line views/stuff.qtpl:136 +//line views/stuff.qtpl:172 qw422016.N().S(` `) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 } -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 func WriteCommonScripts(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 StreamCommonScripts(qw422016) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 } -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 func CommonScripts() string { -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 WriteCommonScripts(qb422016) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 return qs422016 -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:173 } diff --git a/web/stuff.go b/web/stuff.go index b757a97..a914ea5 100644 --- a/web/stuff.go +++ b/web/stuff.go @@ -9,6 +9,7 @@ import ( "log" "math/rand" "net/http" + "strings" "github.com/bouncepaw/mycorrhiza/cfg" "github.com/bouncepaw/mycorrhiza/files" @@ -39,9 +40,24 @@ func handlerHelp(w http.ResponseWriter, rq *http.Request) { } content, err := help.Get(rq.URL.Path[6:]) // Drop /help/ + if err != nil && strings.HasPrefix(err.Error(), "open") { + w.WriteHeader(http.StatusNotFound) + _, _ = io.WriteString( + w, + views.BaseHTML("Entry not found", + views.HelpHTML(views.HelpEmptyErrorHTML()), + user.FromRequest(rq)), + ) + return + } if err != nil { - // TODO: proper error reporting that makes sense - httpErr(w, http.StatusForbidden, cfg.HomeHypha, err.Error(), err.Error()) + w.WriteHeader(http.StatusInternalServerError) + _, _ = io.WriteString( + w, + views.BaseHTML(err.Error(), + views.HelpHTML(err.Error()), + user.FromRequest(rq)), + ) return } @@ -50,7 +66,13 @@ func handlerHelp(w http.ResponseWriter, rq *http.Request) { ast := mycomarkup.BlockTree(ctx) result := mycomarkup.BlocksToHTML(ctx, ast) // TODO: styled output idk - _, _ = io.WriteString(w, result) + w.WriteHeader(http.StatusOK) + _, _ = io.WriteString( + w, + views.BaseHTML("Help", + views.HelpHTML(result), + user.FromRequest(rq)), + ) } // handlerList shows a list of all hyphae in the wiki in random order. From b1489cf11f07080db4eac529b181e3e2498f9383 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Mon, 12 Jul 2021 15:01:53 +0500 Subject: [PATCH 5/7] Move the main help page It was on /help/en/index, now it is on both /help/en and /help --- help/{en/index.myco => en.myco} | 0 help/help.go | 5 ++++- views/stuff.qtpl | 2 +- views/stuff.qtpl.go | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) rename help/{en/index.myco => en.myco} (100%) diff --git a/help/en/index.myco b/help/en.myco similarity index 100% rename from help/en/index.myco rename to help/en.myco diff --git a/help/help.go b/help/help.go index 06fc6f1..bc12477 100644 --- a/help/help.go +++ b/help/help.go @@ -5,11 +5,14 @@ import ( "embed" ) -//go:embed en +//go:embed en en.myco var fs embed.FS // Get determines what help text you need and returns it. The path is a substring from URL, it follows this form: // / func Get(path string) ([]byte, error) { + if path == "" { + return Get("en") + } return fs.ReadFile(path + ".myco") } diff --git a/views/stuff.qtpl b/views/stuff.qtpl index ddd18d1..f068f16 100644 --- a/views/stuff.qtpl +++ b/views/stuff.qtpl @@ -66,7 +66,7 @@

Help topics

  • - Main + Main
  • Hypha diff --git a/views/stuff.qtpl.go b/views/stuff.qtpl.go index 487218f..b330c4f 100644 --- a/views/stuff.qtpl.go +++ b/views/stuff.qtpl.go @@ -236,7 +236,7 @@ func streamhelpTopicsHTML(qw422016 *qt422016.Writer) {

    Help topics

    • - Main + Main
    • Hypha From b955e4816a00eed173ce6d7400ae4eb2a7c92adf Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Mon, 12 Jul 2021 15:13:12 +0500 Subject: [PATCH 6/7] Make the help topics sidebar look acceptable --- static/default.css | 15 +++++++++++++-- views/stuff.qtpl | 2 +- views/stuff.qtpl.go | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/static/default.css b/static/default.css index 3928611..4c04d32 100644 --- a/static/default.css +++ b/static/default.css @@ -74,7 +74,7 @@ header { width: 100%; margin-bottom: 1rem; } .layout { display: grid; grid-template-columns: auto 1fr; column-gap: 1rem; margin: 0 1rem; row-gap: 1rem; } .main-width { margin: 0; } main { grid-column: 1 / span 1; grid-row: 1 / span 2; } - .sister-hyphae, .edit-toolbar { grid-column: 2 / span 1; grid-row: 1 / span 1; } + .sister-hyphae, .edit-toolbar, .help-topics { grid-column: 2 / span 1; grid-row: 1 / span 1; } .layout-card { width: 100%; } .edit-toolbar__buttons {display: grid; } } @@ -89,7 +89,7 @@ header { width: 100%; margin-bottom: 1rem; } .main-width { margin: 0 auto; } .backlinks { grid-column: 1 / span 1; margin-right: 0; } main { grid-column: 2 / span 1; } - .sister-hyphae, .edit-toolbar { grid-column: 3 / span 1; margin-left: 0; } + .sister-hyphae, .edit-toolbar, .help-topics { grid-column: 3 / span 1; margin-left: 0; } .edit-toolbar__buttons { grid-template-columns: 1fr; } .backlinks__title { text-align: right; } @@ -594,3 +594,14 @@ kbd { left: -1.6rem; top: .1rem; } + +/* + * Help topics sidebar + */ +.help-topics__list { + margin: .5rem 0; + padding-left: .5rem; +} +.help-topics__list ul { + padding-left: 1rem; +} \ No newline at end of file diff --git a/views/stuff.qtpl b/views/stuff.qtpl index f068f16..c34753f 100644 --- a/views/stuff.qtpl +++ b/views/stuff.qtpl @@ -64,7 +64,7 @@ {% func helpTopicsHTML() %}