{-# LANGUAGE CPP #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Templates.Templates
-- Maintainer  :  bartek@skrivapa.se
-- Stability   :  development
-- Portability :  portable
--
-- This is main templating module. It provides basic interface for
-- generation templates (RenderTemplate) with 'renderTemplate'
-- function. We also provide types for templates and few functions for
-- loading and testing
--
-- HOW TO USE TEMPLATING SYSTEM
--
-- 1) There is a folder called templates, All templates files (*.st) are there. Each files contains many templates
--    definitions, and there must be line starting with # between each two templates.
--    Template definition has form 'nameOfTemplate=bodyOfTemplate'.
--
-- 2) Template body is just String Template and you should be able to find more
--    info at http://www.haskell.org/haskellwiki/HStringTemplate
--
-- 3) All templates are in a global scope. Watch out for conflicting names.
--    On dev computers they are loaded on every request, so one can change them without stoping server.
--
-- 4) To generate a template in haskell call renderTemplate.
--       First param is a set of all templates. Usually you can get it from 'Context'.
--       Next is a name of template that You wan't to render.
--       Last one is some for of list of params.
--       As a result you get IO String.
--        If template will fail You will get error info inside. But this is only for syntax errors.
--        If You will forget a param there will be info in log, and template set param value to something empty.
--
--
-- FIELDS
--
-- Current policy is to use fields. You can find usage of
-- [(String,String)] as params and also composition of setAttribute
-- functions in a code.  This are old concepts and will be droped at
-- some point.
--
-- How to user fields:
--  - there is one function ('field') that sets one field
--  - fields form a monad so you can use do notation for setting many fields
--  - value of a field can be almoust everything (String, Int, Maybe, List, Map, types that are instances of Data and Typeable etc)
--  - IO wrapped values and fields can be also a values of a field.
--
-- Example
--
-- >      userView tempates user =
-- >        renderTemplate templates "userView" $ do
-- >          userFields
-- >
-- >      userFields user = do
-- >        field "name" $ username user
-- >        field "company" $ usercompany user
-- >        field "documents" $ map (documentFields) getUserDocumentsFromDB
-- >
-- >      documentFields document = do
-- >        field "id" $ documentid document
-- >        field "title" $ documenttitle document
--
--
-- Why we want to use fields
--      - They force reuse. We write documentFields, and reuse it every time we want to pass document info to template.
--      - Fields can be extended. If I want to have extended info about user I use 'userFields' to set basic info and
--        then add advanced fields
--      - No need to first bind from IO, then pass to template
--      - They support advanced structures like lists and maybe's
--
--
-- Some extra info:
--  In templates use maybe. You can use 'if' in template body to check for Nothing
--  Always change ByteString to String. We have a problems with encoding, so please watch for this.
--
-- Please also see example.hs for a running example
-----------------------------------------------------------------------------
module Text.StringTemplates.Templates ( Fields
                                      , runFields
                                      , TemplatesMonad(..)
                                      , renderTemplate
                                      , renderTemplate_
                                      , renderTemplateI
                                      , TemplatesT(..)
                                      , runTemplatesT
                                      , renderHelper
                                      ) where

import Text.StringTemplate.Base hiding (ToSElem, toSElem, render)
import Text.StringTemplates.Templates.Class
import Text.StringTemplates.TemplatesLoader

import Text.StringTemplates.Fields
import Control.Monad.Base (MonadBase)
import Control.Monad.Catch
import Control.Monad.Except
import Control.Monad.Reader
import Control.Monad.Identity hiding (liftCatch)
import Control.Monad.Trans.Control ( MonadBaseControl(..)
                                   , MonadTransControl(..)
                                   , ComposeSt
                                   , defaultLiftBaseWith
                                   , defaultRestoreM
                                   , defaultLiftWith
                                   , defaultRestoreT
                                   )

-- | renders a template by name
renderTemplate :: TemplatesMonad m =>
                 String     -- ^ template name
               -> Fields m () -- ^ template params
               -> m String
renderTemplate :: forall (m :: * -> *).
TemplatesMonad m =>
String -> Fields m () -> m String
renderTemplate String
name Fields m ()
fields = do
  Templates
ts <- m Templates
forall (m :: * -> *). TemplatesMonad m => m Templates
getTemplates
  Templates -> String -> Fields m () -> m String
