diff options
author | Brian Picciano <mediocregopher@gmail.com> | 2024-05-18 18:29:19 +0200 |
---|---|---|
committer | Brian Picciano <mediocregopher@gmail.com> | 2024-05-18 18:29:19 +0200 |
commit | 0665d0c65974533fbd313f4e0b062b5103057aeb (patch) | |
tree | 5287795eed9767bd959a5139b77ef78b4024216d | |
parent | ffa26298c95451639a6e01db6692d02d50b3d518 (diff) |
Replace all URL rendering within templates by a URLConstructor
-rw-r--r-- | src/gmi/gmi.go | 4 | ||||
-rw-r--r-- | src/gmi/tpl.go | 2 | ||||
-rw-r--r-- | src/gmi/tpl/feed.xml | 8 | ||||
-rw-r--r-- | src/gmi/tpl/footer.gmi | 4 | ||||
-rw-r--r-- | src/gmi/tpl/index.gmi | 8 | ||||
-rw-r--r-- | src/gmi/tpl/posts/index.gmi | 11 | ||||
-rw-r--r-- | src/gmi/tpl/posts/post.gmi | 10 | ||||
-rw-r--r-- | src/http/http.go | 5 | ||||
-rw-r--r-- | src/http/posts.go | 6 | ||||
-rw-r--r-- | src/http/tpl.go | 2 | ||||
-rw-r--r-- | src/http/tpl/admin.html | 6 | ||||
-rw-r--r-- | src/http/tpl/base.html | 22 | ||||
-rw-r--r-- | src/http/tpl/draft-posts-manage.html | 14 | ||||
-rw-r--r-- | src/http/tpl/follow.html | 2 | ||||
-rw-r--r-- | src/http/tpl/gemini-cta.html | 6 | ||||
-rw-r--r-- | src/http/tpl/image.html | 4 | ||||
-rw-r--r-- | src/http/tpl/index.html | 6 | ||||
-rw-r--r-- | src/http/tpl/post-assets-manage.html | 8 | ||||
-rw-r--r-- | src/http/tpl/post-edit.html | 16 | ||||
-rw-r--r-- | src/http/tpl/post.html | 4 | ||||
-rw-r--r-- | src/http/tpl/posts-manage.html | 14 | ||||
-rw-r--r-- | src/http/tpl/posts.html | 8 | ||||
-rw-r--r-- | src/render/methods.go | 14 | ||||
-rw-r--r-- | src/render/url.go | 168 |
24 files changed, 269 insertions, 83 deletions
diff --git a/src/gmi/gmi.go b/src/gmi/gmi.go index e37ca74..89c35bc 100644 --- a/src/gmi/gmi.go +++ b/src/gmi/gmi.go @@ -58,7 +58,9 @@ func (p *Params) SetupCfg(cfg *cfg.Cfg) { var err error - *publicURLStr = strings.TrimSuffix(*publicURLStr, "/") + if !strings.HasSuffix(*publicURLStr, "/") { + *publicURLStr += "/" + } if p.PublicURL, err = url.Parse(*publicURLStr); err != nil { return fmt.Errorf("parsing -gemini-public-url: %w", err) diff --git a/src/gmi/tpl.go b/src/gmi/tpl.go index f6c1754..cdf9535 100644 --- a/src/gmi/tpl.go +++ b/src/gmi/tpl.go @@ -175,6 +175,8 @@ func (a *api) tplHandler() (gemini.Handler, error) { ctx, r.URL, a.params.PublicURL, + a.params.HTTPPublicURL, + a.params.PublicURL, // geminiURL a.params.HTTPGeminiGatewayURL, a.params.PostStore, nil, // asset.Store, not supported by gemini endpoint diff --git a/src/gmi/tpl/feed.xml b/src/gmi/tpl/feed.xml index aa596b7..2935327 100644 --- a/src/gmi/tpl/feed.xml +++ b/src/gmi/tpl/feed.xml @@ -3,11 +3,11 @@ <?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"> <title>mediocregopher's lil web corner</title> - <id>{{ BlogGeminiURL "/" }}</id> + <id>{{ .RootURL.Absolute }}</id> {{ if gt (len $posts) 0 -}} <updated>{{ (index $posts 0).PublishedAt.Format "2006-01-02T15:04:05Z07:00" }}</updated> {{ end -}} - <link href="{{ BlogGeminiURL "/" }}"></link> + <link href="{{ .RootURL.Absolute }}"></link> <author> <name>mediocregopher</name> </author> @@ -15,8 +15,8 @@ <entry> <title>{{ .Title }}</title> <updated>{{ .PublishedAt.Format "2006-01-02T15:04:05Z07:00" }}</updated> - <id>{{ PostURLAbs .ID }}</id> - <link href="{{ PostURLAbs .ID }}" rel="alternate"></link> + <id>{{ $.RootURL.Absolute.Post .ID }}</id> + <link href="{{ $.RootURL.Absolute.Post .ID }}" rel="alternate"></link> {{ if .Description -}} <summary type="html">{{ .Description }}</summary> {{ end -}} diff --git a/src/gmi/tpl/footer.gmi b/src/gmi/tpl/footer.gmi index 15ee7b6..04a6562 100644 --- a/src/gmi/tpl/footer.gmi +++ b/src/gmi/tpl/footer.gmi @@ -1,10 +1,10 @@ ======================================== {{ if ne .GetPath "index.gmi" -}} -=> {{ BlogURL "/" }} Home +=> {{ .RootURL }} Home {{ end -}} => https://dev.mediocregopher.com/mediocre-blog.git Source -=> {{ BlogURL "wtfpl.txt" }} License for all content, if you must have one +=> {{ .RootURL.Path "wtfpl.txt" }} License for all content, if you must have one diff --git a/src/gmi/tpl/index.gmi b/src/gmi/tpl/index.gmi index b854481..6a70607 100644 --- a/src/gmi/tpl/index.gmi +++ b/src/gmi/tpl/index.gmi @@ -2,16 +2,16 @@ This here's my little corner of the web, where I publish posts about projects I'm working on and things that interest me (which you can follow, if you like). -=> {{ BlogURL "posts/" }} Browse all posts +=> {{ .RootURL.Posts }} Browse all posts {{ $getPostsRes := .GetPosts 0 1 -}} {{ if gt (len $getPostsRes.Posts) 0 -}} {{ $post := index $getPostsRes.Posts 0 -}} -=> {{ PostURL $post.ID }} (Latest post: {{ $post.Title }}) +=> {{ .RootURL.Post $post.ID }} (Latest post: {{ $post.Title }}) {{ end -}} -=> {{ BlogURL "feed.xml" }} RSS feed +=> {{ .RootURL.Path "feed.xml" }} RSS feed Below you'll find other information and links related to me. @@ -21,7 +21,7 @@ Feel free to hmu over email or Signal if you'd like to get in touch. => mailto:me@mediocregopher Email: me@mediocregopher.com -=> {{ BlogURL "me@mediocregopher.com.gpg" }} GPG Key +=> {{ .RootURL.Path "me@mediocregopher.com.gpg" }} GPG Key => https://signal.me/#eu/x5psueq2E3WfFwwEgFDoWeSZx9k4u8vFBaiMSa4Lo0cvluHkb-dIpJp1wfdJsdie Signal: mediocregopher.01 diff --git a/src/gmi/tpl/posts/index.gmi b/src/gmi/tpl/posts/index.gmi index 2ff296a..873222b 100644 --- a/src/gmi/tpl/posts/index.gmi +++ b/src/gmi/tpl/posts/index.gmi @@ -1,29 +1,28 @@ # 👻 mediocregopher's Posts {{ $page := .GetQueryIntValue "page" 0 -}} +{{ $getPostsRes := .GetPosts $page 20 -}} {{ if eq $page 0 -}} Here you'll find an archive of all published posts. The content varies almost as much as the quality! {{ end -}} -{{ $getPostsRes := .GetPosts $page 20 -}} - {{ if gt $page 0 -}} -=> {{ BlogURL "posts" }}/?page={{ .Add $page -1 }} Previous Page +=> {{ .RootURL.Posts.Page (.Add $page -1) }} Previous Page {{ end -}} {{ range $getPostsRes.Posts -}} -=> {{ PostURL .ID }} {{ .PublishedAt.Format "2006-01-02" }} - {{ .Title }} +=> {{ $.RootURL.Post .ID }} {{ .PublishedAt.Format "2006-01-02" }} - {{ .Title }} {{ end -}} {{ if $getPostsRes.HasMore -}} -=> {{ BlogURL "posts" }}/?page={{ .Add $page 1 }} Next page +=> {{ .RootURL.Posts.Page (.Add $page 1) }} Next page {{ end }} ======================================== -=> {{ BlogURL "feed.xml" }} RSS feed +=> {{ .RootURL.Path "feed.xml" }} RSS feed {{ template "footer.gmi" . }} diff --git a/src/gmi/tpl/posts/post.gmi b/src/gmi/tpl/posts/post.gmi index b568044..eafa76c 100644 --- a/src/gmi/tpl/posts/post.gmi +++ b/src/gmi/tpl/posts/post.gmi @@ -3,7 +3,7 @@ {{ if eq $post.Format "md" -}} This post has been translated from it's original markdown format, if it seems busted it might appear better over HTTP: -=> {{ PostHTTPURL $post.ID }} +=> {{ .RootURL.HTTP.Post $post.ID }} {{ end -}} @@ -26,18 +26,18 @@ Published {{ $post.PublishedAt.Format "2006-01-02" }} by mediocregopher This post is part of a series! {{ if $seriesNextPrev.Next -}} -=> {{ BlogURL "posts" }}/{{ $seriesNextPrev.Next.ID }}.gmi Next in the series: {{ $seriesNextPrev.Next.Title }} +=> {{ .RootURL.Post $seriesNextPrev.Next.ID }} Next in the series: {{ $seriesNextPrev.Next.Title }} {{ end -}} {{ if $seriesNextPrev.Previous -}} -=> {{ BlogURL "posts" }}/{{ $seriesNextPrev.Previous.ID }}.gmi Prevous in the series: {{ $seriesNextPrev.Previous.Title }} +=> {{ .RootURL.Post $seriesNextPrev.Previous.ID }} Prevous in the series: {{ $seriesNextPrev.Previous.Title }} {{ end -}} {{ end -}} {{ else }}{{/* newline */}} {{ end }} -=> {{ BlogURL "posts/" }} Browse all posts +=> {{ .RootURL.Posts }} Browse all posts -=> {{ BlogURL "feed.xml" }} RSS feed +=> {{ .RootURL.Path "feed.xml" }} RSS feed {{ template "footer.gmi" . }} diff --git a/src/http/http.go b/src/http/http.go index 9bfed59..93cc043 100644 --- a/src/http/http.go +++ b/src/http/http.go @@ -89,7 +89,10 @@ func (p *Params) SetupCfg(cfg *cfg.Cfg) { return fmt.Errorf("unmarshaling -http-auth-ratelimit: %w", err) } - *publicURLStr = strings.TrimSuffix(*publicURLStr, "/") + if !strings.HasSuffix(*publicURLStr, "/") { + *publicURLStr += "/" + } + if p.PublicURL, err = url.Parse(*publicURLStr); err != nil { return fmt.Errorf("parsing -http-public-url: %w", err) } diff --git a/src/http/posts.go b/src/http/posts.go index 14224f2..42e5b4a 100644 --- a/src/http/posts.go +++ b/src/http/posts.go @@ -40,10 +40,16 @@ func (a *api) postPreprocessFuncImage(args ...string) (string, error) { tpl = txttpl.Must(tpl.Parse(mustReadTplFile("image.html"))) tplPayload := struct { + RootURL render.URLBuilder ID string Descr string Resizable bool }{ + RootURL: render.NewURLBuilder( + a.params.PublicURL, + a.params.PublicURL, // httpURL + a.params.GeminiPublicURL, + ), ID: id, Descr: descr, Resizable: asset.IsImageResizable(id), diff --git a/src/http/tpl.go b/src/http/tpl.go index 2711259..c4afbdc 100644 --- a/src/http/tpl.go +++ b/src/http/tpl.go @@ -135,6 +135,8 @@ func (a *api) newTPLData(r *http.Request, payload interface{}) tplData { r.Context(), r.URL, a.params.PublicURL, + a.params.PublicURL, // httpURL + a.params.GeminiPublicURL, a.params.GeminiGatewayURL, a.params.PostStore, a.params.PostAssetStore, diff --git a/src/http/tpl/admin.html b/src/http/tpl/admin.html index 0b4b4e3..2dfab0f 100644 --- a/src/http/tpl/admin.html +++ b/src/http/tpl/admin.html @@ -7,9 +7,9 @@ mostly left open to inspection, but you will not able to change anything without providing credentials. <ul> - <li><a href="{{ BlogURL "posts?method=manage" }}">Posts</a></li> - <li><a href="{{ BlogURL "assets?method=manage" }}">Assets</a></li> - <li><a href="{{ BlogURL "drafts?method=manage" }}">Drafts</a> (private)</li> + <li><a href="{{ .RootURL.Posts.MethodManage }}">Posts</a></li> + <li><a href="{{ .RootURL.Assets.MethodManage }}">Assets</a></li> + <li><a href="{{ .RootURL.Drafts.MethodManage }}">Drafts</a> (private)</li> </ul> {{ end }} diff --git a/src/http/tpl/base.html b/src/http/tpl/base.html index 47644f7..f0419d5 100644 --- a/src/http/tpl/base.html +++ b/src/http/tpl/base.html @@ -3,12 +3,12 @@ <head> <title>{{ .Title }}</title> - <link rel="stylesheet" type="text/css" href="{{ StaticURL "new.css" }}" /> - <link rel="stylesheet" type="text/css" href="{{ StaticURL "mediocre.css" }}" /> - <link rel="apple-touch-icon" sizes="180x180" href="{{ StaticURL "favicon/apple-touch-icon.png" }}"> - <link rel="icon" type="image/png" sizes="32x32" href="{{ StaticURL "favicon/favicon-32x32.png" }}"> - <link rel="icon" type="image/png" sizes="16x16" href="{{ StaticURL "favicon/favicon-16x16.png" }}"> - <link rel="manifest" href="{{ StaticURL "favicon/site.webmanifest" }}"> + <link rel="stylesheet" type="text/css" href="{{ .RootURL.Static "new.css" }}" /> + <link rel="stylesheet" type="text/css" href="{{ .RootURL.Static "mediocre.css" }}" /> + <link rel="apple-touch-icon" sizes="180x180" href="{{ .RootURL.Static "favicon/apple-touch-icon.png" }}"> + <link rel="icon" type="image/png" sizes="32x32" href="{{ .RootURL.Static "favicon/favicon-32x32.png" }}"> + <link rel="icon" type="image/png" sizes="16x16" href="{{ .RootURL.Static "favicon/favicon-16x16.png" }}"> + <link rel="manifest" href="{{ .RootURL.Static "favicon/site.webmanifest" }}"> </head> <body> @@ -105,17 +105,17 @@ <strong>mediocregopher</strong>'s lil web corner <br/> <br/> - <a href="{{ BlogURL "/" }}">Home</a> + <a href="{{ .RootURL }}">Home</a> // - <a href="{{ BlogURL "/posts" }}">Posts</a> + <a href="{{ .RootURL.Posts }}">Posts</a> / - <a href="{{ BlogURL "follow" }}">Follow</a> + <a href="{{ .RootURL.Path "follow" }}">Follow</a> / - <a href="{{ BlogURL "feed.xml" }}">RSS</a> + <a href="{{ .RootURL.Path "feed.xml" }}">RSS</a> // <a href="https://dev.mediocregopher.com/mediocre-blog.git">Source</a> / - <a href="{{ StaticURL "wtfpl.txt" }}">License</a> + <a href="{{ .RootURL.Static "wtfpl.txt" }}">License</a> </header> {{ template "body" . }} diff --git a/src/http/tpl/draft-posts-manage.html b/src/http/tpl/draft-posts-manage.html index b1b4362..417f716 100644 --- a/src/http/tpl/draft-posts-manage.html +++ b/src/http/tpl/draft-posts-manage.html @@ -1,6 +1,6 @@ {{ define "body" }} - {{ $page := .GetQueryIntValue "p" 0 -}} + {{ $page := .GetQueryIntValue "page" 0 -}} {{ $getPostsRes := .GetDraftPosts $page 20 -}} <script> @@ -11,18 +11,18 @@ </script> <p> - <a href="{{ BlogURL "admin" }}">Back to Admin</a> + <a href="{{ .RootURL.Path "admin" }}">Back to Admin</a> </p> <h1>Drafts</h1> <p> - <a href="{{ BlogURL "drafts" }}?method=edit">New Draft</a> + <a href="{{ .RootURL.Drafts.MethodEdit }}">New Draft</a> </p> {{ if gt $page 0 }} <p> - <a href="?method=manage&p={{ .Add $page -1 }}">< < Previous Page</a> + <a href="{{ .RootURL.Drafts.MethodManage.Page (.Add $page -1) }}">< < Previous Page</a> </p> {{ end }} @@ -32,13 +32,13 @@ <tr> <td>{{ .Title }}</td> <td> - <a href="{{ DraftURL .ID }}?method=edit"> + <a href="{{ ($.RootURL.Draft .ID).MethodEdit }}"> Edit </a> </td> <td> <form - action="{{ DraftURL .ID }}?method=delete" + action="{{ ($.RootURL.Draft .ID).MethodDelete }}" method="POST" > <input @@ -55,7 +55,7 @@ {{ if $getPostsRes.HasMore }} <p> - <a href="?method=manage&p={{ .Add $page 1 }}">Next Page > ></a> + <a href="{{ .RootURL.Drafts.MethodManage.Page (.Add $page 1) }}">Next Page > ></a> </p> {{ end }} diff --git a/src/http/tpl/follow.html b/src/http/tpl/follow.html index 1958f95..091af49 100644 --- a/src/http/tpl/follow.html +++ b/src/http/tpl/follow.html @@ -6,7 +6,7 @@ </p> <p> - <a href="{{ BlogHTTPURL "feed.xml" }}">{{ BlogHTTPURL "feed.xml" }}</a> + <a href="{{ .RootURL.Absolute.Path "feed.xml" }}">{{ .RootURL.Absolute.Path "feed.xml" }}</a> </p> <p> diff --git a/src/http/tpl/gemini-cta.html b/src/http/tpl/gemini-cta.html index 89b8e8b..77c1114 100644 --- a/src/http/tpl/gemini-cta.html +++ b/src/http/tpl/gemini-cta.html @@ -2,11 +2,9 @@ <p> This site can also be accessed via the gemini protocol: - <a href="{{ BlogGeminiURL "/" | .URLIsSafe }}"> - {{ BlogGeminiURL "/" }} - </a> + <a href="{{ .RootURL.Gemini.HTMLSafe }}">{{ .RootURL.Gemini.HTMLSafe }}</a> </p> <p> - <a href="{{ PostURL "gemspace-tour" }}">What is gemini?</a> + <a href="{{ .RootURL.Post "gemspace-tour" }}">What is gemini?</a> </p> diff --git a/src/http/tpl/image.html b/src/http/tpl/image.html index c6c19b3..7778625 100644 --- a/src/http/tpl/image.html +++ b/src/http/tpl/image.html @@ -1,7 +1,7 @@ <div style="text-align: center;"> - <a href="{{ AssetURL .ID }}" target="_blank"> + <a href="{{ .RootURL.Asset .ID }}" target="_blank"> <img - src="{{ AssetURL .ID }}{{ if .Resizable }}?w=800{{ end }}" + src="{{ .RootURL.Asset .ID }}{{ if .Resizable }}?w=800{{ end }}" alt="{{ .Descr }}" /> </a> diff --git a/src/http/tpl/index.html b/src/http/tpl/index.html index 7f6399a..2685f4f 100644 --- a/src/http/tpl/index.html +++ b/src/http/tpl/index.html @@ -2,9 +2,9 @@ <p> This here's my little corner of the web, where I publish - <a href="{{ BlogURL "posts" }}">posts</a> + <a href="{{ .RootURL.Posts }}">posts</a> about projects I'm working on and things that interest me (which you can - <a href="{{ BlogURL "follow" }}">follow</a>, + <a href="{{ .RootURL.Path "follow" }}">follow</a>, if you like). </p> @@ -12,7 +12,7 @@ <p>Feel free to hmu over email or Signal if you'd like to get in touch.</p> <ul> <li>Email: <a href="mailto:me@mediocregopher.com">me@mediocregopher.com</a></li> - <li><a href="{{ StaticURL "me@mediocregopher.com.gpg" }}">GPG Key</a></li> + <li><a href="{{ .RootURL.Static "me@mediocregopher.com.gpg" }}">GPG Key</a></li> <li>Signal: <a href="https://signal.me/#eu/x5psueq2E3WfFwwEgFDoWeSZx9k4u8vFBaiMSa4Lo0cvluHkb-dIpJp1wfdJsdie"> mediocregopher.01 diff --git a/src/http/tpl/post-assets-manage.html b/src/http/tpl/post-assets-manage.html index a0b0da0..7e01ff4 100644 --- a/src/http/tpl/post-assets-manage.html +++ b/src/http/tpl/post-assets-manage.html @@ -3,7 +3,7 @@ {{ $assetIDs := .GetPostAssetIDs }} <p> - <a href="{{ BlogURL "admin" }}">Back to Admin</a> + <a href="{{ .RootURL.Path "admin" }}">Back to Admin</a> </p> <h1>Assets</h1> @@ -15,7 +15,7 @@ overwritten. </p> -<form action="{{ BlogURL "assets/" }}" method="POST" enctype="multipart/form-data"> +<form action="{{ .RootURL.Assets }}" method="POST" enctype="multipart/form-data"> <div class="row"> <div class="four columns"> <input type="text" placeholder="Unique ID" name="id" /> @@ -37,10 +37,10 @@ {{ range $assetIDs }} <tr> - <td><a href="{{ AssetURL . }}">{{ . }}</a></td> + <td><a href="{{ $.RootURL.Asset . }}">{{ . }}</a></td> <td> <form - action="{{ AssetURL . }}?method=delete" + action="{{ ($.RootURL.Asset .).MethodDelete }}" method="POST" style="margin-bottom: 0;" > diff --git a/src/http/tpl/post-edit.html b/src/http/tpl/post-edit.html index 28dcd0e..1c40a3a 100644 --- a/src/http/tpl/post-edit.html +++ b/src/http/tpl/post-edit.html @@ -6,17 +6,17 @@ <p> {{ if .Payload.IsDraft }} - <a href="{{ BlogURL "drafts?method=manage" }}"> + <a href="{{ .RootURL.Drafts.MethodManage }}"> Back to Drafts </a> {{ else }} - <a href="{{ BlogURL "posts?method=manage" }}"> + <a href="{{ .RootURL.Posts.MethodManage }}"> Back to Posts </a> {{ end }} </p> -<form method="POST" action="{{ BlogURL "posts/" }}"> +<form method="POST" action="{{ .RootURL.Posts }}"> <table> @@ -36,7 +36,7 @@ {{ $post.ID }} <input name="id" type="hidden" value="{{ $post.ID }}" /> {{ else }} - <a href="{{ PostURL $post.ID }}">{{ $post.ID }}</a> + <a href="{{ .RootURL.Post $post.ID }}">{{ $post.ID }}</a> <input name="id" type="hidden" value="{{ $post.ID }}" /> {{ end }} </td> @@ -135,12 +135,12 @@ <input type="submit" value="Preview" - formaction="{{ BlogURL "posts/" }}{{ $post.ID }}?method=preview" + formaction="{{ (.RootURL.Post $post.ID).MethodPreview }}" formtarget="_blank" /> {{ if .Payload.IsDraft }} - <input type="submit" value="Save" formaction="{{ BlogURL "drafts/" }}" /> + <input type="submit" value="Save" formaction="{{ .RootURL.Drafts }}" /> <script> @@ -154,12 +154,12 @@ <input type="submit" value="Publish" - formaction="{{ BlogURL "posts/" }}" + formaction="{{ .RootURL.Posts }}" onclick="confirmPublish(event)" /> {{ else }} - <input type="submit" value="Update" formaction="{{ BlogURL "posts/" }}" /> + <input type="submit" value="Update" formaction="{{ .RootURL.Posts }}" /> {{ end }} </p> diff --git a/src/http/tpl/post.html b/src/http/tpl/post.html index 46a24fc..1bda8c9 100644 --- a/src/http/tpl/post.html +++ b/src/http/tpl/post.html @@ -27,7 +27,7 @@ This post is part of a series.<br/> {{ if $seriesNextPrev.Next }} - Next: <a href="{{ PostURL $seriesNextPrev.Next.ID }}">{{ $seriesNextPrev.Next.Title }}</a> + Next: <a href="{{ .RootURL.Post $seriesNextPrev.Next.ID }}">{{ $seriesNextPrev.Next.Title }}</a> {{ end }} {{ if and $seriesNextPrev.Next $seriesNextPrev.Previous }} @@ -35,7 +35,7 @@ {{ end }} {{ if $seriesNextPrev.Previous }} - Previously: <a href="{{ PostURL $seriesNextPrev.Previous.ID }}">{{ $seriesNextPrev.Previous.Title }}</a> + Previously: <a href="{{ .RootURL.Post $seriesNextPrev.Previous.ID }}">{{ $seriesNextPrev.Previous.Title }}</a> <br/> {{ end }} diff --git a/src/http/tpl/posts-manage.html b/src/http/tpl/posts-manage.html index f9adbc1..ad9c9d7 100644 --- a/src/http/tpl/posts-manage.html +++ b/src/http/tpl/posts-manage.html @@ -1,6 +1,6 @@ {{ define "body" }} - {{ $page := .GetQueryIntValue "p" 0 -}} + {{ $page := .GetQueryIntValue "page" 0 -}} {{ $getPostsRes := .GetPosts $page 20 -}} <script> @@ -11,14 +11,14 @@ </script> <p> - <a href="{{ BlogURL "admin" }}">Back to Admin</a> + <a href="{{ .RootURL.Path "admin" }}">Back to Admin</a> </p> <h1>Posts</h1> {{ if gt $page 0 }} <p> - <a href="?method=manage&p={{ .Add $page -1 }}">< < Previous Page</a> + <a href="{{ .RootURL.Posts.MethodManage.Page (.Add $page -1) }}">< < Previous Page</a> </p> {{ end }} @@ -33,15 +33,15 @@ {{ range $getPostsRes.Posts }} <tr> <td>{{ .PublishedAt.Local.Format "2006-01-02 15:04:05 MST" }}</td> - <td><a href="{{ PostURL .ID }}">{{ .Title }}</a></td> + <td><a href="{{ $.RootURL.Post .ID }}">{{ .Title }}</a></td> <td> - <a href="{{ PostURL .ID }}?method=edit"> + <a href="{{ ($.RootURL.Post .ID).MethodEdit }}"> Edit </a> </td> <td> <form - action="{{ PostURL .ID }}?method=delete" + action="{{ ($.RootURL.Post .ID).MethodDelete }}" method="POST" > <input @@ -58,7 +58,7 @@ {{ if $getPostsRes.HasMore }} <p> - <a href="?method=manage&p={{ .Add $page 1 }}">Next Page > ></a> + <a href="{{ .RootURL.Posts.MethodManage.Page (.Add $page 1) }}">Next Page > ></a> </p> {{ end }} diff --git a/src/http/tpl/posts.html b/src/http/tpl/posts.html index 2fa336d..0df166a 100644 --- a/src/http/tpl/posts.html +++ b/src/http/tpl/posts.html @@ -1,11 +1,11 @@ {{ define "body" }} - {{ $page := .GetQueryIntValue "p" 0 -}} + {{ $page := .GetQueryIntValue "page" 0 -}} {{ $getPostsRes := .GetPosts $page 20 -}} {{ if gt $page 0 }} <p> - <a href="?p={{ .Add $page -1 }}">< < Previous Page</a> + <a href="{{ .RootURL.Posts.Page (.Add $page -1) }}">< < Previous Page</a> </p> {{ else }} <p> @@ -17,7 +17,7 @@ <ul> {{ range $getPostsRes.Posts }} <li> - <strong><a href="{{ PostURL .ID }}"> + <strong><a href="{{ $.RootURL.Post .ID }}"> {{ .PublishedAt.Format "2006-01-02" }} - {{ .Title }} </a></strong> {{ if .Description }} @@ -29,7 +29,7 @@ {{ if $getPostsRes.HasMore }} <p> - <a href="?p={{ .Add $page 1 }}">Next Page > ></a> + <a href="{{ .RootURL.Posts.Page (.Add $page 1) }}">Next Page > ></a> </p> {{ end }} 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 +} |