Render the p-note as Markdown - this is mostly useful because it means other h-card fields can be defined inside it
This commit is contained in:
parent
012c62dd09
commit
805e422eba
6 changed files with 44 additions and 3 deletions
|
@ -4,7 +4,7 @@ User
|
||||||
fullName Text maxlen=500
|
fullName Text maxlen=500
|
||||||
email Text maxlen=190
|
email Text maxlen=190
|
||||||
avatar Text maxlen=190
|
avatar Text maxlen=190
|
||||||
note Text sqltype=mediumtext
|
note Markdown sqltype=mediumtext
|
||||||
UniqueUser username
|
UniqueUser username
|
||||||
UniqueEmail email
|
UniqueEmail email
|
||||||
deriving Typeable
|
deriving Typeable
|
||||||
|
|
|
@ -52,6 +52,7 @@ dependencies:
|
||||||
- esqueleto >=2.5 && <2.6
|
- esqueleto >=2.5 && <2.6
|
||||||
- friendly-time >=0.4 && <0.5
|
- friendly-time >=0.4 && <0.5
|
||||||
- foreign-store >=0.2 && <0.3
|
- foreign-store >=0.2 && <0.3
|
||||||
|
- markdown >=0.1 && <0.2
|
||||||
- mustache >=2.2 && <2.3
|
- mustache >=2.2 && <2.3
|
||||||
- parsec >=3.1 && <3.2
|
- parsec >=3.1 && <3.2
|
||||||
- slug >=0.1 && <0.2
|
- slug >=0.1 && <0.2
|
||||||
|
|
|
@ -17,6 +17,7 @@ import Text.Mustache ( (~>) )
|
||||||
import qualified Text.Mustache as M
|
import qualified Text.Mustache as M
|
||||||
|
|
||||||
import Model.Entry.Kind ( EntryKind )
|
import Model.Entry.Kind ( EntryKind )
|
||||||
|
import Model.Markdown ( Markdown )
|
||||||
|
|
||||||
-- You can define all of your database entities in the entities file.
|
-- You can define all of your database entities in the entities file.
|
||||||
-- You can find more information on persistent and how to declare entities
|
-- You can find more information on persistent and how to declare entities
|
||||||
|
|
38
src/Model/Markdown.hs
Normal file
38
src/Model/Markdown.hs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
module Model.Markdown ( Markdown(..) ) where
|
||||||
|
|
||||||
|
import Data.Aeson ( FromJSON(..), ToJSON(..), Value(Object), object, (.=), (.:) )
|
||||||
|
import Data.Default ( def )
|
||||||
|
import Database.Persist ( PersistField(..), PersistValue(PersistText) )
|
||||||
|
import Database.Persist.Sql ( PersistFieldSql(..), SqlType(SqlString) )
|
||||||
|
import Data.String ( IsString )
|
||||||
|
import Text.Blaze ( ToMarkup(..) )
|
||||||
|
import Text.Markdown ( markdown )
|
||||||
|
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Text.Lazy as TL
|
||||||
|
|
||||||
|
newtype Markdown = Markdown { unMarkdown :: TL.Text }
|
||||||
|
deriving (Eq, Ord, Monoid, IsString, Show)
|
||||||
|
|
||||||
|
instance ToMarkup Markdown where
|
||||||
|
toMarkup (Markdown t) = markdown def t
|
||||||
|
|
||||||
|
instance PersistField Markdown where
|
||||||
|
toPersistValue (Markdown t) = PersistText $ TL.toStrict t
|
||||||
|
fromPersistValue (PersistText t) = Right . Markdown $ TL.fromStrict t
|
||||||
|
fromPersistValue wrongValue = Left $ T.concat
|
||||||
|
[ "Model.Markdown: When attempting to create Markdown from a PersistValue, received "
|
||||||
|
, T.pack $ show wrongValue
|
||||||
|
, " when a value of type PersistText was expected."
|
||||||
|
]
|
||||||
|
instance PersistFieldSql Markdown where
|
||||||
|
sqlType _ = SqlString
|
||||||
|
|
||||||
|
instance ToJSON Markdown where
|
||||||
|
toJSON (Markdown text) = object ["markdown" .= text]
|
||||||
|
|
||||||
|
instance FromJSON Markdown where
|
||||||
|
parseJSON (Object v) = Markdown <$> v .: "markdown"
|
||||||
|
parseJSON _ = mempty
|
|
@ -9,6 +9,7 @@ import Import
|
||||||
import Database.Esqueleto ( (^.) )
|
import Database.Esqueleto ( (^.) )
|
||||||
import qualified Database.Esqueleto as E
|
import qualified Database.Esqueleto as E
|
||||||
|
|
||||||
|
import Model.Markdown ( unMarkdown )
|
||||||
import Text.Mustache ( substitute )
|
import Text.Mustache ( substitute )
|
||||||
import Util ( compileMustache )
|
import Util ( compileMustache )
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ hCard (Entity userId user) = do
|
||||||
<link rel="author" href=@{HomeR}>
|
<link rel="author" href=@{HomeR}>
|
||||||
<meta property="og:type" content="profile">
|
<meta property="og:type" content="profile">
|
||||||
<meta property="og:title" content="#{userFullName user}">
|
<meta property="og:title" content="#{userFullName user}">
|
||||||
<meta property="og:description" content=#{userNote user}>
|
<meta property="og:description" content=#{unMarkdown $ userNote user}>
|
||||||
<meta property="og:image" content=@{staticR ["img", userAvatar user]}>
|
<meta property="og:image" content=@{staticR ["img", userAvatar user]}>
|
||||||
<meta property="profile:first_name" content=#{firstName}>
|
<meta property="profile:first_name" content=#{firstName}>
|
||||||
<meta property="profile:last_name" content=#{T.unwords lastName}>
|
<meta property="profile:last_name" content=#{T.unwords lastName}>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<a .card-subtitle.u-key type="application/pgp-keys" href=@{routeFromPgp key}>
|
<a .card-subtitle.u-key type="application/pgp-keys" href=@{routeFromPgp key}>
|
||||||
<i .fa.fa-key>
|
<i .fa.fa-key>
|
||||||
#{prettyPgp key}
|
#{prettyPgp key}
|
||||||
<p .card-text.p-note .text-muted>#{userNote user}
|
<div .p-note .text-muted>#{userNote user}
|
||||||
|
|
||||||
<ul .profiles>
|
<ul .profiles>
|
||||||
<li>
|
<li>
|
||||||
|
|
Loading…
Reference in a new issue