forall (m :: * -> *).
Monad m =>
Templates -> String -> Fields m () -> m String
renderHelper Templates
ts String
name Fields m ()
fields

-- | renders a template by name (params function cannot use side effects)
renderTemplateI :: TemplatesMonad m =>
                  String            -- ^ template name
                -> Fields Identity () -- ^ template params
                -> m String
renderTemplateI :: forall (m :: * -> *).
TemplatesMonad m =>
String -> Fields Identity () -> m String
renderTemplateI String
name Fields Identity ()
fields = do
  Templates
ts <- m Templates
forall (m :: * -> *). TemplatesMonad m => m Templates
getTemplates
  String -> m String
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> m String) -> String -> m String
forall a b. (a -> b) -> a -> b
$ Templates
-> String
-> [(String, String)]
-> (StringTemplate String -> StringTemplate String)
-> String
forall a.
ToSElem a =>
Templates
-> String
-> [(String, a)]
-> (StringTemplate String -> StringTemplate String)
-> String
renderTemplateMain Templates
ts String
name ([]::[(String, String)]) ([(String, SElem String)]
-> StringTemplate String -> StringTemplate String
forall a b.
(ToSElem a, Stringable b) =>
[(String, a)] -> StringTemplate b -> StringTemplate b
setManyAttrib ([(String, SElem String)]
 -> StringTemplate String -> StringTemplate String)
-> [(String, SElem String)]
-> StringTemplate String
-> StringTemplate String
forall a b. (a -> b) -> a -> b
$ Identity [(String, SElem String)] -> [(String, SElem String)]
forall a. Identity a -> a
runIdentity (Identity [(String, SElem String)] -> [(String, SElem String)])
-> Identity [(String, SElem String)] -> [(String, SElem String)]
forall a b. (a -> b) -> a -> b
$ Fields Identity () -> Identity [(String, SElem String)]
forall (m :: * -> *).
Monad m =>
Fields m () -> m [(String, SElem String)]
runFields Fields Identity ()
fields)

-- | renders a template by name without any params
renderTemplate_ :: TemplatesMonad m =>
                  String -- ^ template name
                -> m String
renderTemplate_ :: forall (m :: * -> *). TemplatesMonad m => String -> m String
renderTemplate_ String
name = String -> Fields m () -> m String
forall (m :: * -> *).
TemplatesMonad m =>
String -> Fields m () -> m String
renderTemplate String
name (Fields m () -> m String) -> Fields m () -> m String
forall a b. (a -> b) -> a -> b
$ () -> Fields m ()
forall a. a -> Fields m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

renderHelper :: Monad m => Templates -> String -> Fields m () -> m String
renderHelper :: forall (m :: * -> *).
Monad m =>
Templates -> String -> Fields m () -> m String
renderHelper Templates
ts String
name Fields m ()
fields = do
  [(String, SElem String)]
attrs <- Fields m () -> m [(String, SElem String)]
forall (m :: * -> *).
Monad m =>
Fields m () -> m [(String, SElem String)]
runFields Fields m ()
fields
  String -> m String
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> m String) -> String -> m String
forall a b. (a -> b) -> a -> b
$ Templates
-> String
-> [(String, String)]
-> (StringTemplate String -> StringTemplate String)
-> String
forall a.
ToSElem a =>
Templates
-> String
-> [(String, a)]
-> (StringTemplate String -> StringTemplate String)
-> String
renderTemplateMain Templates
ts String
name ([]::[(String, String)]) ([(String, SElem String)]
-> StringTemplate String -> StringTemplate String
forall a b.
(ToSElem a, Stringable b) =>
[(String, a)] -> StringTemplate b -> StringTemplate b
setManyAttrib [(String, SElem String)]
attrs)

type InnerTemplatesT = ReaderT (String, GlobalTemplates)

