-- | The site's rules: how every source file is compiled, routed, and combined
module MathiasSM.Rules (rules) where

import Control.Monad (when)
import Hakyll (Rules, compile, match, metadataRoute, route)
import MathiasSM.CleanURL (pathRoute)
import MathiasSM.Config (Env (Dev), SiteConfig, projectsGroup, siteEnv, templatePattern)
import MathiasSM.Rules.Assets (processAssets)
import MathiasSM.Rules.Feed (processFeeds)
import MathiasSM.Rules.PostGroup (processPostGroup)
import MathiasSM.Rules.Redirects (processRedirects)
import MathiasSM.Rules.Showcase (processShowcaseGroup)
import MathiasSM.Rules.SinglePages (page, pageCompiler, processPage)
import MathiasSM.Rules.Sitemap (processSitemap)
import MathiasSM.Rules.Static (processStaticFiles)
import MathiasSM.Theme (rewritingTemplateCompiler)
import MathiasSM.Validate (validateNavEntries)
import MathiasSM.Writings (discoverGroups, discoverStandalonePages)
import MathiasSM.Yaml.Website (Website)

-- | Assembles the whole site from the content and configuration
rules :: SiteConfig -> Website -> Rules ()
rules :: SiteConfig -> Website -> Rules ()
rules SiteConfig
cfg Website
website = do
    Pattern -> Rules () -> Rules ()
match (SiteConfig -> Pattern
templatePattern SiteConfig
cfg) (Rules () -> Rules ()) -> Rules () -> Rules ()
forall a b. (a -> b) -> a -> b
$ Compiler (Item Template) -> Rules ()
forall a.
(Binary a, Typeable a, Writable a) =>
Compiler (Item a) -> Rules ()
compile (SiteConfig -> Compiler (Item Template)
rewritingTemplateCompiler SiteConfig
cfg)
    SiteConfig -> Rules ()
validateNavEntries SiteConfig
cfg
    SiteConfig -> Rules ()
processAssets SiteConfig
cfg
    SiteConfig -> Website -> Rules ()
processStaticFiles SiteConfig
cfg Website
website
    standalone <- SiteConfig -> Rules [String]
forall (m :: * -> *). MonadMetadata m => SiteConfig -> m [String]
discoverStandalonePages SiteConfig
cfg
    mapM_ (processPage cfg . page cfg) standalone
    groups <- discoverGroups cfg
    mapM_ (processGroup cfg) groups
    processFeeds cfg website
    processSitemap cfg
    processRedirects cfg
    when (siteEnv cfg == Dev) (processExamplePages cfg)

-- | Processes a group: posts for most groups, projects for the showcase
processGroup :: SiteConfig -> String -> Rules ()
processGroup :: SiteConfig -> String -> Rules ()
processGroup SiteConfig
cfg String
group
    | String
group String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
projectsGroup = SiteConfig -> Rules ()
processShowcaseGroup SiteConfig
cfg
    | Bool
otherwise = SiteConfig -> String -> Rules ()
processPostGroup SiteConfig
cfg String
group

-- | The dev-only preview pages under @dev/example/@, each routed by its own `path:`
processExamplePages :: SiteConfig -> Rules ()
processExamplePages :: SiteConfig -> Rules ()
processExamplePages SiteConfig
cfg = Pattern -> Rules () -> Rules ()
match Pattern
"dev/example/**" (Rules () -> Rules ()) -> Rules () -> Rules ()
forall a b. (a -> b) -> a -> b
$ do
    Routes -> Rules ()
route (Routes -> Rules ()) -> Routes -> Rules ()
forall a b. (a -> b) -> a -> b
$ (Metadata -> Routes) -> Routes
metadataRoute Metadata -> Routes
pathRoute
    Compiler (Item String) -> Rules ()
forall a.
(Binary a, Typeable a, Writable a) =>
Compiler (Item a) -> Rules ()
compile (Compiler (Item String) -> Rules ())
-> Compiler (Item String) -> Rules ()
forall a b. (a -> b) -> a -> b
$ SiteConfig -> Page -> Compiler (Item String)
pageCompiler SiteConfig
cfg (SiteConfig -> String -> Page
page SiteConfig
cfg String
"example")