Skip to content

Commit f2d4758

Browse files
authored
Merge pull request #250 from nomeata/joachim/opengraph
Add opengraph tags to podcast pages
2 parents 461e2db + 7eb91a8 commit f2d4758

File tree

4 files changed

+72
-13
lines changed

4 files changed

+72
-13
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ jobs:
5252
- name: Build site executable
5353
run: stack build --system-ghc
5454

55+
- name: Build site
56+
run: stack exec --system-ghc site rebuild
57+
5558
- name: Deploy
5659
# No deploy from pull requests
5760
if: ${{ github.event_name != 'pull_request' }}
5861
run: |
5962
git config user.name github-actions
6063
git config user.email [email protected]
61-
stack exec --system-ghc site rebuild
6264
git checkout main
6365
git pull --rebase
6466
# Overwrite existing files with new files

haskell-foundation.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ executable site
88
build-depends: base == 4.*
99
, hakyll
1010
, monadlist
11+
, pandoc
12+
, text
1113
ghc-options: -threaded
1214
default-language: Haskell2010

site.hs

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import System.IO (SeekMode(RelativeSeek))
1212
import Hakyll.Web.Html.RelativizeUrls (relativizeUrls)
1313
import Hakyll.Web.Template.Context (defaultContext)
1414
import Data.Maybe (isJust, fromJust, fromMaybe)
15+
import Text.Pandoc as Pandoc
16+
import qualified Data.Text as T
1517

1618
--------------------------------------------------------------------------------------------------------
1719
-- MAIN GENERATION -------------------------------------------------------------------------------------
@@ -176,7 +178,7 @@ main = hakyll $ do
176178
route idRoute
177179
compile $ do
178180
sponsors <- buildBoilerplateCtx (Just "Haskell Interlude")
179-
ctx <- podcastCtx . sortOn podcastOrd <$> loadAll ("podcast/*/index.markdown" .&&. hasVersion "raw")
181+
ctx <- podcastListCtx . sortOn podcastOrd <$> loadAll ("podcast/*/index.markdown" .&&. hasVersion "raw")
180182

181183
makeItem ""
182184
>>= loadAndApplyTemplate "templates/podcast/list.html" ctx
@@ -208,12 +210,18 @@ main = hakyll $ do
208210
match "podcast/*/transcript.markdown" $ compile pandocCompiler
209211
match "podcast/*/links.markdown" $ compile pandocCompiler
210212

213+
-- Description compiler --------------------------------------------------------------------------------
214+
--
215+
-- This identifier compiles the body the file to plain text, to be used in the OpenGraph description field
216+
217+
match "**/*.markdown" $ version "description" $ compile pandocPlainCompiler
218+
211219
-- home page -------------------------------------------------------------------------------------------
212220
create ["index.html"] $ do
213221
route idRoute
214222
compile $ do
215223
sponsors <- buildBoilerplateCtx (Just "Haskell Foundation")
216-
podcastsCtx <- podcastCtx . take 1 . reverse . sortOn podcastOrd <$> loadAll ("podcast/*/index.markdown" .&&. hasVersion "raw")
224+
podcastsCtx <- podcastListCtx . take 1 . reverse . sortOn podcastOrd <$> loadAll ("podcast/*/index.markdown" .&&. hasVersion "raw")
217225
careers <- loadAll @String "careers/*.markdown"
218226
careersCtx <- careersCtx . reverse <$> loadAll "careers/*.markdown"
219227
announces <- take 1 <$> (recentFirst =<< loadAll @String "news/*/**.markdown")
@@ -304,14 +312,18 @@ buildBoilerplateCtx mtitle = boilerPlateCtx mtitle . sortOn itemIdentifier <$> l
304312
-- We set the 'title' based on the title metadata for the item, if present,
305313
-- or use the passed in Maybe title, if it is a Just, or "No title" if not.
306314
boilerPlateCtx :: Maybe String -> [Item String] -> Context String
307-
boilerPlateCtx mtitle sponsors =
308-
listField "monads" defaultContext (ofMetadataField "level" "Monad" sponsors) <>
309-
listField "applicatives" defaultContext (ofMetadataField "level" "Applicative" sponsors) <>
310-
listField "functors" defaultContext (ofMetadataField "level" "Functor" sponsors) <>
311-
field "title" (\item -> do
315+
boilerPlateCtx mtitle sponsors = mconcat
316+
[ listField "monads" defaultContext (ofMetadataField "level" "Monad" sponsors)
317+
, listField "applicatives" defaultContext (ofMetadataField "level" "Applicative" sponsors)
318+
, listField "functors" defaultContext (ofMetadataField "level" "Functor" sponsors)
319+
, field "title" $ \item -> do
312320
metadata <- getMetadata (itemIdentifier item)
313-
return $ fromMaybe (fromMaybe "No title" mtitle) $ lookupString "title" metadata) <>
314-
defaultContext
321+
return $ fromMaybe (fromMaybe "No title" mtitle) $ lookupString "title" metadata
322+
, field "description" $ \item -> do
323+
desc <- loadBody (setVersion (Just "description") (itemIdentifier item))
324+
if null desc then noResult "Description empty" else pure (escapeHtml desc)
325+
, defaultContext
326+
]
315327