-- | Simple implementation of TemplatesMonad
newtype TemplatesT m a = TemplatesT { forall (m :: * -> *) a. TemplatesT m a -> InnerTemplatesT m a
unTT :: InnerTemplatesT m a }
  deriving (Functor (TemplatesT m)
Functor (TemplatesT m) =>
(forall a. a -> TemplatesT m a)
-> (forall a b.
    TemplatesT m (a -> b) -> TemplatesT m a -> TemplatesT m b)
-> (forall a b c.
    (a -> b -> c)
    -> TemplatesT m a -> TemplatesT m b -> TemplatesT m c)
-> (forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m b)
-> (forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m a)
-> Applicative (TemplatesT m)
forall a. a -> TemplatesT m a
forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m a
forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m b
forall a b.
TemplatesT m (a -> b) -> TemplatesT m a -> TemplatesT m b
forall a b c.
(a -> b -> c) -> TemplatesT m a -> TemplatesT m b -> TemplatesT m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (m :: * -> *). Applicative m => Functor (TemplatesT m)
forall (m :: * -> *) a. Applicative m => a -> TemplatesT m a
forall (m :: * -> *) a b.
Applicative m =>
TemplatesT m a -> TemplatesT m b -> TemplatesT m a
forall (m :: * -> *) a b.
Applicative m =>
TemplatesT m a -> TemplatesT m b -> TemplatesT m b
forall (m :: * -> *) a b.
Applicative m =>
TemplatesT m (a -> b) -> TemplatesT m a -> TemplatesT m b
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> TemplatesT m a -> TemplatesT m b -> TemplatesT m c
$cpure :: forall (m :: * -> *) a. Applicative m => a -> TemplatesT m a
pure :: forall a. a -> TemplatesT m a
$c<*> :: forall (m :: * -> *) a b.
Applicative m =>
TemplatesT m (a -> b) -> TemplatesT m a -> TemplatesT m b
<*> :: forall a b.
TemplatesT m (a -> b) -> TemplatesT m a -> TemplatesT m b
$cliftA2 :: forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c) -> TemplatesT m a -> TemplatesT m b -> TemplatesT m c
liftA2 :: forall a b c.
(a -> b -> c) -> TemplatesT m a -> TemplatesT m b -> TemplatesT m c
$c*> :: forall (m :: * -> *) a b.
Applicative m =>
TemplatesT m a -> TemplatesT m b -> TemplatesT m b
*> :: forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m b
$c<* :: forall (m :: * -> *) a b.
Applicative m =>
TemplatesT m a -> TemplatesT m b -> TemplatesT m a
<* :: forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m a
Applicative, (forall a b. (a -> b) -> TemplatesT m a -> TemplatesT m b)
-> (forall a b. a -> TemplatesT m b -> TemplatesT m a)
-> Functor (TemplatesT m)
forall a b. a -> TemplatesT m b -> TemplatesT m a
forall a b. (a -> b) -> TemplatesT m a -> TemplatesT m b
forall (m :: * -> *) a b.
Functor m =>
a -> TemplatesT m b -> TemplatesT m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> TemplatesT m a -> TemplatesT m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> TemplatesT m a -> TemplatesT m b
fmap :: forall a b. (a -> b) -> TemplatesT m a -> TemplatesT m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> TemplatesT m b -> TemplatesT m a
<$ :: forall a b. a -> TemplatesT m b -> TemplatesT m a
Functor, Applicative (TemplatesT m)
Applicative (TemplatesT m) =>
(forall a b.
 TemplatesT m a -> (a -> TemplatesT m b) -> TemplatesT m b)
