avatar and new header design
This commit is contained in:
parent
ae29a0221c
commit
534dc3ba9b
|
@ -237,6 +237,26 @@ func postMediaHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Requ
|
|||
}
|
||||
}
|
||||
|
||||
func userMediaHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
filepath := ps.ByName("filepath")
|
||||
|
||||
user, err := getUserFromRepo(repo, ps)
|
||||
if err != nil {
|
||||
println("Error getting user: ", err.Error())
|
||||
notFoundHandler(repo)(w, r)
|
||||
return
|
||||
}
|
||||
filepath = path.Join(user.MediaDir(), filepath)
|
||||
if _, err := os.Stat(filepath); err != nil {
|
||||
println("Error getting file: ", err.Error())
|
||||
notFoundHandler(repo)(w, r)
|
||||
return
|
||||
}
|
||||
http.ServeFile(w, r, filepath)
|
||||
}
|
||||
}
|
||||
|
||||
func notFoundHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Path
|
||||
|
|
|
@ -14,10 +14,11 @@ func Router(repo *owl.Repository) http.Handler {
|
|||
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||
router.GET("/", repoIndexHandler(repo))
|
||||
router.GET("/user/:user/", userIndexHandler(repo))
|
||||
router.POST("/user/:user/webmention/", userWebmentionHandler(repo))
|
||||
router.GET("/user/:user/media/*filepath", userMediaHandler(repo))
|
||||
router.GET("/user/:user/index.xml", userRSSHandler(repo))
|
||||
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
||||
router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo))
|
||||
router.POST("/user/:user/webmention/", userWebmentionHandler(repo))
|
||||
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
||||
return router
|
||||
}
|
||||
|
@ -26,10 +27,11 @@ func SingleUserRouter(repo *owl.Repository) http.Handler {
|
|||
router := httprouter.New()
|
||||
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||
router.GET("/", userIndexHandler(repo))
|
||||
router.POST("/webmention/", userWebmentionHandler(repo))
|
||||
router.GET("/media/*filepath", userMediaHandler(repo))
|
||||
router.GET("/index.xml", userRSSHandler(repo))
|
||||
router.GET("/posts/:post/", postHandler(repo))
|
||||
router.GET("/posts/:post/media/*filepath", postMediaHandler(repo))
|
||||
router.POST("/webmention/", userWebmentionHandler(repo))
|
||||
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
||||
return router
|
||||
}
|
||||
|
|
|
@ -18,6 +18,26 @@
|
|||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
float: left;
|
||||
margin-right: 1rem;
|
||||
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
.header-profile {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
hgroup h2 a { color: inherit; }
|
||||
</style>
|
||||
|
@ -25,34 +45,34 @@
|
|||
|
||||
<body>
|
||||
<header>
|
||||
<nav class="container">
|
||||
<ul>
|
||||
<li>
|
||||
<hgroup>
|
||||
<h2><a href="{{ .User.UrlPath }}">{{ .UserConfig.Title }}</a></h2>
|
||||
<h3>{{ .UserConfig.SubTitle }}</h3>
|
||||
</hgroup>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="container header h-card">
|
||||
<hgroup class="header-title">
|
||||
<h2><a class="p-name u-url" href="{{ .User.UrlPath }}">{{ .UserConfig.Title }}</a></h2>
|
||||
<h3>{{ .UserConfig.SubTitle }}</h3>
|
||||
</hgroup>
|
||||
|
||||
</nav>
|
||||
<div class="header-profile">
|
||||
{{ if .User.AvatarUrl }}
|
||||
<img class="u-logo avatar" src="{{ .User.AvatarUrl }}" alt="{{ .UserConfig.Title }}" width="100" height="100" />
|
||||
{{ end }}
|
||||
<div style="float: right; list-style: none;">
|
||||
{{ if .UserConfig.TwitterHandle}}
|
||||
<li><a href="https://twitter.com/{{.UserConfig.TwitterHandle}}" rel="me">@{{.UserConfig.TwitterHandle}} on Twitter</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ if .UserConfig.GitHubHandle}}
|
||||
<li><a href="https://github.com/{{.UserConfig.GitHubHandle}}" rel="me">@{{.UserConfig.GitHubHandle}} on GitHub</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</header>
|
||||
<main class="container">
|
||||
{{ .Content }}
|
||||
</main>
|
||||
<footer class="container">
|
||||
<nav>
|
||||
<ul>
|
||||
{{ if .UserConfig.TwitterHandle}}
|
||||
<li><a href="https://twitter.com/{{.UserConfig.TwitterHandle}}" rel="me">@{{.UserConfig.TwitterHandle}} on Twitter</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ if .UserConfig.GitHubHandle}}
|
||||
<li><a href="https://github.com/{{.UserConfig.GitHubHandle}}" rel="me">@{{.UserConfig.GitHubHandle}} on GitHub</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</nav>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -251,3 +251,13 @@ func TestRenderIncludesFullUrl(t *testing.T) {
|
|||
t.Error("Expected: " + post.FullUrl())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddAvatarIfExist(t *testing.T) {
|
||||
user := getTestUser()
|
||||
os.WriteFile(path.Join(user.MediaDir(), "avatar.png"), []byte("test"), 0644)
|
||||
|
||||
result, _ := owl.RenderIndexPage(user)
|
||||
if !strings.Contains(result, "avatar.png") {
|
||||
t.Error("Avatar not rendered. Got: " + result)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,9 +136,10 @@ func (repo *Repository) CreateUser(name string) (User, error) {
|
|||
// creates repo/name folder if it doesn't exist
|
||||
user_dir := new_user.Dir()
|
||||
os.Mkdir(user_dir, 0755)
|
||||
// create folders
|
||||
os.Mkdir(path.Join(user_dir, "meta"), 0755)
|
||||
// create public folder
|
||||
os.Mkdir(path.Join(user_dir, "public"), 0755)
|
||||
os.Mkdir(path.Join(user_dir, "media"), 0755)
|
||||
|
||||
// create Meta files
|
||||
os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte(VERSION), 0644)
|
||||
|
|
19
user.go
19
user.go
|
@ -43,6 +43,11 @@ func (user User) WebmentionUrl() string {
|
|||
return url
|
||||
}
|
||||
|
||||
func (user User) MediaUrl() string {
|
||||
url, _ := url.JoinPath(user.UrlPath(), "media")
|
||||
return url
|
||||
}
|
||||
|
||||
func (user User) PostDir() string {
|
||||
return path.Join(user.Dir(), "public")
|
||||
}
|
||||
|
@ -51,6 +56,10 @@ func (user User) MetaDir() string {
|
|||
return path.Join(user.Dir(), "meta")
|
||||
}
|
||||
|
||||
func (user User) MediaDir() string {
|
||||
return path.Join(user.Dir(), "media")
|
||||
}
|
||||
|
||||
func (user User) ConfigFile() string {
|
||||
return path.Join(user.MetaDir(), "config.yml")
|
||||
}
|
||||
|
@ -59,6 +68,16 @@ func (user User) Name() string {
|
|||
return user.name
|
||||
}
|
||||
|
||||
func (user User) AvatarUrl() string {
|
||||
for _, ext := range []string{".jpg", ".jpeg", ".png", ".gif"} {
|
||||
if fileExists(path.Join(user.MediaDir(), "avatar"+ext)) {
|
||||
url, _ := url.JoinPath(user.MediaUrl(), "avatar"+ext)
|
||||
return url
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (user User) Posts() ([]*Post, error) {
|
||||
postFiles := listDir(path.Join(user.Dir(), "public"))
|
||||
posts := make([]*Post, 0)
|
||||
|
|
15
user_test.go
15
user_test.go
|
@ -302,3 +302,18 @@ func TestPostsSortedByPublishingDateBrokenAtBottom(t *testing.T) {
|
|||
t.Error("Wrong Id, Got: " + posts[1].Id())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAvatarEmptyIfNotExist(t *testing.T) {
|
||||
user := getTestUser()
|
||||
if user.AvatarUrl() != "" {
|
||||
t.Error("Avatar should be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAvatarSetIfFileExist(t *testing.T) {
|
||||
user := getTestUser()
|
||||
os.WriteFile(path.Join(user.MediaDir(), "avatar.png"), []byte("test"), 0644)
|
||||
if user.AvatarUrl() == "" {
|
||||
t.Error("Avatar should not be empty")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue