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) {
|
func notFoundHandler(repo *owl.Repository) func(http.ResponseWriter, *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
path := r.URL.Path
|
path := r.URL.Path
|
||||||
|
|
|
@ -14,10 +14,11 @@ func Router(repo *owl.Repository) http.Handler {
|
||||||
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||||
router.GET("/", repoIndexHandler(repo))
|
router.GET("/", repoIndexHandler(repo))
|
||||||
router.GET("/user/:user/", userIndexHandler(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/index.xml", userRSSHandler(repo))
|
||||||
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
router.GET("/user/:user/posts/:post/", postHandler(repo))
|
||||||
router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo))
|
router.GET("/user/:user/posts/:post/media/*filepath", postMediaHandler(repo))
|
||||||
|
router.POST("/user/:user/webmention/", userWebmentionHandler(repo))
|
||||||
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
@ -26,10 +27,11 @@ func SingleUserRouter(repo *owl.Repository) http.Handler {
|
||||||
router := httprouter.New()
|
router := httprouter.New()
|
||||||
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
router.ServeFiles("/static/*filepath", http.Dir(repo.StaticDir()))
|
||||||
router.GET("/", userIndexHandler(repo))
|
router.GET("/", userIndexHandler(repo))
|
||||||
router.POST("/webmention/", userWebmentionHandler(repo))
|
router.GET("/media/*filepath", userMediaHandler(repo))
|
||||||
router.GET("/index.xml", userRSSHandler(repo))
|
router.GET("/index.xml", userRSSHandler(repo))
|
||||||
router.GET("/posts/:post/", postHandler(repo))
|
router.GET("/posts/:post/", postHandler(repo))
|
||||||
router.GET("/posts/:post/media/*filepath", postMediaHandler(repo))
|
router.GET("/posts/:post/media/*filepath", postMediaHandler(repo))
|
||||||
|
router.POST("/webmention/", userWebmentionHandler(repo))
|
||||||
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
router.NotFound = http.HandlerFunc(notFoundHandler(repo))
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,26 @@
|
||||||
border-color: #ccc;
|
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; }
|
hgroup h2 a { color: inherit; }
|
||||||
</style>
|
</style>
|
||||||
|
@ -25,34 +45,34 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav class="container">
|
<div class="container header h-card">
|
||||||
<ul>
|
<hgroup class="header-title">
|
||||||
<li>
|
<h2><a class="p-name u-url" href="{{ .User.UrlPath }}">{{ .UserConfig.Title }}</a></h2>
|
||||||
<hgroup>
|
<h3>{{ .UserConfig.SubTitle }}</h3>
|
||||||
<h2><a href="{{ .User.UrlPath }}">{{ .UserConfig.Title }}</a></h2>
|
</hgroup>
|
||||||
<h3>{{ .UserConfig.SubTitle }}</h3>
|
|
||||||
</hgroup>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</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>
|
</header>
|
||||||
<main class="container">
|
<main class="container">
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
</main>
|
</main>
|
||||||
<footer class="container">
|
<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>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -251,3 +251,13 @@ func TestRenderIncludesFullUrl(t *testing.T) {
|
||||||
t.Error("Expected: " + post.FullUrl())
|
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
|
// creates repo/name folder if it doesn't exist
|
||||||
user_dir := new_user.Dir()
|
user_dir := new_user.Dir()
|
||||||
os.Mkdir(user_dir, 0755)
|
os.Mkdir(user_dir, 0755)
|
||||||
|
// create folders
|
||||||
os.Mkdir(path.Join(user_dir, "meta"), 0755)
|
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, "public"), 0755)
|
||||||
|
os.Mkdir(path.Join(user_dir, "media"), 0755)
|
||||||
|
|
||||||
// create Meta files
|
// create Meta files
|
||||||
os.WriteFile(path.Join(user_dir, "meta", "VERSION"), []byte(VERSION), 0644)
|
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
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (user User) MediaUrl() string {
|
||||||
|
url, _ := url.JoinPath(user.UrlPath(), "media")
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
func (user User) PostDir() string {
|
func (user User) PostDir() string {
|
||||||
return path.Join(user.Dir(), "public")
|
return path.Join(user.Dir(), "public")
|
||||||
}
|
}
|
||||||
|
@ -51,6 +56,10 @@ func (user User) MetaDir() string {
|
||||||
return path.Join(user.Dir(), "meta")
|
return path.Join(user.Dir(), "meta")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (user User) MediaDir() string {
|
||||||
|
return path.Join(user.Dir(), "media")
|
||||||
|
}
|
||||||
|
|
||||||
func (user User) ConfigFile() string {
|
func (user User) ConfigFile() string {
|
||||||
return path.Join(user.MetaDir(), "config.yml")
|
return path.Join(user.MetaDir(), "config.yml")
|
||||||
}
|
}
|
||||||
|
@ -59,6 +68,16 @@ func (user User) Name() string {
|
||||||
return user.name
|
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) {
|
func (user User) Posts() ([]*Post, error) {
|
||||||
postFiles := listDir(path.Join(user.Dir(), "public"))
|
postFiles := listDir(path.Join(user.Dir(), "public"))
|
||||||
posts := make([]*Post, 0)
|
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())
|
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