forked from gitea/gitea
1
0
Fork 0

Clean repo code

This commit is contained in:
Unknown 2014-05-05 19:58:13 -04:00
parent bbdfe25769
commit 6e3dba2cc5
13 changed files with 96 additions and 154 deletions

View File

@ -130,7 +130,7 @@ func runWeb(*cli.Context) {
m.Get("/user/:username", ignSignIn, user.Profile) m.Get("/user/:username", ignSignIn, user.Profile)
m.Group("/repo", func(r martini.Router) { m.Group("/repo", func(r martini.Router) {
r.Get("/create", repo.Create) // TODO r.Get("/create", repo.Create)
r.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost) r.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
r.Get("/migrate", repo.Migrate) r.Get("/migrate", repo.Migrate)
r.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost) r.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
@ -165,14 +165,19 @@ func runWeb(*cli.Context) {
m.Get("/template/**", dev.TemplatePreview) m.Get("/template/**", dev.TemplatePreview)
} }
reqOwner := middleware.RequireOwner
m.Group("/:username/:reponame", func(r martini.Router) { m.Group("/:username/:reponame", func(r martini.Router) {
r.Get("/settings", repo.Setting) r.Get("/settings", repo.Setting)
r.Post("/settings", repo.SettingPost) r.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingPost)
r.Get("/settings/collaboration", repo.Collaboration) r.Get("/settings/collaboration", repo.Collaboration)
r.Post("/settings/collaboration", repo.CollaborationPost) r.Post("/settings/collaboration", repo.CollaborationPost)
r.Get("/settings/hooks", repo.WebHooks) r.Get("/settings/hooks", repo.WebHooks) // TODO
r.Get("/settings/hooks/add", repo.WebHooksAdd) r.Get("/settings/hooks/add", repo.WebHooksAdd)
r.Get("/settings/hooks/id", repo.WebHooksEdit) r.Get("/settings/hooks/id", repo.WebHooksEdit)
}, reqSignIn, middleware.RepoAssignment(true), reqOwner())
m.Group("/:username/:reponame", func(r martini.Router) {
r.Get("/action/:action", repo.Action) r.Get("/action/:action", repo.Action)
r.Get("/issues/new", repo.CreateIssue) r.Get("/issues/new", repo.CreateIssue)
r.Post("/issues/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost) r.Post("/issues/new", bindIgnErr(auth.CreateIssueForm{}), repo.CreateIssuePost)

View File

@ -11,7 +11,6 @@ import (
"github.com/go-martini/martini" "github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding" "github.com/gogits/gogs/modules/middleware/binding"
) )
@ -36,20 +35,6 @@ func (f *AdminEditUserForm) Name(field string) string {
} }
func (f *AdminEditUserForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) { func (f *AdminEditUserForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("AdminEditUserForm.Validate: %v", err)
}
return
}
validate(errors, data, f) validate(errors, data, f)
} }

View File

@ -183,20 +183,6 @@ func (f *InstallForm) Name(field string) string {
} }
func (f *InstallForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) { func (f *InstallForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("InstallForm.Validate: %v", err)
}
return
}
validate(errors, data, f) validate(errors, data, f)
} }

View File

@ -11,7 +11,6 @@ import (
"github.com/go-martini/martini" "github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding" "github.com/gogits/gogs/modules/middleware/binding"
) )
@ -44,20 +43,6 @@ func (f *AuthenticationForm) Name(field string) string {
} }
func (f *AuthenticationForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) { func (f *AuthenticationForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("AuthenticationForm.Validate: %v", err)
}
return
}
validate(errors, data, f) validate(errors, data, f)
} }

View File

