summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/methods.go14
-rw-r--r--src/render/url.go168
2 files changed, 178 insertions, 4 deletions
diff --git a/src/render/methods.go b/src/render/methods.go
index 9b5a41e..ee22dfd 100644
--- a/src/render/methods.go
+++ b/src/render/methods.go
@@ -56,6 +56,8 @@ type Methods struct {
ctx context.Context
url *url.URL
publicURL *url.URL
+ httpURL *url.URL
+ geminiURL *url.URL
geminiGatewayURL *url.URL
postStore post.Store
postAssetStore asset.Store
@@ -71,6 +73,8 @@ func NewMethods(
ctx context.Context,
url *url.URL,
publicURL *url.URL,
+ httpURL *url.URL,
+ geminiURL *url.URL,
geminiGatewayURL *url.URL,
postStore post.Store,
postAssetStore asset.Store,
@@ -81,6 +85,8 @@ func NewMethods(
ctx,
url,
publicURL,
+ httpURL,
+ geminiURL,
geminiGatewayURL,
postStore,
postAssetStore,
@@ -91,6 +97,10 @@ func NewMethods(
}
}
+func (m *Methods) RootURL() URLBuilder {
+ return NewURLBuilder(m.publicURL, m.httpURL, m.geminiURL)
+}
+
func (m *Methods) GetTags() ([]string, error) {
return m.postStore.GetTags()
}
@@ -263,7 +273,3 @@ func (m *Methods) GetPath() (string, error) {
}
func (m *Methods) Add(a, b int) int { return a + b }
-
-func (m *Methods) URLIsSafe(s string) template.URL {
- return template.URL(s)
-}
diff --git a/src/render/url.go b/src/render/url.go
new file mode 100644
index 0000000..eb9756b
--- /dev/null
+++ b/src/render/url.go
@@ -0,0 +1,168 @@
+package render
+
+import (
+ "html/template"
+ "net/url"
+ "path"
+ "strconv"
+ "strings"
+)
+
+const (
+ urlBasePublic = iota
+ urlBaseHTTP
+ urlBaseGemini
+)
+
+// URLBuilder is used to construct a URL for the site. The API of URLBuilder is
+// designed to be convenient to used from a go template.
+type URLBuilder struct {
+ publicURL, httpURL, geminiURL *url.URL
+
+ abs bool
+ base int
+ path, method string
+ page int
+}
+
+func NewURLBuilder(publicURL, httpURL, geminiURL *url.URL) URLBuilder {
+ return URLBuilder{
+ publicURL: publicURL,
+ httpURL: httpURL,
+ geminiURL: geminiURL,
+ }
+}
+
+func (b URLBuilder) String() string {
+ var u *url.URL
+ switch b.base {
+ case urlBasePublic:
+ u = b.publicURL
+ case urlBaseHTTP:
+ u = b.httpURL
+ case urlBaseGemini:
+ u = b.geminiURL
+ }
+
+ u = u.JoinPath(b.path)
+
+ if u.Scheme == "gemini" &&
+ u.Host == b.geminiURL.Host &&
+ !strings.HasSuffix(u.Path, "/") &&
+ path.Ext(u.Path) == "" {
+ u.Path += ".gmi"
+ }
+
+ {
+ query := url.Values{}
+ if b.method != "" {
+ query.Set("method", b.method)
+ }
+ if b.page > 0 {
+ query.Set("page", strconv.Itoa(b.page))
+ }
+ if len(query) > 0 {
+ u.RawQuery = query.Encode()
+ }
+ }
+
+ if abs := b.abs || u.Scheme != b.publicURL.Scheme; !abs {
+ u.Scheme = ""
+ u.Host = ""
+ }
+
+ return u.String()
+}
+
+func (b URLBuilder) HTMLSafe() template.URL {
+ return template.URL(b.String())
+}
+
+// Absolute returns a URLBuilder which will always construct a URL containing
+// scheme and host.
+func (b URLBuilder) Absolute() URLBuilder {
+ b.abs = true
+ return b
+}
+
+func (b URLBuilder) Gemini() URLBuilder {
+ b.base = urlBaseGemini
+ return b
+}
+
+func (b URLBuilder) HTTP() URLBuilder {
+ b.base = urlBaseHTTP
+ return b
+}
+
+func (b URLBuilder) Assets() URLBuilder {
+ b.path = "assets/"
+ return b
+}
+
+func (b URLBuilder) Asset(id string) URLBuilder {
+ b.path = "assets/" + id
+ return b
+}
+
+func (b URLBuilder) Posts() URLBuilder {
+ b.path = "posts/"
+ return b
+}
+
+func (b URLBuilder) Post(id string) URLBuilder {
+ b.path = "posts/" + id
+ return b
+}
+
+func (b URLBuilder) Drafts() URLBuilder {
+ b.base = urlBaseHTTP
+ b.path = "drafts/"
+ return b
+}
+
+func (b URLBuilder) Draft(id string) URLBuilder {
+ b.base = urlBaseHTTP
+ b.path = "drafts/" + id
+ return b
+}
+
+func (b URLBuilder) Static(staticPath string) URLBuilder {
+ b.base = urlBaseHTTP
+ b.path = path.Join("static", staticPath)
+ return b
+}
+
+func (b URLBuilder) Path(p string) URLBuilder {
+ b.path = p
+ return b
+}
+
+func (b URLBuilder) Page(page int) URLBuilder {
+ b.page = page
+ return b
+}
+
+func (b URLBuilder) MethodEdit() URLBuilder {
+ b.base = urlBaseHTTP
+ b.method = "edit"
+ return b
+}
+
+func (b URLBuilder) MethodManage() URLBuilder {
+ b.base = urlBaseHTTP
+ b.method = "manage"
+ return b
+}
+
+func (b URLBuilder) MethodDelete() URLBuilder {
+ b.base = urlBaseHTTP
+ b.method = "delete"
+ return b
+}
+
+func (b URLBuilder) MethodPreview() URLBuilder {
+ b.base = urlBaseHTTP
+ b.method = "preview"
+ return b
+}