this repo has no description

legit/templates: move templates to subdirectories

+122
legit/routes/file.go
··· 1 + package routes 2 + 3 + import ( 4 + "bytes" 5 + "html/template" 6 + "io" 7 + "log" 8 + "net/http" 9 + "strings" 10 + 11 + "github.com/alecthomas/chroma/v2/formatters/html" 12 + "github.com/alecthomas/chroma/v2/lexers" 13 + "github.com/alecthomas/chroma/v2/styles" 14 + "github.com/icyphox/bild/legit/git" 15 + ) 16 + 17 + func (h *Handle) listFiles(files []git.NiceTree, data map[string]any, w http.ResponseWriter) { 18 + data["files"] = files 19 + data["meta"] = h.c.Meta 20 + 21 + if err := h.t.ExecuteTemplate(w, "repo/tree", data); err != nil { 22 + log.Println(err) 23 + return 24 + } 25 + } 26 + 27 + func countLines(r io.Reader) (int, error) { 28 + buf := make([]byte, 32*1024) 29 + bufLen := 0 30 + count := 0 31 + nl := []byte{'\n'} 32 + 33 + for { 34 + c, err := r.Read(buf) 35 + if c > 0 { 36 + bufLen += c 37 + } 38 + count += bytes.Count(buf[:c], nl) 39 + 40 + switch { 41 + case err == io.EOF: 42 + /* handle last line not having a newline at the end */ 43 + if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' { 44 + count++ 45 + } 46 + return count, nil 47 + case err != nil: 48 + return 0, err 49 + } 50 + } 51 + } 52 + 53 + func (h *Handle) showFileWithHighlight(name, content string, data map[string]any, w http.ResponseWriter) { 54 + lexer := lexers.Get(name) 55 + if lexer == nil { 56 + lexer = lexers.Get(".txt") 57 + } 58 + 59 + style := styles.Get(h.c.Meta.SyntaxHighlight) 60 + if style == nil { 61 + style = styles.Get("monokailight") 62 + } 63 + 64 + formatter := html.New( 65 + html.WithLineNumbers(true), 66 + html.WithLinkableLineNumbers(true, "L"), 67 + ) 68 + 69 + iterator, err := lexer.Tokenise(nil, content) 70 + if err != nil { 71 + h.Write500(w) 72 + return 73 + } 74 + 75 + var code bytes.Buffer 76 + err = formatter.Format(&code, style, iterator) 77 + if err != nil { 78 + h.Write500(w) 79 + return 80 + } 81 + 82 + data["content"] = template.HTML(code.String()) 83 + data["meta"] = h.c.Meta 84 + data["chroma"] = true 85 + 86 + if err := h.t.ExecuteTemplate(w, "repo/file", data); err != nil { 87 + log.Println(err) 88 + return 89 + } 90 + } 91 + 92 + func (h *Handle) showFile(content string, data map[string]any, w http.ResponseWriter) { 93 + lc, err := countLines(strings.NewReader(content)) 94 + if err != nil { 95 + // Non-fatal, we'll just skip showing line numbers in the template. 96 + log.Printf("counting lines: %s", err) 97 + } 98 + 99 + lines := make([]int, lc) 100 + if lc > 0 { 101 + for i := range lines { 102 + lines[i] = i + 1 103 + } 104 + } 105 + 106 + data["linecount"] = lines 107 + data["content"] = content 108 + data["meta"] = h.c.Meta 109 + data["chroma"] = false 110 + 111 + if err := h.t.ExecuteTemplate(w, "repo/file", data); err != nil { 112 + log.Println(err) 113 + return 114 + } 115 + } 116 + 117 + func (h *Handle) showRaw(content string, w http.ResponseWriter) { 118 + w.WriteHeader(http.StatusOK) 119 + w.Header().Set("Content-Type", "text/plain") 120 + w.Write([]byte(content)) 121 + return 122 + }
+6 -4
legit/routes/handler.go
··· 2 2 3 3 import ( 4 4 "fmt" 5 - "html/template" 6 5 "net/http" 7 - "path/filepath" 8 6 9 7 _ "github.com/bluesky-social/indigo/atproto/identity" 10 8 _ "github.com/bluesky-social/indigo/atproto/syntax" ··· 13 11 "github.com/gorilla/sessions" 14 12 "github.com/icyphox/bild/legit/config" 15 13 "github.com/icyphox/bild/legit/db" 14 + "github.com/icyphox/bild/legit/routes/tmpl" 16 15 ) 17 16 18 17 // Checks for gitprotocol-http(5) specific smells; if found, passes ··· 39 38 40 39 func Setup(c *config.Config) (http.Handler, error) { 41 40 r := chi.NewRouter() 42 - t := template.Must(template.ParseGlob(filepath.Join(c.Dirs.Templates, "*"))) 43 41 s := sessions.NewCookieStore([]byte("TODO_CHANGE_ME")) 42 + t, err := tmpl.Load(c.Dirs.Templates) 43 + if err != nil { 44 + return nil, fmt.Errorf("failed to load templates: %w", err) 45 + } 46 + 44 47 db, err := db.Setup(c.Server.DBPath) 45 - 46 48 if err != nil { 47 49 return nil, fmt.Errorf("failed to setup db: %w", err) 48 50 }
+29
legit/routes/html_util.go
··· 1 + package routes 2 + 3 + import ( 4 + "fmt" 5 + "log" 6 + "net/http" 7 + ) 8 + 9 + func (h *Handle) Write404(w http.ResponseWriter) { 10 + w.WriteHeader(404) 11 + if err := h.t.ExecuteTemplate(w, "errors/404", nil); err != nil { 12 + log.Printf("404 template: %s", err) 13 + } 14 + } 15 + 16 + func (h *Handle) Write500(w http.ResponseWriter) { 17 + w.WriteHeader(500) 18 + if err := h.t.ExecuteTemplate(w, "errors/500", nil); err != nil { 19 + log.Printf("500 template: %s", err) 20 + } 21 + } 22 + 23 + func (h *Handle) WriteOOBNotice(w http.ResponseWriter, id, msg string) { 24 + html := fmt.Sprintf(`<span id="%s" hx-swap-oob="innerHTML">%s</span>`, id, msg) 25 + 26 + w.Header().Set("Content-Type", "text/html") 27 + w.WriteHeader(http.StatusOK) 28 + w.Write([]byte(html)) 29 + }
+7 -9
legit/routes/routes.go
··· 106 106 name = filepath.Clean(name) 107 107 path := filepath.Join(h.c.Repo.ScanPath, name) 108 108 109 - fmt.Println(path) 110 109 gr, err := git.Open(path, "") 111 110 if err != nil { 112 111 if errors.Is(err, plumbing.ErrReferenceNotFound) { 113 - h.t.ExecuteTemplate(w, "empty", nil) 112 + h.t.ExecuteTemplate(w, "repo/empty", nil) 114 113 return 115 114 } else { 116 115 h.Write404(w) ··· 173 172 data["meta"] = h.c.Meta 174 173 data["gomod"] = isGoModule(gr) 175 174 176 - if err := h.t.ExecuteTemplate(w, "repo", data); err != nil { 175 + if err := h.t.ExecuteTemplate(w, "repo/repo", data); err != nil { 177 176 log.Println(err) 178 177 return 179 178 } ··· 192 191 193 192 name = filepath.Clean(name) 194 193 path := filepath.Join(h.c.Repo.ScanPath, name) 195 - fmt.Println(path) 196 194 gr, err := git.Open(path, ref) 197 195 if err != nil { 198 196 h.Write404(w) ··· 348 346 data["desc"] = getDescription(path) 349 347 data["log"] = true 350 348 351 - if err := h.t.ExecuteTemplate(w, "log", data); err != nil { 349 + if err := h.t.ExecuteTemplate(w, "repo/log", data); err != nil { 352 350 log.Println(err) 353 351 return 354 352 } ··· 387 385 data["ref"] = ref 388 386 data["desc"] = getDescription(path) 389 387 390 - if err := h.t.ExecuteTemplate(w, "commit", data); err != nil { 388 + if err := h.t.ExecuteTemplate(w, "repo/commit", data); err != nil { 391 389 log.Println(err) 392 390 return 393 391 } ··· 429 427 data["tags"] = tags 430 428 data["desc"] = getDescription(path) 431 429 432 - if err := h.t.ExecuteTemplate(w, "refs", data); err != nil { 430 + if err := h.t.ExecuteTemplate(w, "repo/refs", data); err != nil { 433 431 log.Println(err) 434 432 return 435 433 } ··· 509 507 510 508 data := make(map[string]interface{}) 511 509 data["keys"] = keys 512 - if err := h.t.ExecuteTemplate(w, "keys", data); err != nil { 510 + if err := h.t.ExecuteTemplate(w, "settings/keys", data); err != nil { 513 511 log.Println(err) 514 512 return 515 513 } ··· 541 539 542 540 switch r.Method { 543 541 case http.MethodGet: 544 - if err := h.t.ExecuteTemplate(w, "new", nil); err != nil { 542 + if err := h.t.ExecuteTemplate(w, "repo/new", nil); err != nil { 545 543 log.Println(err) 546 544 return 547 545 }
-155
legit/routes/template.go
··· 1 - package routes 2 - 3 - import ( 4 - "bytes" 5 - "fmt" 6 - "html/template" 7 - "io" 8 - "log" 9 - "net/http" 10 - "path/filepath" 11 - "strings" 12 - 13 - "github.com/alecthomas/chroma/v2/formatters/html" 14 - "github.com/alecthomas/chroma/v2/lexers" 15 - "github.com/alecthomas/chroma/v2/styles" 16 - "github.com/icyphox/bild/legit/git" 17 - ) 18 - 19 - func (h *Handle) Write404(w http.ResponseWriter) { 20 - w.WriteHeader(404) 21 - if err := h.t.ExecuteTemplate(w, "404", nil); err != nil { 22 - log.Printf("404 template: %s", err) 23 - } 24 - } 25 - 26 - func (h *Handle) Write500(w http.ResponseWriter) { 27 - w.WriteHeader(500) 28 - if err := h.t.ExecuteTemplate(w, "500", nil); err != nil { 29 - log.Printf("500 template: %s", err) 30 - } 31 - } 32 - 33 - func (h *Handle) WriteOOBNotice(w http.ResponseWriter, id, msg string) { 34 - html := fmt.Sprintf(`<span id="%s" hx-swap-oob="innerHTML">%s</span>`, id, msg) 35 - 36 - w.Header().Set("Content-Type", "text/html") 37 - w.WriteHeader(http.StatusOK) 38 - w.Write([]byte(html)) 39 - } 40 - 41 - func (h *Handle) listFiles(files []git.NiceTree, data map[string]any, w http.ResponseWriter) { 42 - tpath := filepath.Join(h.c.Dirs.Templates, "*") 43 - t := template.Must(template.ParseGlob(tpath)) 44 - 45 - data["files"] = files 46 - data["meta"] = h.c.Meta 47 - 48 - if err := t.ExecuteTemplate(w, "tree", data); err != nil { 49 - log.Println(err) 50 - return 51 - } 52 - } 53 - 54 - func countLines(r io.Reader) (int, error) { 55 - buf := make([]byte, 32*1024) 56 - bufLen := 0 57 - count := 0 58 - nl := []byte{'\n'} 59 - 60 - for { 61 - c, err := r.Read(buf) 62 - if c > 0 { 63 - bufLen += c 64 - } 65 - count += bytes.Count(buf[:c], nl) 66 - 67 - switch { 68 - case err == io.EOF: 69 - /* handle last line not having a newline at the end */ 70 - if bufLen >= 1 && buf[(bufLen-1)%(32*1024)] != '\n' { 71 - count++ 72 - } 73 - return count, nil 74 - case err != nil: 75 - return 0, err 76 - } 77 - } 78 - } 79 - 80 - func (d *Handle) showFileWithHighlight(name, content string, data map[string]any, w http.ResponseWriter) { 81 - tpath := filepath.Join(d.c.Dirs.Templates, "*") 82 - t := template.Must(template.ParseGlob(tpath)) 83 - 84 - lexer := lexers.Get(name) 85 - if lexer == nil { 86 - lexer = lexers.Get(".txt") 87 - } 88 - 89 - style := styles.Get(d.c.Meta.SyntaxHighlight) 90 - if style == nil { 91 - style = styles.Get("monokailight") 92 - } 93 - 94 - formatter := html.New( 95 - html.WithLineNumbers(true), 96 - html.WithLinkableLineNumbers(true, "L"), 97 - ) 98 - 99 - iterator, err := lexer.Tokenise(nil, content) 100 - if err != nil { 101 - d.Write500(w) 102 - return 103 - } 104 - 105 - var code bytes.Buffer 106 - err = formatter.Format(&code, style, iterator) 107 - if err != nil { 108 - d.Write500(w) 109 - return 110 - } 111 - 112 - data["content"] = template.HTML(code.String()) 113 - data["meta"] = d.c.Meta 114 - data["chroma"] = true 115 - 116 - if err := t.ExecuteTemplate(w, "file", data); err != nil { 117 - log.Println(err) 118 - return 119 - } 120 - } 121 - 122 - func (d *Handle) showFile(content string, data map[string]any, w http.ResponseWriter) { 123 - tpath := filepath.Join(d.c.Dirs.Templates, "*") 124 - t := template.Must(template.ParseGlob(tpath)) 125 - 126 - lc, err := countLines(strings.NewReader(content)) 127 - if err != nil { 128 - // Non-fatal, we'll just skip showing line numbers in the template. 129 - log.Printf("counting lines: %s", err) 130 - } 131 - 132 - lines := make([]int, lc) 133 - if lc > 0 { 134 - for i := range lines { 135 - lines[i] = i + 1 136 - } 137 - } 138 - 139 - data["linecount"] = lines 140 - data["content"] = content 141 - data["meta"] = d.c.Meta 142 - data["chroma"] = false 143 - 144 - if err := t.ExecuteTemplate(w, "file", data); err != nil { 145 - log.Println(err) 146 - return 147 - } 148 - } 149 - 150 - func (d *Handle) showRaw(content string, w http.ResponseWriter) { 151 - w.WriteHeader(http.StatusOK) 152 - w.Header().Set("Content-Type", "text/plain") 153 - w.Write([]byte(content)) 154 - return 155 - }
+54
legit/routes/tmpl/tmpl.go
··· 1 + package tmpl 2 + 3 + import ( 4 + "html/template" 5 + "log" 6 + "os" 7 + "path/filepath" 8 + "strings" 9 + ) 10 + 11 + func Load(tpath string) (*template.Template, error) { 12 + tmpl := template.New("") 13 + loadedTemplates := make(map[string]bool) 14 + 15 + err := filepath.Walk(tpath, func(path string, info os.FileInfo, err error) error { 16 + if err != nil { 17 + return err 18 + } 19 + 20 + if !info.IsDir() && strings.HasSuffix(path, ".html") { 21 + content, err := os.ReadFile(path) 22 + if err != nil { 23 + return err 24 + } 25 + 26 + relPath, err := filepath.Rel(tpath, path) 27 + if err != nil { 28 + return err 29 + } 30 + 31 + name := strings.TrimSuffix(relPath, ".html") 32 + name = strings.ReplaceAll(name, string(filepath.Separator), "/") 33 + 34 + _, err = tmpl.New(name).Parse(string(content)) 35 + if err != nil { 36 + log.Printf("error parsing template %s: %v", name, err) 37 + return err 38 + } 39 + 40 + loadedTemplates[name] = true 41 + log.Printf("loaded template: %s", name) 42 + return err 43 + } 44 + return nil 45 + }) 46 + 47 + if err != nil { 48 + return nil, err 49 + } 50 + 51 + log.Printf("total templates loaded: %d", len(loadedTemplates)) 52 + return tmpl, nil 53 + 54 + }
-13
legit/templates/404.html
··· 1 - {{ define "404" }} 2 - <html> 3 - <title>404</title> 4 - {{ template "head" . }} 5 - <body> 6 - {{ template "nav" . }} 7 - <main> 8 - <h3>404 &mdash; nothing like that here.</h3> 9 - </main> 10 - </body> 11 - 12 - </html> 13 - {{ end }}
-13
legit/templates/500.html
··· 1 - {{ define "500" }} 2 - <html> 3 - <title>500</title> 4 - {{ template "head" . }} 5 - <body> 6 - {{ template "nav" . }} 7 - <main> 8 - <h3>500 &mdash; something broke!</h3> 9 - </main> 10 - </body> 11 - 12 - </html> 13 - {{ end }}
+5 -9
legit/templates/commit.html legit/templates/repo/commit.html
··· 1 - {{ define "commit" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 - {{ template "repoheader" . }} 4 + {{ template "layouts/repo-header" . }} 6 5 <body> 7 - {{ template "nav" . }} 6 + {{ template "layouts/nav" . }} 8 7 <main> 9 8 <section class="commit"> 10 - <pre> 11 - {{- .commit.Message -}} 12 - </pre> 9 + <pre>{{- .commit.Message -}}</pre> 13 10 <div class="commit-info"> 14 11 {{ .commit.Author.Name }} <a href="mailto:{{ .commit.Author.Email }}" class="commit-email">{{ .commit.Author.Email}}</a> 15 12 <div>{{ .commit.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div> ··· 100 97 </section> 101 98 </main> 102 99 </body> 103 - </html> 104 - {{ end }} 100 + </html>
+1 -3
legit/templates/empty.html legit/templates/repo/empty.html
··· 1 - {{ define "empty" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 4 <body> 6 5 <main> ··· 8 7 </main> 9 8 </body> 10 9 </html> 11 - {{ end }}
+10
legit/templates/errors/404.html
··· 1 + <html> 2 + <title>404</title> 3 + {{ template "layouts/head" . }} 4 + <body> 5 + {{ template "layouts/nav" . }} 6 + <main> 7 + <h3>404 &mdash; nothing like that here.</h3> 8 + </main> 9 + </body> 10 + </html>
+10
legit/templates/errors/500.html
··· 1 + <html> 2 + <title>500</title> 3 + {{ template "layouts/head" . }} 4 + <body> 5 + {{ template "layouts/nav" . }} 6 + <main> 7 + <h3>500 &mdash; something broke!</h3> 8 + </main> 9 + </body> 10 + </html>
+3 -5
legit/templates/file.html legit/templates/repo/file.html
··· 1 - {{ define "file" }} 2 1 <html> 3 - {{ template "head" . }} 4 - {{ template "repoheader" . }} 2 + {{ template "layouts/head" . }} 3 + {{ template "layouts/repo-header" . }} 5 4 <body> 6 - {{ template "nav" . }} 5 + {{ template "layouts/nav" . }} 7 6 <main> 8 7 <p>{{ .path }} (<a style="color: gray" href="?raw=true">view raw</a>)</p> 9 8 {{if .chroma }} ··· 33 32 </main> 34 33 </body> 35 34 </html> 36 - {{ end }}
-2
legit/templates/head.html legit/templates/layouts/head.html
··· 1 - {{ define "head" }} 2 1 <head> 3 2 <meta charset="utf-8" /> 4 3 <meta name="viewport" content="width=device-width, initial-scale=1" /> ··· 36 35 {{ end }} 37 36 <!-- other meta tags here --> 38 37 </head> 39 - {{ end }}
+1 -1
legit/templates/index.html
··· 1 1 {{ define "index" }} 2 2 <html> 3 - {{ template "head" . }} 3 + {{ template "layouts/head" . }} 4 4 5 5 <header> 6 6 <h1>{{ .meta.Title }}</h1>
+2 -4
legit/templates/keys.html legit/templates/settings/keys.html
··· 1 - {{ define "keys" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 4 <body> 6 5 <main> ··· 49 48 </table> 50 49 </main> 51 50 </body> 52 - </html> 53 - {{ end }} 51 + </html>
+12
legit/templates/layouts/nav.html
··· 1 + <nav> 2 + <ul> 3 + {{ if .name }} 4 + <li><a href="/{{ .name }}">summary</a></li> 5 + <li><a href="/{{ .name }}/refs">refs</a> {{ if .ref }}</li> 6 + 7 + <li><a href="/{{ .name }}/tree/{{ .ref }}/">tree</a></li> 8 + <li> 9 + <a href="/{{ .name }}/log/{{ .ref }}">log</a> {{ end }} {{ end }} 10 + </li> 11 + </ul> 12 + </nav>
+9
legit/templates/layouts/repo-header.html
··· 1 + <header> 2 + <h2> 3 + <a href="/">all repos</a> 4 + &mdash; {{ .displayname }} {{ if .ref }} 5 + <span class="ref">@ {{ .ref }}</span> 6 + {{ end }} 7 + </h2> 8 + <h3 class="desc">{{ .desc }}</h3> 9 + </header>
+3 -5
legit/templates/log.html legit/templates/repo/log.html
··· 1 - {{ define "log" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 - {{ template "repoheader" . }} 4 + {{ template "layouts/repo-header" . }} 6 5 <body> 7 - {{ template "nav" . }} 6 + {{ template "layouts/nav" . }} 8 7 <main> 9 8 {{ $repo := .name }} 10 9 <div class="log"> ··· 22 21 </main> 23 22 </body> 24 23 </html> 25 - {{ end }}
+3 -9
legit/templates/login.html legit/templates/user/login.html
··· 1 - {{ define "login" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 4 <body> 6 5 <main> 7 - <form 8 - class="form-login" 9 - method="post" 10 - action="/login" 11 - > 6 + <form class="form-login" method="post" action="/login"> 12 7 <p> 13 8 You will be redirected to bsky.social (or your PDS) to 14 9 complete login. ··· 31 26 </form> 32 27 </main> 33 28 </body> 34 - </html> 35 - {{ end }} 29 + </html>
-14
legit/templates/nav.html
··· 1 - {{ define "nav" }} 2 - <nav> 3 - <ul> 4 - {{ if .name }} 5 - <li><a href="/{{ .name }}">summary</a> 6 - <li><a href="/{{ .name }}/refs">refs</a> 7 - {{ if .ref }} 8 - <li><a href="/{{ .name }}/tree/{{ .ref }}/">tree</a> 9 - <li><a href="/{{ .name }}/log/{{ .ref }}">log</a> 10 - {{ end }} 11 - {{ end }} 12 - </ul> 13 - </nav> 14 - {{ end }}
+1 -3
legit/templates/new.html legit/templates/repo/new.html
··· 1 - {{ define "new" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 4 <body> 6 5 <main> ··· 29 28 </main> 30 29 </body> 31 30 </html> 32 - {{ end }}
+4 -6
legit/templates/refs.html legit/templates/repo/refs.html
··· 1 - {{ define "refs" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 - {{ template "repoheader" . }} 4 + {{ template "layouts/repo-header" . }} 6 5 <body> 7 - {{ template "nav" . }} 6 + {{ template "layouts/nav" . }} 8 7 <main> 9 8 {{ $name := .name }} 10 9 <h3>branches</h3> ··· 36 35 {{ end }} 37 36 </main> 38 37 </body> 39 - </html> 40 - {{ end }} 38 + </html>
-12
legit/templates/repo-header.html
··· 1 - {{ define "repoheader" }} 2 - <header> 3 - <h2> 4 - <a href="/">all repos</a> 5 - &mdash; {{ .displayname }} 6 - {{ if .ref }} 7 - <span class="ref">@ {{ .ref }}</span> 8 - {{ end }} 9 - </h2> 10 - <h3 class="desc">{{ .desc }}</h3> 11 - </header> 12 - {{ end }}
+3 -5
legit/templates/repo.html legit/templates/repo/repo.html
··· 1 - {{ define "repo" }} 2 1 <html> 3 - {{ template "head" . }} 2 + {{ template "layouts/head" . }} 4 3 5 - {{ template "repoheader" . }} 4 + {{ template "layouts/repo-header" . }} 6 5 7 6 <body> 8 - {{ template "nav" . }} 7 + {{ template "layouts/nav" . }} 9 8 <main> 10 9 {{ $repo := .name }} 11 10 <div class="log"> ··· 35 34 </main> 36 35 </body> 37 36 </html> 38 - {{ end }}
+4 -6
legit/templates/tree.html legit/templates/repo/tree.html
··· 1 - {{ define "tree" }} 2 1 <html> 3 2 4 - {{ template "head" . }} 3 + {{ template "layouts/head" . }} 5 4 6 - {{ template "repoheader" . }} 5 + {{ template "layouts/repo-header" . }} 7 6 <body> 8 - {{ template "nav" . }} 7 + {{ template "layouts/nav" . }} 9 8 <main> 10 9 {{ $repo := .name }} 11 10 {{ $ref := .ref }} ··· 51 50 </article> 52 51 </main> 53 52 </body> 54 - </html> 55 - {{ end }} 53 + </html>