@ -11,12 +11,11 @@ import (
"github.com/go-martini/martini" "github.com/go-martini/martini"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/middleware/binding" "github.com/gogits/gogs/modules/middleware/binding"
) )
type CreateRepoForm struct { type CreateRepoForm struct {
RepoName string `form:"repo" binding:"Required;AlphaDash"` RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
Private bool `form:"private"` Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(100)"` Description string `form:"desc" binding:"MaxSize(100)"`
Language string `form:"language"` Language string `form:"language"`
@ -33,21 +32,7 @@ func (f *CreateRepoForm) Name(field string) string {
} }
func (f *CreateRepoForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) { func (f *CreateRepoForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true
AssignForm(f, data)
if len(errors.Overall) > 0 {
for _, err := range errors.Overall {
log.Error("CreateRepoForm.Validate: %v", err)
}
return
}
validate(errors, data, f) validate(errors, data, f)
} }
@ -55,7 +40,7 @@ type MigrateRepoForm struct {
Url string `form:"url" binding:"Url"` Url string `form:"url" binding:"Url"`
AuthUserName string `form:"auth_username"` AuthUserName string `form:"auth_username"`
AuthPasswd string `form:"auth_password"` AuthPasswd string `form:"auth_password"`
RepoName string `form:"repo" binding:"Required;AlphaDash"` RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
Mirror bool `form:"mirror"` Mirror bool `form:"mirror"`
Private bool `form:"private"` Private bool `form:"private"`
Description string `form:"desc" binding:"MaxSize(100)"` Description string `form:"desc" binding:"MaxSize(100)"`
@ -71,20 +56,30 @@ func (f *MigrateRepoForm) Name(field string) string {
} }
func (f *MigrateRepoForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) { func (f *MigrateRepoForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) {
if req.Method == "GET" || errors.Count() == 0 {
return
}
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
data["HasError"] = true validate(errors, data, f)
AssignForm(f, data) }
if len(errors.Overall) > 0 { type RepoSettingForm struct {
for _, err := range errors.Overall { RepoName string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"`
log.Error("MigrateRepoForm.Validate: %v", err) Description string `form:"desc" binding:"MaxSize(100)"`
} Website string `form:"url" binding:"Url;MaxSize(100)"`
return Branch string `form:"branch"`
} Interval int `form:"interval"`
Private bool `form:"private"`
GoGet bool `form:"goget"`
}
func (f *RepoSettingForm) Name(field string) string {
names := map[string]string{
"RepoName": "Repository name",
"Description": "Description",
"Website": "Website address",
}
return names[field]
}
func (f *RepoSettingForm) Validate(errors *binding.BindingErrors, req *http.Request, context martini.Context) {
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
validate(errors, data, f) validate(errors, data, f)
} }

View File

@ -267,7 +267,10 @@ func validateStruct(errors *BindingErrors, obj interface{}) {
break break
} }
case rule == "Url": case rule == "Url":
if !urlPattern.MatchString(fmt.Sprintf("%v", fieldValue)) { str := fmt.Sprintf("%v", fieldValue)
if len(str) == 0 {
continue
} else if !urlPattern.MatchString(str) {
errors.Fields[field.Name] = BindingUrlError errors.Fields[field.Name] = BindingUrlError
break break
} }

View File

@ -7,6 +7,7 @@ package middleware
import ( import (
"errors" "errors"
"fmt" "fmt"
"net/url"
"strings" "strings"
"github.com/go-martini/martini" "github.com/go-martini/martini"
@ -238,3 +239,17 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching ctx.Data["IsRepositoryWatching"] = ctx.Repo.IsWatching
} }
} }
func RequireOwner() martini.Handler {
return func(ctx *Context) {
if !ctx.Repo.IsOwner {
if !ctx.IsSigned {
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(ctx.Req.RequestURI))
ctx.Redirect("/user/login")
return
}
ctx.Handle(404, ctx.Req.RequestURI, nil)
return
}
}
}

View File

