Compare commits
No commits in common. "master" and "v1.6.1" have entirely different histories.
15 changed files with 39 additions and 38 deletions
|
@ -35,4 +35,5 @@ title: 00dani.me
|
||||||
app-name: lebd
|
app-name: lebd
|
||||||
username: dani
|
username: dani
|
||||||
repository: https://gitlab.com/00dani/lebd
|
repository: https://gitlab.com/00dani/lebd
|
||||||
|
#analytics: UA-YOURCODE
|
||||||
fb-app-id: "_env:FB_APP_ID:142105433189339"
|
fb-app-id: "_env:FB_APP_ID:142105433189339"
|
||||||
|
|
2
package-lock.json
generated
2
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "lebd",
|
"name": "lebd",
|
||||||
"version": "1.6.4",
|
"version": "1.6.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "lebd",
|
"name": "lebd",
|
||||||
"version": "1.6.4",
|
"version": "1.6.1",
|
||||||
"description": "the codebase backing 00dani.me, an indieweb.org site",
|
"description": "the codebase backing 00dani.me, an indieweb.org site",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: lebd
|
name: lebd
|
||||||
version: "1.6.4"
|
version: "1.6.1"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
||||||
|
|
|
@ -67,9 +67,6 @@ mkYesodData "App" $(parseRoutesFile "config/routes")
|
||||||
-- | A convenient synonym for creating forms.
|
-- | A convenient synonym for creating forms.
|
||||||
type Form x = Html -> MForm (HandlerT App IO) (FormResult x, Widget)
|
type Form x = Html -> MForm (HandlerT App IO) (FormResult x, Widget)
|
||||||
|
|
||||||
sessionLifetime :: Int
|
|
||||||
sessionLifetime = 120 -- minutes
|
|
||||||
|
|
||||||
-- Please see the documentation for the Yesod typeclass. There are a number
|
-- Please see the documentation for the Yesod typeclass. There are a number
|
||||||
-- of settings which can be configured by overriding methods here.
|
-- of settings which can be configured by overriding methods here.
|
||||||
instance Yesod App where
|
instance Yesod App where
|
||||||
|
@ -80,7 +77,7 @@ instance Yesod App where
|
||||||
-- Store session data on the client in encrypted cookies,
|
-- Store session data on the client in encrypted cookies,
|
||||||
-- default session idle timeout is 120 minutes
|
-- default session idle timeout is 120 minutes
|
||||||
makeSessionBackend _ = sslOnlySessions . strictSameSiteSessions $ Just <$> defaultClientSessionBackend
|
makeSessionBackend _ = sslOnlySessions . strictSameSiteSessions $ Just <$> defaultClientSessionBackend
|
||||||
sessionLifetime
|
120 -- timeout in minutes
|
||||||
"config/client_session_key.aes"
|
"config/client_session_key.aes"
|
||||||
|
|
||||||
-- Redirect static requests to a subdomain - this is recommended for best
|
-- Redirect static requests to a subdomain - this is recommended for best
|
||||||
|
@ -100,7 +97,7 @@ instance Yesod App where
|
||||||
-- b) Validates that incoming write requests include that token in either a header or POST parameter.
|
-- b) Validates that incoming write requests include that token in either a header or POST parameter.
|
||||||
-- To add it, chain it together with the defaultMiddleware: yesodMiddleware = defaultYesodMiddleware . defaultCsrfMiddleware
|
-- To add it, chain it together with the defaultMiddleware: yesodMiddleware = defaultYesodMiddleware . defaultCsrfMiddleware
|
||||||
-- For details, see the CSRF documentation in the Yesod.Core.Handler module of the yesod-core package.
|
-- For details, see the CSRF documentation in the Yesod.Core.Handler module of the yesod-core package.
|
||||||
yesodMiddleware = defaultYesodMiddleware . defaultCsrfMiddleware . sslOnlyMiddleware sessionLifetime
|
yesodMiddleware = defaultYesodMiddleware . defaultCsrfMiddleware
|
||||||
|
|
||||||
defaultLayout widget = do
|
defaultLayout widget = do
|
||||||
master <- getYesod
|
master <- getYesod
|
||||||
|
|
|
@ -8,15 +8,12 @@ import Database.Esqueleto
|
||||||
import Widget.Feed ( hFeed )
|
import Widget.Feed ( hFeed )
|
||||||
import Model.Category ( Category, asTag )
|
import Model.Category ( Category, asTag )
|
||||||
|
|
||||||
import qualified Data.Text as T
|
|
||||||
|
|
||||||
getCategoryR :: Category -> Handler Html
|
getCategoryR :: Category -> Handler Html
|
||||||
getCategoryR tag = do
|
getCategoryR tag = do
|
||||||
title <- asks $ siteTitle . appSettings
|
|
||||||
entries <- runDB . select . from $ \(entry `InnerJoin` category) -> do
|
entries <- runDB . select . from $ \(entry `InnerJoin` category) -> do
|
||||||
on $ entry ^. EntryId ==. category ^. EntryCategoryEntryId
|
on $ entry ^. EntryId ==. category ^. EntryCategoryEntryId
|
||||||
where_ $ category ^. EntryCategoryCategory ==. val tag
|
where_ $ category ^. EntryCategoryCategory ==. val tag
|
||||||
return entry
|
return entry
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitle . toHtml . asTag $ tag
|
setTitle . toHtml . asTag $ tag
|
||||||
T.concat [asTag tag, " ~ ", title] `hFeed` entries
|
hFeed entries
|
||||||
|
|
|
@ -20,11 +20,10 @@ getEntriesR :: K.EntryKind -> Handler Html
|
||||||
getEntriesR kind = do
|
getEntriesR kind = do
|
||||||
entries <- runDB $ selectList [EntryKind ==. kind] [Desc EntryPublished]
|
entries <- runDB $ selectList [EntryKind ==. kind] [Desc EntryPublished]
|
||||||
title <- asks $ siteTitle . appSettings
|
title <- asks $ siteTitle . appSettings
|
||||||
let myTitle = T.concat [K.pluralise kind, " ~ ", title]
|
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitle . toHtml . K.pluralise $ kind
|
setTitle . toHtml . K.pluralise $ kind
|
||||||
FeedKindR kind `atomLink` myTitle
|
atomLink (FeedKindR kind) $ T.concat [K.pluralise kind, " ~ ", title]
|
||||||
hFeed myTitle entries
|
hFeed entries
|
||||||
|
|
||||||
getEntryR :: a -> EntryId -> Handler Html
|
getEntryR :: a -> EntryId -> Handler Html
|
||||||
getEntryR _ = renderEntry <=< getCached
|
getEntryR _ = renderEntry <=< getCached
|
||||||
|
|
|
@ -58,8 +58,11 @@ data AppSettings = AppSettings
|
||||||
, appSkipCombining :: Bool
|
, appSkipCombining :: Bool
|
||||||
-- ^ Perform no stylesheet/script combining
|
-- ^ Perform no stylesheet/script combining
|
||||||
|
|
||||||
|
-- Example app-specific configuration values.
|
||||||
|
, appAnalytics :: Maybe Text
|
||||||
|
-- ^ Google Analytics code
|
||||||
, appFacebookId :: Maybe Int
|
, appFacebookId :: Maybe Int
|
||||||
-- ^ Facebook app ID.
|
-- ^ Facebook app ID, also used for analytics.
|
||||||
|
|
||||||
, siteTitle :: Text
|
, siteTitle :: Text
|
||||||
-- ^ Site-wide title.
|
-- ^ Site-wide title.
|
||||||
|
@ -94,6 +97,7 @@ instance FromJSON AppSettings where
|
||||||
appMutableStatic <- o .:? "mutable-static" .!= defaultDev
|
appMutableStatic <- o .:? "mutable-static" .!= defaultDev
|
||||||
appSkipCombining <- o .:? "skip-combining" .!= defaultDev
|
appSkipCombining <- o .:? "skip-combining" .!= defaultDev
|
||||||
|
|
||||||
|
appAnalytics <- o .:? "analytics"
|
||||||
appFacebookId <- o .:? "fb-app-id"
|
appFacebookId <- o .:? "fb-app-id"
|
||||||
siteTitle <- o .: "title"
|
siteTitle <- o .: "title"
|
||||||
siteUsername <- o .: "username"
|
siteUsername <- o .: "username"
|
||||||
|
|
|
@ -4,9 +4,5 @@ module Widget.Feed ( hFeed ) where
|
||||||
import Import
|
import Import
|
||||||
import Widget.Entry ( hEntry )
|
import Widget.Entry ( hEntry )
|
||||||
|
|
||||||
import qualified Data.Text as T
|
hFeed :: [Entity Entry] -> Widget
|
||||||
|
hFeed entries = $(widgetFile "mf2/h-feed")
|
||||||
hFeed :: T.Text -> [Entity Entry] -> Widget
|
|
||||||
hFeed name entries = do
|
|
||||||
mroute <- getCurrentRoute
|
|
||||||
$(widgetFile "mf2/h-feed")
|
|
||||||
|
|
|
@ -25,3 +25,14 @@ $doctype 5
|
||||||
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous">
|
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous">
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous">
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous">
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous">
|
||||||
|
$maybe analytics <- appAnalytics $ appSettings master
|
||||||
|
<script>
|
||||||
|
if(!window.location.href.match(/localhost/)){
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||||
|
|
||||||
|
ga('create', '#{analytics}', 'auto');
|
||||||
|
ga('send', 'pageview');
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<header>
|
<header>
|
||||||
<nav .navbar .navbar-expand-md .navbar-dark.bg-dark>
|
<nav .navbar .navbar-expand-lg .navbar-dark.bg-dark>
|
||||||
<a .navbar-brand rel="home" href=@{HomeR}>#{siteTitle $ appSettings master}
|
<a .navbar-brand rel="home" href=@{HomeR}>#{siteTitle $ appSettings master}
|
||||||
<button type="button" .navbar-toggler data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar" aria-label="Toggle navigation">
|
<button type="button" .navbar-toggler data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar" aria-label="Toggle navigation">
|
||||||
<span .navbar-toggler-icon>
|
<span .navbar-toggler-icon>
|
||||||
|
|
|
@ -2,7 +2,7 @@ body > main
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
align-items: center
|
align-items: center
|
||||||
> div.h-feed
|
> ol.h-feed
|
||||||
flex: 1
|
flex: 1
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
> aside.author
|
> aside.author
|
||||||
|
@ -16,7 +16,7 @@ body > main
|
||||||
body > main
|
body > main
|
||||||
flex-direction: row-reverse
|
flex-direction: row-reverse
|
||||||
align-items: unset
|
align-items: unset
|
||||||
> div.h-feed
|
> ol.h-feed
|
||||||
margin-right: 2em
|
margin-right: 2em
|
||||||
> aside.author
|
> aside.author
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
<aside .author>^{hCard user}
|
<aside .author>^{hCard user}
|
||||||
^{hFeed title entries}
|
^{hFeed entries}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
div.h-feed
|
ol.h-feed
|
||||||
> ol.list-unstyled
|
list-style: none
|
||||||
margin-bottom: 0
|
padding-left: 0
|
||||||
> li:not(:last-child)
|
> li:not(:last-child)
|
||||||
margin-bottom: 1em
|
margin-bottom: 1em
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
<div .h-feed>
|
<ol .h-feed>
|
||||||
<span .p-name hidden>#{name}
|
$forall entry <- entries
|
||||||
$maybe route <- mroute
|
<li>^{hEntry entry}
|
||||||
<a .u-url href=@{route} hidden>
|
|
||||||
<ol .list-unstyled>
|
|
||||||
$forall entry <- entries
|
|
||||||
<li>^{hEntry entry}
|
|
||||||
|
|
Loading…
Reference in a new issue