GOX / LIBRARY
Examples
Go libraries. GOX components. Code for your next project.
Markdown
Render documents as HTML with a Go library.
Source
1## Hello, GOX
2
3A **small document**, rendered with Go.
4
5- Write Markdown
6- Render HTML
7
8[Read the docs](/docs)
Result
1. Add the Go library
Run this command from your project root.
gox get github.com/yuin/[email protected]
2. Copy the component
Save the complete GOX source from the Code tab as pages/@components/markdown.gox.
3. Create the source file
content/examples/welcome.md
1## Hello, GOX
2
3A **small document**, rendered with Go.
4
5- Write Markdown
6- Render HTML
7
8[Read the docs](/docs)
Use it in your page
module index
import (
"github.com/gox-lang/gox"
markdown "@components/markdown.gox"
)
func GET(ctx *gox.Context) gox.Page {
return <main>
<&markdown.Markdown src="content/examples/welcome.md" />
</main>
}
When the source changes
The memory cache avoids reading or compiling on repeated renders. After replacing the file, invalidate its entry:
markdown.Invalidate("content/examples/welcome.md") Use local project-owned Markdown. Raw HTML and dangerous links are disabled by Goldmark's default renderer.
pages/@components/markdown.gox
This is the complete component used by the live preview. Copy this single GOX file into your project.
module markdown
import (
"bytes"
"log"
"os"
"path/filepath"
"sync"
"github.com/gox-lang/gox"
"github.com/yuin/goldmark"
)
var cache map[string]string = make(map[string]string)
var cacheMu sync.RWMutex
func Markdown(src string) gox.Component {
rendered, err := Render(src)
if err != nil {
log.Printf("Markdown: %v", err)
return <p>Markdown unavailable</p>
}
return <div class="gox-markdown">{{< rendered >}}</div>
}
// Use local project files. Raw HTML and unsafe links remain disabled.
func Render(src string) (string, error) {
key := filepath.Clean(src)
cacheMu.RLock()
rendered, ready := cache[key]
cacheMu.RUnlock()
if ready {
return rendered, nil
}
cacheMu.Lock()
defer cacheMu.Unlock()
if rendered, ready := cache[key]; ready {
return rendered, nil
}
source, err := os.ReadFile(key)
if err != nil {
return "", err
}
var output bytes.Buffer
if err := goldmark.Convert(source, &output); err != nil {
return "", err
}
rendered = output.String()
cache[key] = rendered
return rendered, nil
}
// Call after replacing a document so the next render reads it again.
func Invalidate(src string) {
cacheMu.Lock()
defer cacheMu.Unlock()
delete(cache, filepath.Clean(src))
}
Live exampleGOX / Go