@ -112,14 +112,27 @@ func Users(ctx *middleware.Context) {
ctx.Data["PageIsUsers"] = true ctx.Data["PageIsUsers"] = true
var err error var err error
ctx.Data["Users"], err = models.GetUsers(100, 0) ctx.Data["Users"], err = models.GetUsers(200, 0)
if err != nil { if err != nil {
ctx.Handle(200, "admin.Users", err) ctx.Handle(500, "admin.Users", err)
return return
} }
ctx.HTML(200, "admin/users") ctx.HTML(200, "admin/users")
} }
func Repositories(ctx *middleware.Context) {
ctx.Data["Title"] = "Repository Management"
ctx.Data["PageIsRepos"] = true
var err error
ctx.Data["Repos"], err = models.GetRepos(200, 0)
if err != nil {
ctx.Handle(500, "admin.Repositories", err)
return
}
ctx.HTML(200, "admin/repos")
}
func Auths(ctx *middleware.Context) { func Auths(ctx *middleware.Context) {
ctx.Data["Title"] = "Auth Sources" ctx.Data["Title"] = "Auth Sources"
ctx.Data["PageIsAuths"] = true ctx.Data["PageIsAuths"] = true
@ -127,25 +140,12 @@ func Auths(ctx *middleware.Context) {
var err error var err error
ctx.Data["Sources"], err = models.GetAuths() ctx.Data["Sources"], err = models.GetAuths()
if err != nil { if err != nil {
ctx.Handle(200, "admin.Auths", err) ctx.Handle(500, "admin.Auths", err)
return return
} }
ctx.HTML(200, "admin/auths") ctx.HTML(200, "admin/auths")
} }
func Repositories(ctx *middleware.Context) {
ctx.Data["Title"] = "Repository Management"
ctx.Data["PageIsRepos"] = true
var err error
ctx.Data["Repos"], err = models.GetRepos(100, 0)
if err != nil {
ctx.Handle(200, "admin.Repositories", err)
return
}
ctx.HTML(200, "admin/repos")
}
func Config(ctx *middleware.Context) { func Config(ctx *middleware.Context) {
ctx.Data["Title"] = "Server Configuration" ctx.Data["Title"] = "Server Configuration"
ctx.Data["PageIsConfig"] = true ctx.Data["PageIsConfig"] = true

View File

@ -34,19 +34,18 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
ctx.Data["Title"] = "New Account" ctx.Data["Title"] = "New Account"
ctx.Data["PageIsUsers"] = true ctx.Data["PageIsUsers"] = true
if form.Password != form.RetypePasswd {
ctx.Data["HasError"] = true
ctx.Data["Err_Password"] = true
ctx.Data["Err_RetypePasswd"] = true
ctx.Data["ErrorMsg"] = "Password and re-type password are not same"
auth.AssignForm(form, ctx.Data)
}
if ctx.HasError() { if ctx.HasError() {
ctx.HTML(200, "admin/users/new") ctx.HTML(200, "admin/users/new")
return return
} }
if form.Password != form.RetypePasswd {
ctx.Data["Err_Password"] = true
ctx.Data["Err_RetypePasswd"] = true
ctx.RenderWithErr("Password and re-type password are not same.", "admin/users/new", &form)
return
}
u := &models.User{ u := &models.User{
Name: form.UserName, Name: form.UserName,
Email: form.Email, Email: form.Email,

View File

@ -8,13 +8,14 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"github.com/gogits/git"
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/go-martini/martini" "github.com/go-martini/martini"
"github.com/gogits/git"
"github.com/gogits/gogs/models" "github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"

View File

@ -11,6 +11,7 @@ import (
"github.com/gogits/git" "github.com/gogits/git"
"github.com/gogits/gogs/models" "github.com/gogits/gogs/models"
"github.com/gogits/gogs/modules/auth"
"github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/base"
"github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/log"
"github.com/gogits/gogs/modules/mailer" "github.com/gogits/gogs/modules/mailer"
@ -18,27 +19,22 @@ import (
) )
func Setting(ctx *middleware.Context) { func Setting(ctx *middleware.Context) {
if !ctx.Repo.IsOwner {
ctx.Handle(404, "repo.Setting", nil)
return
}
ctx.Data["IsRepoToolbarSetting"] = true ctx.Data["IsRepoToolbarSetting"] = true
ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - settings" ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - settings"
ctx.HTML(200, "repo/setting") ctx.HTML(200, "repo/setting")
} }
func SettingPost(ctx *middleware.Context) { func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) {
if !ctx.Repo.IsOwner {
ctx.Error(404)
return
}
ctx.Data["IsRepoToolbarSetting"] = true ctx.Data["IsRepoToolbarSetting"] = true
switch ctx.Query("action") { switch ctx.Query("action") {
case "update": case "update":
newRepoName := ctx.Query("name") if ctx.HasError() {
ctx.HTML(200, "repo/setting")
return
}
newRepoName := form.RepoName
// Check if repository name has been changed. // Check if repository name has been changed.
if ctx.Repo.Repository.Name != newRepoName { if ctx.Repo.Repository.Name != newRepoName {
isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName) isExist, err := models.IsRepositoryExist(ctx.Repo.Owner, newRepoName)
@ -57,15 +53,15 @@ func SettingPost(ctx *middleware.Context) {
ctx.Repo.Repository.Name = newRepoName ctx.Repo.Repository.Name = newRepoName
} }
br := ctx.Query("branch") br := form.Branch
if git.IsBranchExist(models.RepoPath(ctx.User.Name, ctx.Repo.Repository.Name), br) { if git.IsBranchExist(models.RepoPath(ctx.User.Name, ctx.Repo.Repository.Name), br) {
ctx.Repo.Repository.DefaultBranch = br ctx.Repo.Repository.DefaultBranch = br
} }
ctx.Repo.Repository.Description = ctx.Query("desc") ctx.Repo.Repository.Description = form.Description
ctx.Repo.Repository.Website = ctx.Query("site") ctx.Repo.Repository.Website = form.Website
ctx.Repo.Repository.IsPrivate = ctx.Query("private") == "on" ctx.Repo.Repository.IsPrivate = form.Private
ctx.Repo.Repository.IsGoget = ctx.Query("goget") == "on" ctx.Repo.Repository.IsGoget = form.GoGet
if err := models.UpdateRepository(ctx.Repo.Repository); err != nil { if err := models.UpdateRepository(ctx.Repo.Repository); err != nil {
ctx.Handle(404, "repo.SettingPost(update)", err) ctx.Handle(404, "repo.SettingPost(update)", err)
return return
@ -73,12 +69,9 @@ func SettingPost(ctx *middleware.Context) {
log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name) log.Trace("%s Repository updated: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
if ctx.Repo.Repository.IsMirror { if ctx.Repo.Repository.IsMirror {
if len(ctx.Query("interval")) > 0 { if form.Interval > 0 {
var err error ctx.Repo.Mirror.Interval = form.Interval
ctx.Repo.Mirror.Interval, err = base.StrTo(ctx.Query("interval")).Int() if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil {
if err != nil {
log.Error("repo.SettingPost(get mirror interval): %v", err)
} else if err = models.UpdateMirror(ctx.Repo.Mirror); err != nil {
log.Error("repo.SettingPost(UpdateMirror): %v", err) log.Error("repo.SettingPost(UpdateMirror): %v", err)
} }
} }
@ -125,11 +118,6 @@ func SettingPost(ctx *middleware.Context) {
} }
func Collaboration(ctx *middleware.Context) { func Collaboration(ctx *middleware.Context) {
if !ctx.Repo.IsOwner {
ctx.Error(404)
return
}
repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/") repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/")
ctx.Data["IsRepoToolbarCollaboration"] = true ctx.Data["IsRepoToolbarCollaboration"] = true
ctx.Data["Title"] = repoLink + " - collaboration" ctx.Data["Title"] = repoLink + " - collaboration"
@ -166,11 +154,6 @@ func Collaboration(ctx *middleware.Context) {
} }
func CollaborationPost(ctx *middleware.Context) { func CollaborationPost(ctx *middleware.Context) {
if !ctx.Repo.IsOwner {
ctx.Error(404)
return
}
repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/") repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/")
name := strings.ToLower(ctx.Query("collaborator")) name := strings.ToLower(ctx.Query("collaborator"))
if len(name) == 0 || ctx.Repo.Owner.LowerName == name { if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
@ -215,33 +198,18 @@ func CollaborationPost(ctx *middleware.Context) {
} }
func WebHooks(ctx *middleware.Context) { func WebHooks(ctx *middleware.Context) {
if !ctx.Repo.IsOwner {
ctx.Handle(404, "repo.WebHooks", nil)
return
}
ctx.Data["IsRepoToolbarWebHooks"] = true ctx.Data["IsRepoToolbarWebHooks"] = true
ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Web Hooks" ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Web Hooks"
ctx.HTML(200, "repo/hooks") ctx.HTML(200, "repo/hooks")
} }
func WebHooksAdd(ctx *middleware.Context) { func WebHooksAdd(ctx *middleware.Context) {
if !ctx.Repo.IsOwner {
ctx.Handle(404, "repo.WebHooksAdd", nil)
return
}
ctx.Data["IsRepoToolbarWebHooks"] = true ctx.Data["IsRepoToolbarWebHooks"] = true
ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Add Web Hook" ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Add Web Hook"
ctx.HTML(200, "repo/hooks_add") ctx.HTML(200, "repo/hooks_add")
} }
func WebHooksEdit(ctx *middleware.Context) { func WebHooksEdit(ctx *middleware.Context) {
if !ctx.Repo.IsOwner {
ctx.Handle(404, "repo.WebHooksEdit", nil)
return
}
ctx.Data["IsRepoToolbarWebHooks"] = true ctx.Data["IsRepoToolbarWebHooks"] = true
ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Web Hook Name" ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Web Hook Name"
ctx.HTML(200, "repo/hooks_edit") ctx.HTML(200, "repo/hooks_edit")

View File

@ -217,7 +217,7 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) {
if form.Password != form.RetypePasswd { if form.Password != form.RetypePasswd {
ctx.Data["Err_Password"] = true ctx.Data["Err_Password"] = true
ctx.Data["Err_RetypePasswd"] = true ctx.Data["Err_RetypePasswd"] = true
ctx.RenderWithErr("Password and re-type password are not same", "user/signup", &form) ctx.RenderWithErr("Password and re-type password are not same.", "user/signup", &form)
return return
} }

View File

@ -3,7 +3,7 @@
<li class="list-group-item{{if .PageIsDashboard}} active{{end}}"><a href="/admin"><i class="fa fa-tachometer fa-lg"></i> Dashboard</a></li> <li class="list-group-item{{if .PageIsDashboard}} active{{end}}"><a href="/admin"><i class="fa fa-tachometer fa-lg"></i> Dashboard</a></li>
<li class="list-group-item{{if .PageIsUsers}} active{{end}}"><a href="/admin/users"><i class="fa fa-users fa-lg"></i> Users</a></li> <li class="list-group-item{{if .PageIsUsers}} active{{end}}"><a href="/admin/users"><i class="fa fa-users fa-lg"></i> Users</a></li>
<li class="list-group-item{{if .PageIsRepos}} active{{end}}"><a href="/admin/repos"><i class="fa fa-book fa-lg"></i> Repositories</a></li> <li class="list-group-item{{if .PageIsRepos}} active{{end}}"><a href="/admin/repos"><i class="fa fa-book fa-lg"></i> Repositories</a></li>
<li class="list-group-item{{if .PageIsConfig}} active{{end}}"><a href="/admin/config"><i class="fa fa-cogs fa-lg"></i> Configuration</a></li>
<li class="list-group-item{{if .PageIsAuths}} active{{end}}"><a href="/admin/auths"><i class="fa fa-certificate fa-lg"></i> Authentication</a></li> <li class="list-group-item{{if .PageIsAuths}} active{{end}}"><a href="/admin/auths"><i class="fa fa-certificate fa-lg"></i> Authentication</a></li>
<li class="list-group-item{{if .PageIsConfig}} active{{end}}"><a href="/admin/config"><i class="fa fa-cogs fa-lg"></i> Configuration</a></li>
</ul> </ul>
</div> </div>