316328
-- affiliates ------------------------------------------------------------------------------------------
317329
-- | Partition affiliates into affiliates and pending
@@ -385,8 +397,8 @@ whoWeAreCtx people =
385397
) items'
386398

387399
-- podcast ---------------------------------------------------------------------------------------------
388-
podcastCtx :: [Item String] -> Context String
389-
podcastCtx episodes =
400+
podcastListCtx :: [Item String] -> Context String
401+
podcastListCtx episodes =
390402
listField "episodes" defaultContext (return $ reverse episodes) <>
391403
defaultContext
392404

@@ -439,3 +451,39 @@ sortFromMetadataField field = sortByM (\a b -> do
439451
b' <- getMetadataField (itemIdentifier b) field
440452
return $ compare a' b'
441453
)
454+
455+
--------------------------------------------------------------------------------------------------------
456+
-- Pandoc extensions -----------------------------------------------------------------------------------
457+
--------------------------------------------------------------------------------------------------------
458+
459+
-- | Read a page render using pandoc, rendering its first paragraph as a plain string
460+
--
461+
-- Cargo-culted from pandocCompiler
462+
pandocPlainCompiler :: Compiler (Item String)
463+
pandocPlainCompiler = cached "pandocPlainCompiler" $
464+
getResourceBody >>=
465+
readPandocWith defaultHakyllReaderOptions >>=
466+
pure . fmap firstPara >>=
467+
pure . writePandocPlainWith defaultHakyllWriterOptions
468+
469+
-- | Write a document's first paragraph (as plain text) using pandoc, with the supplied options
470+
--
471+
-- Cargo-culted from hakyll’s writePandocWith
472+
writePandocPlainWith :: Pandoc.WriterOptions -- ^ Writer options for pandoc
473+
-> Item Pandoc.Pandoc -- ^ Document to write
474+
-> Item String -- ^ Resulting HTML
475+
writePandocPlainWith wopt (Item itemi doc) =
476+
case runPure $ writePlain wopt doc of
477+
Left err -> error $ "Hakyll.Web.Pandoc.writePandocWith: " ++ show err
478+
Right item' -> Item itemi $ T.unpack item'
479+
480+
481+
-- | Finds the first regular paragraph of a Pandoc doc
482+
firstPara :: Pandoc.Pandoc -> Pandoc.Pandoc
483+
firstPara (Pandoc.Pandoc meta blocks) = Pandoc.Pandoc meta (go blocks)
484+
where
485+
go :: [Pandoc.Block] -> [Pandoc.Block]
486+
go [] = [] -- I tried to use noResult "firstPara: No plain text found", but it made the build fail
487+
go (block@(Pandoc.Plain _) : _) = [block]
488+
go (block@(Pandoc.Para _) : _) = [block]
489+
go (_ : bs) = go bs

templates/boilerplate.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
<!-- other -->
1414
<meta charset="utf-8">
1515
<meta content="width=device-width, initial-scale=1" data-ssr="" name="viewport">
16-
<title>$title$</title>
1716
<link rel="preconnect" href="https://fonts.gstatic.com">
1817
<link href="https://fonts.googleapis.com/css2?family=Fira+Code&family=Maven+Pro:wght@400;500;700&family=Playfair+Display:wght@400;600;800&display=swap" rel="stylesheet">
1918
<link href="/assets/fontawesome-free-5.15.2-web/css/all.css" rel="stylesheet">
@@ -35,6 +34,14 @@
3534
});
3635
}
3736
</script>
37+
38+
<!-- metadata -->
39+
<title>$title$</title>
40+
<meta property="og:title" content="$title$"></meta>
41+
$if(description)$
42+
<meta property="og:description" content="$description$"></meta>
43+
$endif$
44+
3845
</head>
3946
<body class="relative">
4047

0 commit comments

Comments
 (0)