-> (forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m b)
-> (forall a. a -> TemplatesT m a)
-> Monad (TemplatesT m)
forall a. a -> TemplatesT m a
forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m b
forall a b.
TemplatesT m a -> (a -> TemplatesT m b) -> TemplatesT m b
forall (m :: * -> *). Monad m => Applicative (TemplatesT m)
forall (m :: * -> *) a. Monad m => a -> TemplatesT m a
forall (m :: * -> *) a b.
Monad m =>
TemplatesT m a -> TemplatesT m b -> TemplatesT m b
forall (m :: * -> *) a b.
Monad m =>
TemplatesT m a -> (a -> TemplatesT m b) -> TemplatesT m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
TemplatesT m a -> (a -> TemplatesT m b) -> TemplatesT m b
>>= :: forall a b.
TemplatesT m a -> (a -> TemplatesT m b) -> TemplatesT m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
TemplatesT m a -> TemplatesT m b -> TemplatesT m b
>> :: forall a b. TemplatesT m a -> TemplatesT m b -> TemplatesT m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> TemplatesT m a
return :: forall a. a -> TemplatesT m a
Monad, Monad (TemplatesT m)
Monad (TemplatesT m) =>
(forall a. IO a -> TemplatesT m a) -> MonadIO (TemplatesT m)
forall a. IO a -> TemplatesT m a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
forall (m :: * -> *). MonadIO m => Monad (TemplatesT m)
forall (m :: * -> *) a. MonadIO m => IO a -> TemplatesT m a
$cliftIO :: forall (m :: * -> *) a. MonadIO m => IO a -> TemplatesT m a
liftIO :: forall a. IO a -> TemplatesT m a
MonadIO, (forall (m :: * -> *). Monad m => Monad (TemplatesT m)) =>
(forall (m :: * -> *) a. Monad m => m a -> TemplatesT m a)
-> MonadTrans TemplatesT
forall (m :: * -> *). Monad m => Monad (TemplatesT m)
forall (m :: * -> *) a. Monad m => m a -> TemplatesT m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *). Monad m => Monad (t m)) =>
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
$clift :: forall (m :: * -> *) a. Monad m => m a -> TemplatesT m a
lift :: forall (m :: * -> *) a. Monad m => m a -> TemplatesT m a
MonadTrans, MonadBase b, Monad (TemplatesT m)
Monad (TemplatesT m) =>
(forall e a. (HasCallStack, Exception e) => e -> TemplatesT m a)
-> MonadThrow (TemplatesT m)
forall e a. (HasCallStack, Exception e) => e -> TemplatesT m a
forall (m :: * -> *).
Monad m =>
(forall e a. (HasCallStack, Exception e) => e -> m a)
-> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (TemplatesT m)
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> TemplatesT m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> TemplatesT m a
throwM :: forall e a. (HasCallStack, Exception e) => e -> TemplatesT m a
MonadThrow, MonadThrow (TemplatesT m)
MonadThrow (TemplatesT m) =>
(forall e a.
 (HasCallStack, Exception e) =>
 TemplatesT m a -> (e -> TemplatesT m a) -> TemplatesT m a)
-> MonadCatch (TemplatesT m)
forall e a.
(HasCallStack, Exception e) =>
TemplatesT m a -> (e -> TemplatesT m a) -> TemplatesT m a
forall (m :: * -> *). MonadCatch m => MonadThrow (TemplatesT m)
forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
TemplatesT m a -> (e -> TemplatesT m a) -> TemplatesT m a
forall (m :: * -> *).
MonadThrow m =>
(forall e a.
 (HasCallStack, Exception e) =>
 m a -> (e -> m a) -> m a)
