Add more types to OpenGraph helper.

This commit is contained in:
Dillon Kearns 2019-08-05 12:59:31 -07:00
parent 3a1d525692
commit d3480e2a81
2 changed files with 162 additions and 70 deletions

View File

@ -180,9 +180,20 @@ pageTags metadata =
Metadata.Page record -> Metadata.Page record ->
OpenGraph.website OpenGraph.website
{ url = canonicalUrl { url = canonicalUrl
, name = "elm-pages" , siteName = "elm-pages"
, image = { url = "", alt = "", dimensions = Nothing, secureUrl = Nothing } , image =
, description = Just siteTagline { url = ""
, alt = ""
, dimensions = Nothing
, secureUrl = Nothing
, mimeType = Nothing
}
, description = siteTagline
, alternateLocales = []
, audio = Nothing
, locale = Nothing
, title = "elm-pages"
, video = Nothing
} }
Metadata.Article meta -> Metadata.Article meta ->
@ -214,11 +225,20 @@ pageTags metadata =
, alt = description , alt = description
, dimensions = Nothing , dimensions = Nothing
, secureUrl = Nothing , secureUrl = Nothing
, mimeType = Nothing
} }
, name = title , title = title
, url = url , url = url
, description = "" , description = ""
, tags = []
, section = Nothing
, siteName = "elm-pages" , siteName = "elm-pages"
, alternateLocales = []
, audio = Nothing
, locale = Nothing
, video = Nothing
}
{ tags = []
, section = Nothing
, publishedTime = Nothing
, modifiedTime = Nothing
, expirationTime = Nothing
} }

View File

