1diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
2index cb202a2e0a5a5409454f72d82c7da4f28449c243..ffa5dfd6230013ce209b1c3f51c866254e734e2e 100644
3--- a/pkg/handler/git/handler.go
4+++ b/pkg/handler/git/handler.go
5@@ -38,6 +38,7 @@ configurationRepository interface {
6 GetRootReadme() string
7 GetSyntaxHighlight() string
8 GetOrderBy() config.OrderBy
9+ GetHostname() string
10 }
11 )
12
13@@ -194,6 +195,7 @@ GitItemBase: &templates.GitItemSummaryPage{
14 Tags: tags,
15 Branches: branches,
16 Commits: commits,
17+ Hostname: g.config.GetHostname(),
18 },
19 }
20 templates.WritePageTemplate(w, gitList, r.Context())
21diff --git a/templates/gititemblob.qtpl b/templates/gititemblob.qtpl
22index ca3a1faaf12d3dc0cf337b42cecfa209ba6a1938..c5f412b0364d2dc468deff0cd16a50c1990bd7b5 100644
23--- a/templates/gititemblob.qtpl
24+++ b/templates/gititemblob.qtpl
25@@ -13,9 +13,9 @@ {% func (g *GitItemBlobPage) GitContent(name, ref string) %}
26 <div class="pathing">
27 {% stripspace %}
28 {% if len(g.Path) != 0 %}
29- <a href="{%s url(name, Folder, ref, Root, []string{}) %}">root/</a>
30+ <a href="{%s generateURL(name, Folder, ref, Root, []string{}) %}">root/</a>
31 {% for i, e := range g.Path[:len(g.Path)-1] %}
32- <a href="{%s url(name, Folder, ref, Root, g.Path[:1+i]) %}">{%s e %}/</a>
33+ <a href="{%s generateURL(name, Folder, ref, Root, g.Path[:1+i]) %}">{%s e %}/</a>
34 {% endfor %}
35 <a>{%s u.LastOrZero(g.Path) %}</a>
36 {% else %}
37diff --git a/templates/gititemblob.qtpl.go b/templates/gititemblob.qtpl.go
38index 73742f6b614d8b0da61e9c1c366348e70d55e8e7..484388209c6360c7dbe8999d7f05c42ab8f503ac 100644
39--- a/templates/gititemblob.qtpl.go
40+++ b/templates/gititemblob.qtpl.go
41@@ -70,7 +70,7 @@ if len(g.Path) != 0 {
42 //line templates/gititemblob.qtpl:15
43 qw422016.N().S(`<a href="`)
44 //line templates/gititemblob.qtpl:16
45- qw422016.E().S(url(name, Folder, ref, Root, []string{}))
46+ qw422016.E().S(generateURL(name, Folder, ref, Root, []string{}))
47 //line templates/gititemblob.qtpl:16
48 qw422016.N().S(`">root/</a>`)
49 //line templates/gititemblob.qtpl:17
50@@ -78,7 +78,7 @@ for i, e := range g.Path[:len(g.Path)-1] {
51 //line templates/gititemblob.qtpl:17
52 qw422016.N().S(`<a href="`)
53 //line templates/gititemblob.qtpl:18
54- qw422016.E().S(url(name, Folder, ref, Root, g.Path[:1+i]))
55+ qw422016.E().S(generateURL(name, Folder, ref, Root, g.Path[:1+i]))
56 //line templates/gititemblob.qtpl:18
57 qw422016.N().S(`">`)
58 //line templates/gititemblob.qtpl:18
59diff --git a/templates/gititemsummary.qtpl b/templates/gititemsummary.qtpl
60index f39a6131b5e71a509165e3938c1990be3a1c3ea9..7f56837e8a8cc5f4a02bd3a862feba7ac85759d2 100644
61--- a/templates/gititemsummary.qtpl
62+++ b/templates/gititemsummary.qtpl
63@@ -1,3 +1,4 @@
64+{% import "net/url" %}
65 {% import "github.com/go-git/go-git/v5/plumbing" %}
66 {% import "git.gabrielgio.me/cerrado/pkg/git" %}
67
68@@ -6,12 +7,26 @@ type GitItemSummaryPage struct {
69 Tags []*git.TagReference
70 Branches []*plumbing.Reference
71 Commits []*git.CommitReference
72+ Hostname string
73 }
74 %}
75
76+{% code
77+
78+func mergeURL(hostname, name string) string {
79+ s, _ := url.JoinPath(hostname, name)
80+ return s
81+}
82+
83+%}
84+
85 {% func (g *GitItemSummaryPage) Nav(name, ref string) %}{%= GitItemNav(name, ref, Summary) %}{% endfunc %}
86
87 {% func (g *GitItemSummaryPage) GitContent(name, ref string) %}
88+<div class="row event">
89+ <div class="col-auto">clone: </div>
90+ <div class="col-md">{%s mergeURL(g.Hostname, name) %}</div>
91+</div>
92 <div class="row">
93 <div class="col-md-8">
94 {%= ListTags(name, g.Tags) %}
95diff --git a/templates/gititemsummary.qtpl.go b/templates/gititemsummary.qtpl.go
96index d6d20cb4ea2566dc6a136444ff934e14dc20f85d..d132cbac3053ab7ec078e15854f250e394a2219f 100644
97--- a/templates/gititemsummary.qtpl.go
98+++ b/templates/gititemsummary.qtpl.go
99@@ -5,190 +5,208 @@ //line templates/gititemsummary.qtpl:1
100 package templates
101
102 //line templates/gititemsummary.qtpl:1
103+import "net/url"
104+
105+//line templates/gititemsummary.qtpl:2
106 import "github.com/go-git/go-git/v5/plumbing"
107
108-//line templates/gititemsummary.qtpl:2
109+//line templates/gititemsummary.qtpl:3
110 import "git.gabrielgio.me/cerrado/pkg/git"
111
112-//line templates/gititemsummary.qtpl:4
113+//line templates/gititemsummary.qtpl:5
114 import (
115 qtio422016 "io"
116
117 qt422016 "github.com/valyala/quicktemplate"
118 )
119
120-//line templates/gititemsummary.qtpl:4
121+//line templates/gititemsummary.qtpl:5
122 var (
123 _ = qtio422016.Copy
124 _ = qt422016.AcquireByteBuffer
125 )
126
127-//line templates/gititemsummary.qtpl:5
128+//line templates/gititemsummary.qtpl:6
129 type GitItemSummaryPage struct {
130 Tags []*git.TagReference
131 Branches []*plumbing.Reference
132 Commits []*git.CommitReference
133+ Hostname string
134 }
135
136-//line templates/gititemsummary.qtpl:12
137+//line templates/gititemsummary.qtpl:16
138+func mergeURL(hostname, name string) string {
139+ s, _ := url.JoinPath(hostname, name)
140+ return s
141+}
142+
143+//line templates/gititemsummary.qtpl:23
144 func (g *GitItemSummaryPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) {
145-//line templates/gititemsummary.qtpl:12
146+//line templates/gititemsummary.qtpl:23
147 StreamGitItemNav(qw422016, name, ref, Summary)
148-//line templates/gititemsummary.qtpl:12
149+//line templates/gititemsummary.qtpl:23
150 }
151
152-//line templates/gititemsummary.qtpl:12
153+//line templates/gititemsummary.qtpl:23
154 func (g *GitItemSummaryPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) {
155-//line templates/gititemsummary.qtpl:12
156+//line templates/gititemsummary.qtpl:23
157 qw422016 := qt422016.AcquireWriter(qq422016)
158-//line templates/gititemsummary.qtpl:12
159+//line templates/gititemsummary.qtpl:23
160 g.StreamNav(qw422016, name, ref)
161-//line templates/gititemsummary.qtpl:12
162+//line templates/gititemsummary.qtpl:23
163 qt422016.ReleaseWriter(qw422016)
164-//line templates/gititemsummary.qtpl:12
165+//line templates/gititemsummary.qtpl:23
166 }
167
168-//line templates/gititemsummary.qtpl:12
169+//line templates/gititemsummary.qtpl:23
170 func (g *GitItemSummaryPage) Nav(name, ref string) string {
171-//line templates/gititemsummary.qtpl:12
172+//line templates/gititemsummary.qtpl:23
173 qb422016 := qt422016.AcquireByteBuffer()
174-//line templates/gititemsummary.qtpl:12
175+//line templates/gititemsummary.qtpl:23
176 g.WriteNav(qb422016, name, ref)
177-//line templates/gititemsummary.qtpl:12
178+//line templates/gititemsummary.qtpl:23
179 qs422016 := string(qb422016.B)
180-//line templates/gititemsummary.qtpl:12
181+//line templates/gititemsummary.qtpl:23
182 qt422016.ReleaseByteBuffer(qb422016)
183-//line templates/gititemsummary.qtpl:12
184+//line templates/gititemsummary.qtpl:23
185 return qs422016
186-//line templates/gititemsummary.qtpl:12
187+//line templates/gititemsummary.qtpl:23
188 }
189
190-//line templates/gititemsummary.qtpl:14
191+//line templates/gititemsummary.qtpl:25
192 func (g *GitItemSummaryPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
193-//line templates/gititemsummary.qtpl:14
194+//line templates/gititemsummary.qtpl:25
195 qw422016.N().S(`
196+<div class="row event">
197+ <div class="col-auto">clone: </div>
198+ <div class="col-md">`)
199+//line templates/gititemsummary.qtpl:28
200+ qw422016.E().S(mergeURL(g.Hostname, name))
201+//line templates/gititemsummary.qtpl:28
202+ qw422016.N().S(`</div>
203+</div>
204 <div class="row">
205 <div class="col-md-8">
206 `)
207-//line templates/gititemsummary.qtpl:17
208+//line templates/gititemsummary.qtpl:32
209 StreamListTags(qw422016, name, g.Tags)
210-//line templates/gititemsummary.qtpl:17
211+//line templates/gititemsummary.qtpl:32
212 qw422016.N().S(`
213 </div>
214 <div class="col-md-4">
215 <div class="event-list">
216 `)
217-//line templates/gititemsummary.qtpl:21
218+//line templates/gititemsummary.qtpl:36
219 for _, b := range g.Branches {
220-//line templates/gititemsummary.qtpl:21
221+//line templates/gititemsummary.qtpl:36
222 qw422016.N().S(`
223 <div class="row event">
224 <div class="col-4">
225 `)
226-//line templates/gititemsummary.qtpl:24
227+//line templates/gititemsummary.qtpl:39
228 qw422016.E().S(b.Name().Short())
229-//line templates/gititemsummary.qtpl:24
230+//line templates/gititemsummary.qtpl:39
231 qw422016.N().S(`
232 </div>
233 <div class="col-8">
234 <div class="float-end">
235 <a href="/`)
236-//line templates/gititemsummary.qtpl:28
237+//line templates/gititemsummary.qtpl:43
238 qw422016.E().S(name)
239-//line templates/gititemsummary.qtpl:28
240+//line templates/gititemsummary.qtpl:43
241 qw422016.N().S(`/archive/`)
242-//line templates/gititemsummary.qtpl:28
243+//line templates/gititemsummary.qtpl:43
244 qw422016.E().S(b.Name().Short())
245-//line templates/gititemsummary.qtpl:28
246+//line templates/gititemsummary.qtpl:43
247 qw422016.N().S(`.tar.gz">tar.gz</a>
248 <a href="/`)
249-//line templates/gititemsummary.qtpl:29
250+//line templates/gititemsummary.qtpl:44
251 qw422016.E().S(name)
252-//line templates/gititemsummary.qtpl:29
253+//line templates/gititemsummary.qtpl:44
254 qw422016.N().S(`/tree/`)
255-//line templates/gititemsummary.qtpl:29
256+//line templates/gititemsummary.qtpl:44
257 qw422016.E().S(b.Name().Short())
258-//line templates/gititemsummary.qtpl:29
259+//line templates/gititemsummary.qtpl:44
260 qw422016.N().S(`/">tree</a>
261 <a href="/`)
262-//line templates/gititemsummary.qtpl:30
263+//line templates/gititemsummary.qtpl:45
264 qw422016.E().S(name)
265-//line templates/gititemsummary.qtpl:30
266+//line templates/gititemsummary.qtpl:45
267 qw422016.N().S(`/log/`)
268-//line templates/gititemsummary.qtpl:30
269+//line templates/gititemsummary.qtpl:45
270 qw422016.E().S(b.Name().Short())
271-//line templates/gititemsummary.qtpl:30
272+//line templates/gititemsummary.qtpl:45
273 qw422016.N().S(`/">log</a>
274 </div>
275 </div>
276 </div>
277 `)
278-//line templates/gititemsummary.qtpl:34
279+//line templates/gititemsummary.qtpl:49
280 }
281-//line templates/gititemsummary.qtpl:34
282+//line templates/gititemsummary.qtpl:49
283 qw422016.N().S(`
284 </div>
285 </div>
286 <a class="more" href="/`)
287-//line templates/gititemsummary.qtpl:37
288+//line templates/gititemsummary.qtpl:52
289 qw422016.E().S(name)
290-//line templates/gititemsummary.qtpl:37
291+//line templates/gititemsummary.qtpl:52
292 qw422016.N().S(`/refs/">[ see refs... ]</a>
293 </div>
294 <div class="row">
295 <div class="event-list">
296 `)
297-//line templates/gititemsummary.qtpl:41
298+//line templates/gititemsummary.qtpl:56
299 for _, c := range g.Commits {
300-//line templates/gititemsummary.qtpl:41
301+//line templates/gititemsummary.qtpl:56
302 qw422016.N().S(`
303 `)
304-//line templates/gititemsummary.qtpl:42
305+//line templates/gititemsummary.qtpl:57
306 StreamCommit(qw422016, name, c, false)
307-//line templates/gititemsummary.qtpl:42
308+//line templates/gititemsummary.qtpl:57
309 qw422016.N().S(`
310 `)
311-//line templates/gititemsummary.qtpl:43
312+//line templates/gititemsummary.qtpl:58
313 }
314-//line templates/gititemsummary.qtpl:43
315+//line templates/gititemsummary.qtpl:58
316 qw422016.N().S(`
317 </div>
318 <a class="more" href="/`)
319-//line templates/gititemsummary.qtpl:45
320+//line templates/gititemsummary.qtpl:60
321 qw422016.E().S(name)
322-//line templates/gititemsummary.qtpl:45
323+//line templates/gititemsummary.qtpl:60
324 qw422016.N().S(`/log/`)
325-//line templates/gititemsummary.qtpl:45
326+//line templates/gititemsummary.qtpl:60
327 qw422016.E().S(ref)
328-//line templates/gititemsummary.qtpl:45
329+//line templates/gititemsummary.qtpl:60
330 qw422016.N().S(`/">[ see log... ]</a>
331 </div>
332 `)
333-//line templates/gititemsummary.qtpl:47
334+//line templates/gititemsummary.qtpl:62
335 }
336
337-//line templates/gititemsummary.qtpl:47
338+//line templates/gititemsummary.qtpl:62
339 func (g *GitItemSummaryPage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) {
340-//line templates/gititemsummary.qtpl:47
341+//line templates/gititemsummary.qtpl:62
342 qw422016 := qt422016.AcquireWriter(qq422016)
343-//line templates/gititemsummary.qtpl:47
344+//line templates/gititemsummary.qtpl:62
345 g.StreamGitContent(qw422016, name, ref)
346-//line templates/gititemsummary.qtpl:47
347+//line templates/gititemsummary.qtpl:62
348 qt422016.ReleaseWriter(qw422016)
349-//line templates/gititemsummary.qtpl:47
350+//line templates/gititemsummary.qtpl:62
351 }
352
353-//line templates/gititemsummary.qtpl:47
354+//line templates/gititemsummary.qtpl:62
355 func (g *GitItemSummaryPage) GitContent(name, ref string) string {
356-//line templates/gititemsummary.qtpl:47
357+//line templates/gititemsummary.qtpl:62
358 qb422016 := qt422016.AcquireByteBuffer()
359-//line templates/gititemsummary.qtpl:47
360+//line templates/gititemsummary.qtpl:62
361 g.WriteGitContent(qb422016, name, ref)
362-//line templates/gititemsummary.qtpl:47
363+//line templates/gititemsummary.qtpl:62
364 qs422016 := string(qb422016.B)
365-//line templates/gititemsummary.qtpl:47
366+//line templates/gititemsummary.qtpl:62
367 qt422016.ReleaseByteBuffer(qb422016)
368-//line templates/gititemsummary.qtpl:47
369+//line templates/gititemsummary.qtpl:62
370 return qs422016
371-//line templates/gititemsummary.qtpl:47
372+//line templates/gititemsummary.qtpl:62
373 }
374diff --git a/templates/gititemtree.qtpl b/templates/gititemtree.qtpl
375index 2753e24fd356cfec2fd3a412d5d8669266d5da0a..677d8ec9947938e59ef7bc8355396bc1f2a11666 100644
376--- a/templates/gititemtree.qtpl
377+++ b/templates/gititemtree.qtpl
378@@ -15,7 +15,7 @@ Root = ""
379 )
380 %}
381
382-{% code func url(name, mode, ref, filename string, path []string) string {
383+{% code func generateURL(name, mode, ref, filename string, path []string) string {
384 return u.NewPathing().
385 AddPath(name).
386 AddPath(mode).
387@@ -32,9 +32,9 @@ {% func (g *GitItemTreePage) GitContent(name, ref string) %}
388 <div class="pathing">
389 {% stripspace %}
390 {% if len(g.Path) != 0 %}
391- <a href="{%s url(name, Folder, ref, Root, []string{}) %}">root/</a>
392+ <a href="{%s generateURL(name, Folder, ref, Root, []string{}) %}">root/</a>
393 {% for i, e := range g.Path[:len(g.Path)-1] %}
394- <a href="{%s url(name, Folder, ref, Root, g.Path[:1+i]) %}">{%s e %}/</a>
395+ <a href="{%s generateURL(name, Folder, ref, Root, g.Path[:1+i]) %}">{%s e %}/</a>
396 {% endfor %}
397 <a>{%s u.LastOrZero(g.Path) %}</a>
398 {% else %}
399@@ -46,7 +46,7 @@ <div class="row">
400 <div class="col-md-12">
401 <div class="tree-list">
402 {% if len(g.Path) != 0 %}
403- <div class="mode"><a href="{%s url(name, Folder, ref, g.Path[len(g.Path)-1], g.Path[:len(g.Path)-1]) %}">..</a></div>
404+ <div class="mode"><a href="{%s generateURL(name, Folder, ref, g.Path[len(g.Path)-1], g.Path[:len(g.Path)-1]) %}">..</a></div>
405 <div class="name tree"></div>
406 <div class="commit"></div>
407 <div class="date"></div>
408@@ -55,13 +55,13 @@ {% endif %}
409 {% for _, e := range g.Tree.Entries %}
410 {% if e.Mode.IsFile() %}
411 <div class="mode">{%s Ignore(e.Mode.ToOSFileMode()).String() %}</div>
412- <div class="name blob"><a href="{%s url(name, Blob, ref, e.Name, g.Path) %}">{%s e.Name %}</a></div>
413+ <div class="name blob"><a href="{%s generateURL(name, Blob, ref, e.Name, g.Path) %}">{%s e.Name %}</a></div>
414 {% elseif e.Mode == filemode.Submodule %}
415 <div class="mode">m---------</div>
416 <div class="name tree">{%s e.Name %} (submodule)</div>
417 {% else %}
418 <div class="mode">d---------</div>
419- <div class="name tree"><a href="{%s url(name, Folder, ref, e.Name, g.Path) %}">{%s e.Name %}</a></div>
420+ <div class="name tree"><a href="{%s generateURL(name, Folder, ref, e.Name, g.Path) %}">{%s e.Name %}</a></div>
421 {% endif %}
422 <div class="commit"></div>
423 <div class="date"></div>
424diff --git a/templates/gititemtree.qtpl.go b/templates/gititemtree.qtpl.go
425index 9116cd7ad048807f0680548d264b163eed71f1b5..7a378ccff016e0a97d91c042033ed1852de7dff2 100644
426--- a/templates/gititemtree.qtpl.go
427+++ b/templates/gititemtree.qtpl.go
428@@ -40,7 +40,7 @@ Root = ""
429 )
430
431 //line templates/gititemtree.qtpl:18
432-func url(name, mode, ref, filename string, path []string) string {
433+func generateURL(name, mode, ref, filename string, path []string) string {
434 return u.NewPathing().
435 AddPath(name).
436 AddPath(mode).
437@@ -94,7 +94,7 @@ if len(g.Path) != 0 {
438 //line templates/gititemtree.qtpl:34
439 qw422016.N().S(`<a href="`)
440 //line templates/gititemtree.qtpl:35
441- qw422016.E().S(url(name, Folder, ref, Root, []string{}))
442+ qw422016.E().S(generateURL(name, Folder, ref, Root, []string{}))
443 //line templates/gititemtree.qtpl:35
444 qw422016.N().S(`">root/</a>`)
445 //line templates/gititemtree.qtpl:36
446@@ -102,7 +102,7 @@ for i, e := range g.Path[:len(g.Path)-1] {
447 //line templates/gititemtree.qtpl:36
448 qw422016.N().S(`<a href="`)
449 //line templates/gititemtree.qtpl:37
450- qw422016.E().S(url(name, Folder, ref, Root, g.Path[:1+i]))
451+ qw422016.E().S(generateURL(name, Folder, ref, Root, g.Path[:1+i]))
452 //line templates/gititemtree.qtpl:37
453 qw422016.N().S(`">`)
454 //line templates/gititemtree.qtpl:37
455@@ -136,7 +136,7 @@ //line templates/gititemtree.qtpl:48
456 qw422016.N().S(`
457 <div class="mode"><a href="`)
458 //line templates/gititemtree.qtpl:49
459- qw422016.E().S(url(name, Folder, ref, g.Path[len(g.Path)-1], g.Path[:len(g.Path)-1]))
460+ qw422016.E().S(generateURL(name, Folder, ref, g.Path[len(g.Path)-1], g.Path[:len(g.Path)-1]))
461 //line templates/gititemtree.qtpl:49
462 qw422016.N().S(`">..</a></div>
463 <div class="name tree"></div>
464@@ -165,7 +165,7 @@ //line templates/gititemtree.qtpl:57
465 qw422016.N().S(`</div>
466 <div class="name blob"><a href="`)
467 //line templates/gititemtree.qtpl:58
468- qw422016.E().S(url(name, Blob, ref, e.Name, g.Path))
469+ qw422016.E().S(generateURL(name, Blob, ref, e.Name, g.Path))
470 //line templates/gititemtree.qtpl:58
471 qw422016.N().S(`">`)
472 //line templates/gititemtree.qtpl:58
473@@ -191,7 +191,7 @@ qw422016.N().S(`
474 <div class="mode">d---------</div>
475 <div class="name tree"><a href="`)
476 //line templates/gititemtree.qtpl:64
477- qw422016.E().S(url(name, Folder, ref, e.Name, g.Path))
478+ qw422016.E().S(generateURL(name, Folder, ref, e.Name, g.Path))
479 //line templates/gititemtree.qtpl:64
480 qw422016.N().S(`">`)
481 //line templates/gititemtree.qtpl:64