123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- package seo
- import (
- "bytes"
- "database/sql/driver"
- "encoding/csv"
- "encoding/json"
- "strings"
- "time"
- "github.com/qor5/admin/l10n"
- "github.com/qor5/admin/media/media_library"
- h "github.com/theplant/htmlgo"
- )
- // QorSEOSettingInterface support customize Seo model
- // @snippet_begin(QorSEOSettingInterface)
- type QorSEOSettingInterface interface {
- GetName() string
- SetName(string)
- GetSEOSetting() Setting
- SetSEOSetting(Setting)
- GetVariables() Variables
- SetVariables(Variables)
- GetLocale() string
- SetLocale(string)
- GetTitle() string
- GetDescription() string
- GetKeywords() string
- GetOpenGraphTitle() string
- GetOpenGraphDescription() string
- GetOpenGraphURL() string
- GetOpenGraphType() string
- GetOpenGraphImageURL() string
- GetOpenGraphImageFromMediaLibrary() media_library.MediaBox
- GetOpenGraphMetadata() []OpenGraphMetadata
- }
- // @snippet_end
- // QorSEOSetting default seo model
- type QorSEOSetting struct {
- Name string `gorm:"primary_key"`
- Setting Setting
- Variables Variables `sql:"type:text"`
- CreatedAt time.Time
- UpdatedAt time.Time
- DeletedAt *time.Time `gorm:"index"`
- l10n.Locale
- }
- // Setting defined meta's attributes
- type Setting struct {
- Title string `gorm:"size:4294967295"`
- Description string
- Keywords string
- OpenGraphTitle string
- OpenGraphDescription string
- OpenGraphURL string
- OpenGraphType string
- OpenGraphImageURL string
- OpenGraphImageFromMediaLibrary media_library.MediaBox
- OpenGraphMetadata []OpenGraphMetadata
- EnabledCustomize bool
- }
- // OpenGraphMetadata open graph meta data
- type OpenGraphMetadata struct {
- Property string
- Content string
- }
- func (s *QorSEOSetting) SetSEOSetting(setting Setting) {
- s.Setting = setting
- }
- // GetSEOSetting get seo setting
- func (s QorSEOSetting) GetSEOSetting() Setting {
- return s.Setting
- }
- // SetVariablesSetting set variables setting
- func (s *QorSEOSetting) SetVariables(setting Variables) {
- s.Variables = setting
- }
- // GetVariablesSetting get variables setting
- func (s QorSEOSetting) GetVariables() Variables {
- return s.Variables
- }
- // GetName get QorSeoSetting's name
- func (s QorSEOSetting) GetLocale() string {
- return s.Name
- }
- // SetName set QorSeoSetting's name
- func (s *QorSEOSetting) SetLocale(locale string) {
- s.LocaleCode = locale
- }
- // GetName get QorSeoSetting's name
- func (s QorSEOSetting) GetName() string {
- return s.Name
- }
- // SetName set QorSeoSetting's name
- func (s *QorSEOSetting) SetName(name string) {
- s.Name = name
- }
- func (s QorSEOSetting) GetOpenGraphTitle() string {
- return s.Setting.OpenGraphTitle
- }
- func (s QorSEOSetting) GetOpenGraphDescription() string {
- return s.Setting.OpenGraphDescription
- }
- func (s QorSEOSetting) GetOpenGraphURL() string {
- return s.Setting.OpenGraphURL
- }
- func (s QorSEOSetting) GetOpenGraphType() string {
- return s.Setting.OpenGraphType
- }
- func (s QorSEOSetting) GetOpenGraphImageURL() string {
- return s.Setting.OpenGraphImageURL
- }
- func (s QorSEOSetting) GetOpenGraphImageFromMediaLibrary() media_library.MediaBox {
- return s.Setting.OpenGraphImageFromMediaLibrary
- }
- func (s QorSEOSetting) GetOpenGraphMetadata() []OpenGraphMetadata {
- return s.Setting.OpenGraphMetadata
- }
- // GetTitle get Setting's title
- func (s QorSEOSetting) GetTitle() string {
- return s.Setting.Title
- }
- // GetDescription get Setting's description
- func (s QorSEOSetting) GetDescription() string {
- return s.Setting.Description
- }
- // GetKeywords get Setting's keywords
- func (s QorSEOSetting) GetKeywords() string {
- return s.Setting.Keywords
- }
- // Scan scan value from database into struct
- func (setting *Setting) Scan(value interface{}) error {
- if bytes, ok := value.([]byte); ok {
- json.Unmarshal(bytes, setting)
- } else if str, ok := value.(string); ok {
- json.Unmarshal([]byte(str), setting)
- } else if strs, ok := value.([]string); ok {
- for _, str := range strs {
- json.Unmarshal([]byte(str), setting)
- }
- }
- return nil
- }
- // Value get value from struct, and save into database
- func (setting Setting) Value() (driver.Value, error) {
- result, err := json.Marshal(setting)
- return string(result), err
- }
- func (setting Setting) IsEmpty() bool {
- return setting.Title == "" && setting.Description == "" && setting.Keywords == "" &&
- setting.OpenGraphTitle == "" && setting.OpenGraphDescription == "" &&
- setting.OpenGraphURL == "" && setting.OpenGraphType == "" && setting.OpenGraphImageURL == "" &&
- setting.OpenGraphImageFromMediaLibrary.Url == "" && len(setting.OpenGraphMetadata) == 0
- }
- type Variables map[string]string
- // Scan scan value from database into struct
- func (setting *Variables) Scan(value interface{}) error {
- if bytes, ok := value.([]byte); ok {
- json.Unmarshal(bytes, setting)
- } else if str, ok := value.(string); ok {
- json.Unmarshal([]byte(str), setting)
- } else if strs, ok := value.([]string); ok {
- for _, str := range strs {
- json.Unmarshal([]byte(str), setting)
- }
- }
- return nil
- }
- // Value get value from struct, and save into database
- func (setting Variables) Value() (driver.Value, error) {
- result, err := json.Marshal(setting)
- return string(result), err
- }
- func (setting Setting) HTMLComponent(tags map[string]string) h.HTMLComponent {
- openGraphData := map[string]string{
- "og:title": setting.OpenGraphTitle,
- "og:description": setting.OpenGraphDescription,
- "og:url": setting.OpenGraphURL,
- "og:type": setting.OpenGraphType,
- "og:image": setting.OpenGraphImageURL,
- }
- for _, metavalue := range setting.OpenGraphMetadata {
- openGraphData[metavalue.Property] = metavalue.Content
- }
- for _, key := range []string{"og:title", "og:description", "og:url", "og:type", "og:image"} {
- if v := openGraphData[key]; v == "" {
- if v, ok := tags[key]; ok {
- openGraphData[key] = v
- }
- }
- }
- if openGraphData["og:type"] == "" {
- openGraphData["og:type"] = "website"
- }
- for key, value := range tags {
- if _, ok := openGraphData[key]; !ok {
- openGraphData[key] = value
- }
- }
- var openGraphDataComponents h.HTMLComponents
- for key, value := range openGraphData {
- openGraphDataComponents = append(openGraphDataComponents, h.Meta().Attr("property", key).Attr("name", key).Attr("content", value))
- }
- return h.HTMLComponents{
- h.Title(setting.Title),
- h.Meta().Attr("name", "description").Attr("content", setting.Description),
- h.Meta().Attr("name", "keywords").Attr("content", setting.Keywords),
- openGraphDataComponents,
- }
- }
- func GetOpenGraphMetadata(in string) (metadata []OpenGraphMetadata) {
- r := csv.NewReader(strings.NewReader(in))
- records, err := r.ReadAll()
- if err != nil {
- return
- }
- for _, row := range records {
- if len(row) != 2 {
- continue
- }
- metadata = append(metadata, OpenGraphMetadata{
- Property: row[0],
- Content: row[1],
- })
- }
- return
- }
- func GetOpenGraphMetadataString(metadata []OpenGraphMetadata) string {
- records := [][]string{}
- for _, m := range metadata {
- records = append(records, []string{m.Property, m.Content})
- }
- buf := new(bytes.Buffer)
- w := csv.NewWriter(buf)
- w.WriteAll(records)
- return buf.String()
- }
|