@ -9,11 +9,7 @@ import Pages.Head as Head
{-| <https://ogp.me/#type_website> {-| <https://ogp.me/#type_website>
-} -}
website : website :
{ url : String Common
, name : String
, image : Image
, description : Maybe String
}
-> List Head.Tag -> List Head.Tag
website details = website details =
Website details |> tags Website details |> tags
@ -22,65 +18,128 @@ website details =
{-| See <https://ogp.me/#type_article> {-| See <https://ogp.me/#type_article>
-} -}
article : article :
{ image : Image Common
, name : String ->
, url : String { tags : List String
, description : String , section : Maybe String
, tags : List String , publishedTime : Maybe Iso8601DateTime
, section : Maybe String , modifiedTime : Maybe Iso8601DateTime
, siteName : String , expirationTime : Maybe Iso8601DateTime
} }
-> List Head.Tag -> List Head.Tag
article details = article common details =
Article details |> tags Article common details |> tags
{-| See <https://ogp.me/#type_book> {-| See <https://ogp.me/#type_book>
-} -}
book : book :
{ image : Image Common
, title : String ->
{ tags : List String
, isbn : Maybe String
, releaseDate : Maybe Iso8601DateTime
}
-> List Head.Tag
book common details =
Book common details |> tags
{-| These fields apply to any type in the og object types
See <https://ogp.me/#metadata> and <https://ogp.me/#optional>
Skipping this for now, if there's a use case I can add it in:
- og:determiner - The word that appears before this object's title in a sentence. An enum of (a, an, the, "", auto). If auto is chosen, the consumer of your data should chose between "a" or "an". Default is "" (blank).
-}
type alias Common =
{ title : String
, image : Image
, url : String , url : String
, description : String , description : String
, tags : List String
, siteName : String , siteName : String
, isbn : Maybe String , audio : Maybe Audio
, releaseDate : Maybe ISO8601DateTime , video : Maybe Video
, locale : Maybe Locale
, alternateLocales : List Locale
} }
-> List Head.Tag
book details =
Book details |> tags tagsForCommon common =
tagsForImage common.image
++ (common.video |> Maybe.map tagsForVideo |> Maybe.withDefault [])
++ [ ( "og:title", Just common.title )
, ( "og:url", Just common.url )
, ( "og:description", Just common.description )
, ( "og:site_name", Just common.siteName )
, ( "og:locale", common.locale )
]
++ (common.alternateLocales
|> List.map
(\alternateLocale ->
( "og:locale:alternate", Just alternateLocale )
)
)
{-| See the audio section in <https://ogp.me/#structured>
Example:
{ url = "http://example.com/sound.mp3"
, secureUrl = Just "https://secure.example.com/sound.mp3"
mimeType = Just "audio/mpeg"
}
-}
type alias Audio =
{ url : String
, secureUrl : Maybe String
, mimeType : Maybe String
}
tagsForAudio : Audio -> List ( String, Maybe String )
tagsForAudio audio =
[ ( "og:audio", Just audio.url )
, ( "og:audio:secure_url", audio.secureUrl )
, ( "og:audio:type", audio.mimeType )
]
type alias Locale =
-- TODO make this more type-safe
String
type Content type Content
= Website = Website Common
{ url : String
, name : String
, image : Image
, description : Maybe String
}
| Article | Article
{ image : Image Common
, name : String { tags : List String
, url : String
, description : String
, tags : List String
, section : Maybe String , section : Maybe String
, siteName : String , publishedTime : Maybe Iso8601DateTime
, modifiedTime : Maybe Iso8601DateTime
, expirationTime : Maybe Iso8601DateTime
} }
| Book | Book
{ image : Image Common
, title : String { tags : List String
, url : String
, description : String
, tags : List String
, siteName : String
, isbn : Maybe String , isbn : Maybe String
, releaseDate : Maybe ISO8601DateTime , releaseDate : Maybe Iso8601DateTime
} }
type alias ISO8601DateTime = {-| <https://en.wikipedia.org/wiki/ISO_8601>
-}
type alias Iso8601DateTime =
-- TODO should be more type-safe here
String
{-| <https://en.wikipedia.org/wiki/Media_type>
-}
type alias MimeType =
-- TODO should be more type-safe here -- TODO should be more type-safe here
String String
@ -91,6 +150,7 @@ type alias Image =
{ url : String { url : String
, alt : String , alt : String
, dimensions : Maybe { width : Int, height : Int } , dimensions : Maybe { width : Int, height : Int }
, mimeType : Maybe String
, secureUrl : Maybe String , secureUrl : Maybe String
} }
@ -98,47 +158,59 @@ type alias Image =
tagsForImage : Image -> List ( String, Maybe String ) tagsForImage : Image -> List ( String, Maybe String )
tagsForImage image = tagsForImage image =
[ ( "og:image", Just image.url ) [ ( "og:image", Just image.url )
, ( "og:image:secure_url", image.secureUrl )
, ( "og:image:alt", Just image.alt ) , ( "og:image:alt", Just image.alt )
, ( "og:image:width", image.dimensions |> Maybe.map .width |> Maybe.map String.fromInt ) , ( "og:image:width", image.dimensions |> Maybe.map .width |> Maybe.map String.fromInt )
, ( "og:image:height", image.dimensions |> Maybe.map .height |> Maybe.map String.fromInt ) , ( "og:image:height", image.dimensions |> Maybe.map .height |> Maybe.map String.fromInt )
] ]
{-| See <https://ogp.me/#structured>
-}
type alias Video =
{ url : String
, mimeType : Maybe String
, dimensions : Maybe { width : Int, height : Int }
, secureUrl : Maybe String
}
tagsForVideo : Video -> List ( String, Maybe String )
tagsForVideo video =
[ ( "og:video", Just video.url )
, ( "og:video:secure_url", video.secureUrl )
, ( "og:video:width", video.dimensions |> Maybe.map .width |> Maybe.map String.fromInt )
, ( "og:video:height", video.dimensions |> Maybe.map .height |> Maybe.map String.fromInt )
]
tags : Content -> List Head.Tag tags : Content -> List Head.Tag
tags content = tags content =
(case content of (case content of
Website details -> Website common ->
tagsForImage details.image tagsForCommon common
++ [ ( "og:type", Just "website" ) ++ [ ( "og:type", Just "website" )
, ( "og:url", Just details.url )
, ( "og:locale", Just "en" )
, ( "og:site_name", Just details.name )
, ( "og:title", Just details.name )
, ( "og:description", details.description )
] ]
Article details -> Article common details ->
tagsForImage details.image {-
TODO
- article:author - profile array - Writers of the article.
-}
tagsForCommon common
++ [ ( "og:type", Just "article" ) ++ [ ( "og:type", Just "article" )
, ( "og:url", Just details.url )
, ( "og:locale", Just "en" ) -- TODO make locale configurable
, ( "og:site_name", Just details.siteName )
, ( "og:title", Just details.name )
, ( "og:description", Just details.description )
, ( "article:section", details.section ) , ( "article:section", details.section )
, ( "article:published_time", details.publishedTime )
, ( "article:modified_time", details.modifiedTime )
, ( "article:expiration_time", details.expirationTime )
] ]
++ List.map ++ List.map
(\tag -> ( "article:tag", tag |> Just )) (\tag -> ( "article:tag", tag |> Just ))
details.tags details.tags
Book details -> Book common details ->
tagsForImage details.image tagsForCommon common
++ [ ( "og:type", Just "book" ) ++ [ ( "og:type", Just "book" )
, ( "og:url", Just details.url )
, ( "og:locale", Just "en" ) -- TODO make locale configurable
, ( "og:site_name", Just details.siteName )
, ( "og:title", Just details.title )
, ( "og:description", Just details.description )
, ( "og:isbn", details.isbn ) , ( "og:isbn", details.isbn )
, ( "og:release_date", details.releaseDate ) , ( "og:release_date", details.releaseDate )
] ]