snaplet-i18n 0.0.1 → 0.0.2
raw patch · 4 files changed
+51/−47 lines, 4 files
Files
- snaplet-i18n.cabal +2/−3
- src/Snap/Snaplet/I18N.hs +47/−42
- test/snap.hs +1/−1
- test/snaplets/heist/templates/index.tpl +1/−1
snaplet-i18n.cabal view
@@ -3,10 +3,10 @@ -- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr. -- The name of the package. Name: snaplet-i18n-Version: 0.0.1+Version: 0.0.2 Description: A light weight i18n snaplet. Synopsis: snaplet-i18n-Homepage: freizl.github.com+Homepage: https://github.com/HaskellCNOrg/snaplet-i18n License: BSD3 License-file: LICENSE Author: Haisheng,Wu@@ -16,7 +16,6 @@ Build-type: Simple Stability: Experience Cabal-version: >=1.6- Extra-source-files: README.md
src/Snap/Snaplet/I18N.hs view
@@ -2,7 +2,14 @@ {-# LANGUAGE DeriveDataTypeable #-} -module Snap.Snaplet.I18N where+module Snap.Snaplet.I18N + ( I18NSnaplet+ , HasI18N (..)+ , I18NMessage (..)+ , initI18NSnaplet+ , getI18NMessages+ , lookupI18NValue+ ) where import Control.Monad import Data.Lens.Common@@ -18,11 +25,8 @@ import Snap import Snap.Snaplet.Heist----------------------------------------------------------- ------ --- ++ ------------------------------------------------------- type Locale = String@@ -31,6 +35,8 @@ defaultLocale :: Locale defaultLocale = "en_US" +-- | ?? could be multiple message files+-- defaultMessageFilePrefix :: MessageFile defaultMessageFilePrefix = "data/message" @@ -57,34 +63,35 @@ -- | Util functions -- -i18nLens' :: HasI18N b => Lens (Snaplet b) (Snaplet I18NSnaplet)-i18nLens' = subSnaplet i18nLens- getI18NSnaplet :: HasI18N b => Handler b b I18NSnaplet getI18NSnaplet = with i18nLens Snap.get +-- | Get the @I18NMessage@+-- getI18NMessages :: HasI18N b => Handler b b I18NMessage getI18NMessages = liftM _getI18NMessage getI18NSnaplet ------------------------------------------------------------ | Default I18N snaplet+-- | Look up a value in, usuallly Handler Monad -- -defaultI18NSnaplet :: (HasHeist b, HasI18N b) => SnapletInit b I18NSnaplet-defaultI18NSnaplet = initI18NSnaplet Nothing Nothing+lookupI18NValue :: HasI18N b => T.Text -> Handler b b T.Text+lookupI18NValue key = do+ (I18NMessage msg) <- getI18NMessages+ liftIO $ Config.lookupDefault "Error: no value found." msg key +-------------------------------------------------------+ -- | Init this I18NSnaplet snaplet. -- initI18NSnaplet :: (HasHeist b, HasI18N b) => Maybe Locale -- ^ Locale, default to @defaultLocale@- -> Maybe MessageFile -- ^ Message file prefix, default to @defaultMessageFilePrefix@ -> SnapletInit b I18NSnaplet-initI18NSnaplet l m = makeSnaplet "I18NSnaplet" "" Nothing $ do- i18nConfig <- return $ I18NConfig (fromMaybe defaultLocale l) (fromMaybe defaultMessageFilePrefix m)+initI18NSnaplet l = makeSnaplet "I18NSnaplet" "" Nothing $ do+ let i18nConfig = I18NConfig (fromMaybe defaultLocale l) defaultMessageFilePrefix config <- liftIO $ readMessageFile i18nConfig- defaultSplices+ addDefaultSplices return $ I18NSnaplet i18nConfig $ I18NMessage config- where defaultSplices = addSplices [(i18nSpliceName, liftHeist i18nSplice)]+ where addDefaultSplices = addSplices [ ("i18n", liftHeist i18nSplice)+ , ("i18nSpan", liftHeist i18nSpanSplice)] ------------------------------------------------------- -- @@ -96,26 +103,32 @@ readMessageFile :: I18NConfig -> IO Config.Config readMessageFile config = do base <- getCurrentDirectory- fullname <- return $ base </> (file config)+ let fullname = base </> file config Config.load [Config.Required fullname] where -- file fullname will be like message-en_US.cfg+ -- FIXME: Maybe replace "-" with "_" in locale for typo file c = _getMessageFile c ++ "-" ++ _getLocale c ++ ".cfg" ------------------------------------------------------- --- | Splice name used in Heist template.--- e.g. <i18n name="hello" />--- -i18nSpliceName :: T.Text-i18nSpliceName = "i18n"+-- | Splices just wrap value fonud at l10n message.+--+-- FIXME: Turns out that it is not possible to fail at compilation if value is Nothing but runtime. +i18nSplice :: HasI18N b => Splice (Handler b b)+i18nSplice = do+ input <- getParamNode+ value <- lift . lookupI18NValue $ getNameAttr input+ return [X.TextNode value] --- | Output as `span` HTML element for i18n message.--- e.g. <span>Shanghai</span>+-- | Splices. use 'span' html element wrap result. -- -i18nSpliceElement :: T.Text-i18nSpliceElement = "span"+i18nSpanSplice :: HasI18N b => Splice (Handler b b)+i18nSpanSplice = do+ input <- getParamNode+ value <- lift . lookupI18NValue $ getNameAttr input+ return [X.Element "span" (elementAttrs input) [X.TextNode value]] -- | element attribute used for looking up i18n value. -- e.g. <i18n name="hello" />@@ -123,17 +136,9 @@ i18nSpliceAttr :: T.Text i18nSpliceAttr = "name" --- | Splices+-- | Look up 'name' attribute value. -- -i18nSplice :: HasI18N b => Splice (Handler b b)-i18nSplice = do- input <- getParamNode- (I18NMessage messages) <- lift getI18NMessages- value <- liftIO $ getValue messages input- -- FIXME: Turns out that it is not possible to fail at compilation if value is Nothing but runtime.- return [X.Element i18nSpliceElement [] [X.TextNode $ T.pack value]]- where getValue :: Config.Config -> Node -> IO String- getValue m i = Config.lookupDefault "Error: no value found." m (getAttr' i)- getAttr' i = case getAttribute i18nSpliceAttr i of- Just x -> x- _ -> ""+getNameAttr :: Node -> T.Text+getNameAttr n = case getAttribute i18nSpliceAttr n of+ Just x -> x+ _ -> ""
test/snap.hs view
@@ -91,7 +91,7 @@ app = makeSnaplet "app" "An snaplet example application." Nothing $ do h <- nestSnaplet "heist" heist $ heistInit "templates" locale <- liftIO $ getDefaultLocale- i <- nestSnaplet "i18n" i18n $ initI18NSnaplet locale Nothing+ i <- nestSnaplet "i18n" i18n $ initI18NSnaplet (Just "zh_CN") addRoutes routes return $ App h i
test/snaplets/heist/templates/index.tpl view
@@ -16,7 +16,7 @@ <p> <i18n name="shanghai"></i18n>-<i18n name="hello"></i18n>+<i18nSpan name="hello" class="test"></i18nSpan> <i18n name="invalidekey"></i18n> </p>