-> MonadCatch m
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
TemplatesT m a -> (e -> TemplatesT m a) -> TemplatesT m a
catch :: forall e a.
(HasCallStack, Exception e) =>
TemplatesT m a -> (e -> TemplatesT m a) -> TemplatesT m a
MonadCatch, MonadCatch (TemplatesT m)
MonadCatch (TemplatesT m) =>
(forall b.
 HasCallStack =>
 ((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
 -> TemplatesT m b)
-> (forall b.
    HasCallStack =>
    ((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
    -> TemplatesT m b)
-> (forall a b c.
    HasCallStack =>
    TemplatesT m a
    -> (a -> ExitCase b -> TemplatesT m c)
    -> (a -> TemplatesT m b)
    -> TemplatesT m (b, c))
-> MonadMask (TemplatesT m)
forall b.
HasCallStack =>
((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
-> TemplatesT m b
forall a b c.
HasCallStack =>
TemplatesT m a
-> (a -> ExitCase b -> TemplatesT m c)
-> (a -> TemplatesT m b)
-> TemplatesT m (b, c)
forall (m :: * -> *). MonadMask m => MonadCatch (TemplatesT m)
forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
-> TemplatesT m b
forall (m :: * -> *) a b c.
(MonadMask m, HasCallStack) =>
TemplatesT m a
-> (a -> ExitCase b -> TemplatesT m c)
-> (a -> TemplatesT m b)
-> TemplatesT m (b, c)
forall (m :: * -> *).
MonadCatch m =>
(forall b. HasCallStack => ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b.
    HasCallStack =>
    ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    HasCallStack =>
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
$cmask :: forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
-> TemplatesT m b
mask :: forall b.
HasCallStack =>
((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
-> TemplatesT m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
-> TemplatesT m b
uninterruptibleMask :: forall b.
HasCallStack =>
((forall a. TemplatesT m a -> TemplatesT m a) -> TemplatesT m b)
-> TemplatesT m b
$cgeneralBracket :: forall (m :: * -> *) a b c.
(MonadMask m, HasCallStack) =>
TemplatesT m a
-> (a -> ExitCase b -> TemplatesT m c)
-> (a -> TemplatesT m b)
-> TemplatesT m (b, c)
generalBracket :: forall a b c.
HasCallStack =>
TemplatesT m a
-> (a -> ExitCase b -> TemplatesT m c)
-> (a -> TemplatesT m b)
-> TemplatesT m (b, c)
MonadMask)

runTemplatesT :: (Functor m, Monad m) =>
                (String, GlobalTemplates) -- ^ (default language name, global templates)
              -> TemplatesT m a -> m a
runTemplatesT :: forall (m :: * -> *) a.
(Functor m, Monad m) =>
(String, GlobalTemplates) -> TemplatesT m a -> m a
runTemplatesT (String, GlobalTemplates)
ts TemplatesT m a
action = ReaderT (String, GlobalTemplates) m a
-> (String, GlobalTemplates) -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (TemplatesT m a -> ReaderT (String, GlobalTemplates) m a
forall (m :: * -> *) a. TemplatesT m a -> InnerTemplatesT m a
unTT TemplatesT m a
action) (String, GlobalTemplates)
ts

instance MonadBaseControl b m => MonadBaseControl b (TemplatesT m) where
#if MIN_VERSION_monad_control(1,0,0)
  type StM (TemplatesT m) a = ComposeSt TemplatesT m a
  liftBaseWith :: forall a. (RunInBase (TemplatesT m) b -> b a) -> TemplatesT m a
liftBaseWith = (RunInBaseDefault TemplatesT m b -> b a) -> TemplatesT m a
(RunInBase (TemplatesT m) b -> b a) -> TemplatesT m a
forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
(MonadTransControl t, MonadBaseControl b m) =>
(RunInBaseDefault t m b -> b a) -> t m a
defaultLiftBaseWith
  restoreM :: forall a. StM (TemplatesT m) a -> TemplatesT m a
restoreM     = ComposeSt TemplatesT m a -> TemplatesT m a
StM (TemplatesT m) a -> TemplatesT m a
forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
(MonadTransControl t, MonadBaseControl b m) =>
ComposeSt t m a -> t m a
defaultRestoreM
#else
  newtype StM (TemplatesT m) a = StM { unStM :: ComposeSt TemplatesT m a }
  liftBaseWith = defaultLiftBaseWith StM
  restoreM     = defaultRestoreM unStM
#endif
  {-# INLINE liftBaseWith #-}
  {-# INLINE restoreM #-}

instance MonadTransControl TemplatesT where
#if MIN_VERSION_monad_control(1,0,0)
  type StT TemplatesT m = StT InnerTemplatesT m
  liftWith :: forall (m :: * -> *) a.
Monad m =>
(Run TemplatesT -> m a) -> TemplatesT m a
liftWith = (forall b. ReaderT (String, GlobalTemplates) m b -> TemplatesT m b)
-> (forall (m :: * -> *) a. TemplatesT m a -> InnerTemplatesT m a)
-> (RunDefault TemplatesT (ReaderT (String, GlobalTemplates))
    -> m a)
-> TemplatesT m a
forall (m :: * -> *) (n :: (* -> *) -> * -> *)
       (t :: (* -> *) -> * -> *) a.
(Monad m, MonadTransControl n) =>
(forall b. n m b -> t m b)
-> (forall (o :: * -> *) b. t o b -> n o b)
-> (RunDefault t n -> m a)
-> t m a
defaultLiftWith InnerTemplatesT m b -> TemplatesT m b
forall b. ReaderT (String, GlobalTemplates) m b -> TemplatesT m b
forall (m :: * -> *) a. InnerTemplatesT m a -> TemplatesT m a
TemplatesT TemplatesT o b -> InnerTemplatesT o b
forall (m :: * -> *) a. TemplatesT m a -> InnerTemplatesT m a
unTT
  restoreT :: forall (m :: * -> *) a.
Monad m =>
m (StT TemplatesT a) -> TemplatesT m a
restoreT = (ReaderT (String, GlobalTemplates) m a -> TemplatesT m a)
-> m (StT (ReaderT (String, GlobalTemplates)) a) -> TemplatesT m a
forall (m :: * -> *) (n :: (* -> *) -> * -> *) a
       (t :: (* -> *) -> * -> *).
(Monad m, MonadTransControl n) =>
(n m a -> t m a) -> m (StT n a) -> t m a
defaultRestoreT ReaderT (String, GlobalTemplates) m a -> TemplatesT m a
forall (m :: * -> *) a. InnerTemplatesT m a -> TemplatesT m a
TemplatesT
#else
  newtype StT TemplatesT m = StT { unStT :: StT InnerTemplatesT m }
  liftWith = defaultLiftWith TemplatesT unTT StT
  restoreT = defaultRestoreT TemplatesT unStT
#endif
  {-# INLINE liftWith #-}
  {-# INLINE restoreT #-}

instance (Applicative m, Monad m) => TemplatesMonad (TemplatesT m) where
  getTemplates :: TemplatesT m Templates
getTemplates = InnerTemplatesT m Templates -> TemplatesT m Templates
forall (m :: * -> *) a. InnerTemplatesT m a -> TemplatesT m a
TemplatesT (InnerTemplatesT m Templates -> TemplatesT m Templates)
-> InnerTemplatesT m Templates -> TemplatesT m Templates
forall a b. (a -> b) -> a -> b
$ do
    (String
lang, GlobalTemplates
ts) <- ReaderT (String, GlobalTemplates) m (String, GlobalTemplates)
forall r (m :: * -> *). MonadReader r m => m r
ask
    Templates -> InnerTemplatesT m Templates
forall a. a -> ReaderT (String, GlobalTemplates) m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Templates -> InnerTemplatesT m Templates)
-> Templates -> InnerTemplatesT m Templates
forall a b. (a -> b) -> a -> b
$ String -> GlobalTemplates -> Templates
localizedVersion String
lang GlobalTemplates
ts
  getTextTemplatesByLanguage :: String -> TemplatesT m Templates
getTextTemplatesByLanguage String
lang = InnerTemplatesT m Templates -> TemplatesT m Templates
forall (m :: * -> *) a. InnerTemplatesT m a -> TemplatesT m a
TemplatesT (InnerTemplatesT m Templates -> TemplatesT m Templates)
-> InnerTemplatesT m Templates -> TemplatesT m Templates
forall a b. (a -> b) -> a -> b
$ do
    (String
_, GlobalTemplates
ts) <- ReaderT (String, GlobalTemplates) m (String, GlobalTemplates)
forall r (m :: * -> *). MonadReader r m => m r
ask
    Templates -> InnerTemplatesT m Templates
forall a. a -> ReaderT (String, GlobalTemplates) m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Templates -> InnerTemplatesT m Templates)
-> Templates -> InnerTemplatesT m Templates
forall a b. (a -> b) -> a -> b
$ String -> GlobalTemplates -> Templates
localizedVersion String
lang GlobalTemplates
ts

instance MonadError e m => MonadError e (TemplatesT m) where
  throwError :: forall a. e -> TemplatesT m a
throwError = m a -> TemplatesT m a
forall (m :: * -> *) a. Monad m => m a -> TemplatesT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> TemplatesT m a) -> (e -> m a) -> e -> TemplatesT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall a. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
  catchError :: forall a. TemplatesT m a -> (e -> TemplatesT m a) -> TemplatesT m a
catchError TemplatesT m a
m e -> TemplatesT m a
h = InnerTemplatesT m a -> TemplatesT m a
forall (m :: * -> *) a. InnerTemplatesT m a -> TemplatesT m a
TemplatesT (InnerTemplatesT m a -> TemplatesT m a)
-> InnerTemplatesT m a -> TemplatesT m a
forall a b. (a -> b) -> a -> b
$ InnerTemplatesT m a
-> (e -> InnerTemplatesT m a) -> InnerTemplatesT m a
forall a.
ReaderT (String, GlobalTemplates) m a
-> (e -> ReaderT (String, GlobalTemplates) m a)
-> ReaderT (String, GlobalTemplates) m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError (TemplatesT m a -> InnerTemplatesT m a
forall (m :: * -> *) a. TemplatesT m a -> InnerTemplatesT m a
unTT TemplatesT m a
m) (TemplatesT m a -> InnerTemplatesT m a
forall (m :: * -> *) a. TemplatesT m a -> InnerTemplatesT m a
unTT (TemplatesT m a -> InnerTemplatesT m a)
-> (e -> TemplatesT m a) -> e -> InnerTemplatesT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> TemplatesT m a
h)