Skip to content

Commit

Permalink
Add twitter card meta (#499)
Browse files Browse the repository at this point in the history
- Rename `feed.siteUrl` to `page.siteUrl`
- Automatically prepend `page.siteUrl` to `page.image` if the latter is relative URL
- Add `page.twitter.card` metadata
  • Loading branch information
srid authored Jan 19, 2024
1 parent ac61c6b commit bf573e7
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 10 deletions.
5 changes: 2 additions & 3 deletions docs/guide/feed.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ path:blog/*

If the note is named `blog.md`, then the feed will be available at `blog.xml`.

> [!note] `feed.siteUrl`
> You must set `feed.siteUrl` (see below) in the [[yaml-config|index.yaml]] for the feed to be generated.
> [!note] `page.siteUrl`
> You must set `page.siteUrl` (see below) in the [[yaml-config|index.yaml]] for the feed to be generated.
## Example

Expand All @@ -28,7 +28,6 @@ An example is available in the [[query]] note. You can access its feed at [query

Here are the supported settings:

- `feed.siteUrl`: the site url, default to global setting from the [[yaml-config|index.yaml]].
- `feed.title`: the feed title, default to the note title.
- `feed.limit`: the maximum number of notes to include in the feed.

Expand Down
4 changes: 4 additions & 0 deletions docs/guide/html-template/ogp.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Emanote generates OGP meta tags for each note, using the following rules:
| `og:type` | `website` |
| `og:image` | The first image[^img] in the note, if any; otherwise, use the `image` [[yaml-config\|YAML metadata]] |

## Twitter

[Twitter Card](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards) style can be set using `page.twitter.card` [[yaml-config|YAML metadata]]. It it set to `summary_large_image` by default.

[^wl]: Wikilinks like `[[foo]]` render *as is* (due to a limitation). However, `[[foo|some text]]` will render as `some text` (the link text). If you do not wish to have wikilink syntax appearing in page description, specify a custom like in the second example.

[^img]: Unfortunately, embed wikilinks (eg.: `![[foo.jpeg]]`) are not recognized here. You should use regular links, eg.: `![](foo.jpeg)`.
4 changes: 4 additions & 0 deletions docs/guide/yaml-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Notice how this page's sidebar colorscheme has [changed to green]{.greenery}? Vi
>[!tip] Using in HTML templates
> You can reference the YAML frontmatter config from [[html-template]]. See [here](https://github.com/srid/emanote/discussions/131#discussioncomment-1382189) for details.
## Special properties

- `page.image`: The image to use for the page. This is used for the [[ogp]] meta tag `og:image` meta tag. If not specified, the first image in the page is used. Relative URLs are automatically rewritten to absolute URLs if `page.siteUrl` is non-empty.


## Examples

Expand Down
4 changes: 1 addition & 3 deletions docs/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ template:
urlStrategy: pretty

page:
siteUrl: https://emanote.srid.ca
siteTitle: Emanote
headHtml: |
<snippet var="js.highlightjs" />
feed:
siteUrl: https://emanote.srid.ca
1 change: 1 addition & 0 deletions emanote/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Allow specifying `lang` attribute for HTML page in YAML config ([\#485](https://github.com/srid/emanote/pull/485))
- KaTeX support ([\#489](https://github.com/srid/emanote/pull/489))
- Lua filters: filter paths will now be looked up in all layers now.
- **BACKWARDS INCOMPTABILE**: `feed.siteUrl` is now `page.siteUrl`
- Bug fixes:
- Emanote no longer crashes when run on an empty directory ([\#487](https://github.com/srid/emanote/issues/487))
- Stork search fixes
Expand Down
6 changes: 6 additions & 0 deletions emanote/default/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ pandoc:
# Put page-specific metadata here. Override them in Markdown frontmatter or
# per-folder YAML as necessary.
page:
# The URL to the deployed site. Must include everything upto `baseUrl` above.
siteUrl: ""

siteTitle: My Emanote Site
# Desription is expected to be set on a per-page basis.
# By default, the first paragraph is used for description.
Expand All @@ -85,6 +88,9 @@ page:
# Used for https://ogp.me/
image: ""

twitter:
card: summary_large_image

# Put anything that should go in <head> of these routes here:
# You can reference other metadata keys using <snippet var=".." />
# Or use the JS behaviour library below.
Expand Down
3 changes: 3 additions & 0 deletions emanote/default/templates/base.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<meta property="og:image" content="${value:image}" />
<meta property="og:type" content="website" />
<meta property="og:title" content="${ema:title}" />
<with var="twitter">
<meta name="twitter:card" content="${value:card}" />
</with>
</with>
<with var="template">
<base href="${value:baseUrl}" />
Expand Down
2 changes: 1 addition & 1 deletion emanote/emanote.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 2.4
name: emanote
version: 1.3.7.0
version: 1.3.8.0
license: AGPL-3.0-only
copyright: 2022 Sridhar Ratnakumar
maintainer: srid@srid.ca
Expand Down
16 changes: 16 additions & 0 deletions emanote/src/Emanote/Model/SData.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ lookupAeson x (k :| ks) meta =
Aeson.Error _ -> Nothing
Aeson.Success b -> pure b

-- | Modify a key inside the aeson Value
modifyAeson :: NonEmpty KM.Key -> (Maybe Aeson.Value -> Maybe Aeson.Value) -> Aeson.Value -> Aeson.Value
modifyAeson (k :| ks) f meta =
case nonEmpty ks of
Nothing ->
withObject meta $ \obj ->
runIdentity $ KM.alterF (pure . f) k obj
Just ks' ->
withObject meta $ \obj ->
runIdentity $ KM.alterF @Identity (\mv -> Identity $ modifyAeson ks' f <$> mv) k obj
where
withObject :: Aeson.Value -> (Aeson.Object -> Aeson.Object) -> Aeson.Value
withObject v g = case v of
Aeson.Object x -> Aeson.Object $ g x
x -> x

oneAesonText :: [Text] -> Text -> Aeson.Value
oneAesonText k v =
case nonEmpty k of
Expand Down
4 changes: 2 additions & 2 deletions emanote/src/Emanote/View/Feed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ renderFeed model baseNote = case eFeedText of
let feedMeta :: Aeson.Value
feedMeta = getEffectiveRouteMeta (_noteRoute baseNote) model
let mFeedUrl :: Maybe Text
mFeedUrl = lookupAeson Nothing ("feed" :| ["siteUrl"]) feedMeta
feedUrl <- maybeToRight "index.yaml or note doesn't have feed.siteUrl" mFeedUrl
mFeedUrl = lookupAeson Nothing ("page" :| ["siteUrl"]) feedMeta
feedUrl <- maybeToRight "index.yaml or note doesn't have page.siteUrl" mFeedUrl

-- process the notes
let noteUrl note =
Expand Down
18 changes: 17 additions & 1 deletion emanote/src/Emanote/View/Template.hs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,26 @@ loaderHead :: LByteString
loaderHead =
"<em style='font-size: 400%; border-bottom: 1px solid; margin-bottom: 4em; '>Union mounting notebook layers; please wait ...</em>"

patchMeta :: Aeson.Value -> Aeson.Value
patchMeta meta =
-- Convert relative to absolute URLs in "page.image", because some sites
-- (Twitter) require "og:image" to be absolute.
SData.modifyAeson
("page" :| ["image"])
( \case
Just (Aeson.String v)
| not (":" `T.isInfixOf` v) && siteUrl /= "" ->
Just $ Aeson.String $ siteUrl <> "/" <> v
x -> x
)
meta
where
siteUrl = SData.lookupAeson @Text "" ("page" :| ["siteUrl"]) meta

renderLmlHtml :: Model -> MN.Note -> LByteString
renderLmlHtml model note = do
let r = note ^. MN.noteRoute
meta = Meta.getEffectiveRouteMetaWith (note ^. MN.noteMeta) r model
meta = patchMeta $ Meta.getEffectiveRouteMetaWith (note ^. MN.noteMeta) r model
-- Force a doctype into the generated HTML as a workaround for Heist
-- discarding it. See: https://github.com/srid/emanote/issues/216
withDoctype = ("<!DOCTYPE html>\n" <>)
Expand Down

0 comments on commit bf573e7

Please sign in to comment.