hugo/hugolib/author.go
Bjørn Erik Pedersen 51c9bfbc9e Remove Authors.Sort
We may add it again in the future, but let us try to keep the API as small as possible for now.

See #1850
2016-09-17 00:50:11 +02:00

173 lines
5 KiB
Go

// Copyright 2015 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hugolib
import (
"fmt"
"regexp"
"sort"
"strings"
"github.com/spf13/cast"
)
var (
onlyNumbersRegExp = regexp.MustCompile("^[0-9]*$")
)
// Authors is a list of all authors and their metadata.
type Authors []Author
// Get returns an author from an ID
func (a Authors) Get(id string) Author {
for _, author := range a {
if author.ID == id {
return author
}
}
return Author{}
}
// Author contains details about the author of a page.
type Author struct {
ID string
GivenName string // givenName OR firstName
FirstName string // alias for GivenName
FamilyName string // familyName OR lastName
LastName string // alias for FamilyName
DisplayName string // displayName
Thumbnail string // thumbnail
Image string // image
ShortBio string // shortBio
Bio string // bio
Email string // email
Social AuthorSocial // social
Params map[string]string // params
Weight int
}
// AuthorSocial is a place to put social usernames per author. These are the
// standard keys that themes will expect to have available, but can be
// expanded to any others on a per site basis
// - website
// - github
// - facebook
// - twitter
// - googleplus
// - pinterest
// - instagram
// - youtube
// - linkedin
// - skype
type AuthorSocial map[string]string
// URL is a convenience function that provides the correct canonical URL
// for a specific social network given a username. If an unsupported network
// is requested, only the username is returned
func (as AuthorSocial) URL(key string) string {
switch key {
case "github":
return fmt.Sprintf("https://github.com/%s", as[key])
case "facebook":
return fmt.Sprintf("https://www.facebook.com/%s", as[key])
case "twitter":
return fmt.Sprintf("https://twitter.com/%s", as[key])
case "googleplus":
isNumeric := onlyNumbersRegExp.Match([]byte(as[key]))
if isNumeric {
return fmt.Sprintf("https://plus.google.com/%s", as[key])
}
return fmt.Sprintf("https://plus.google.com/+%s", as[key])
case "pinterest":
return fmt.Sprintf("https://www.pinterest.com/%s/", as[key])
case "instagram":
return fmt.Sprintf("https://www.instagram.com/%s/", as[key])
case "youtube":
return fmt.Sprintf("https://www.youtube.com/user/%s", as[key])
case "linkedin":
return fmt.Sprintf("https://www.linkedin.com/in/%s", as[key])
default:
return as[key]
}
}
func mapToAuthors(m map[string]interface{}) Authors {
authors := make(Authors, len(m))
for authorID, data := range m {
authorMap, ok := data.(map[string]interface{})
if !ok {
continue
}
authors = append(authors, mapToAuthor(authorID, authorMap))
}
sort.Stable(authors)
return authors
}
func mapToAuthor(id string, m map[string]interface{}) Author {
author := Author{ID: id}
for k, data := range m {
switch k {
case "givenName", "firstName":
author.GivenName = cast.ToString(data)
author.FirstName = author.GivenName
case "familyName", "lastName":
author.FamilyName = cast.ToString(data)
author.LastName = author.FamilyName
case "displayName":
author.DisplayName = cast.ToString(data)
case "thumbnail":
author.Thumbnail = cast.ToString(data)
case "image":
author.Image = cast.ToString(data)
case "shortBio":
author.ShortBio = cast.ToString(data)
case "bio":
author.Bio = cast.ToString(data)
case "email":
author.Email = cast.ToString(data)
case "social":
author.Social = normalizeSocial(cast.ToStringMapString(data))
case "params":
author.Params = cast.ToStringMapString(data)
}
}
// set a reasonable default for DisplayName
if author.DisplayName == "" {
author.DisplayName = author.GivenName + " " + author.FamilyName
}
return author
}
// normalizeSocial makes a naive attempt to normalize social media usernames
// and strips out extraneous characters or url info
func normalizeSocial(m map[string]string) map[string]string {
for network, username := range m {
username = strings.TrimSpace(username)
username = strings.TrimSuffix(username, "/")
strs := strings.Split(username, "/")
username = strs[len(strs)-1]
username = strings.TrimPrefix(username, "@")
username = strings.TrimPrefix(username, "+")
m[network] = username
}
return m
}
func (a Authors) Len() int { return len(a) }
func (a Authors) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a Authors) Less(i, j int) bool { return a[i].Weight < a[j].Weight }