Snap:编译的拼接代码示例

时间:2013-10-23 11:01:03

标签: haskell haskell-snap-framework heist

我想我前段时间确实问了一个类似的问题,但由于API不稳定而没有回答。所以我在等待0.13经过。我不确定提出类似问题是否正确......?

在编译的拼接世界中,解释runChildrenWith(Text)mapSplices的替代方法是什么? (这种组合似乎是最常见的) 如果可能的话,我会非常感谢一些代码示例。

如果我理解正确,我们将所有应用程序拼接汇集在一起​​,然后将它们添加到heistInit。有人能说明怎么做吗?

splice绑定标记在整个应用程序中是否必须是唯一的?

是否有完整的快照项目utilising新API和已编译的拼接,以便我可以阅读并查看学习内容?

谢谢。

- 更新 -

下面的答案很棒。但不幸的是,有些部分(带镜头的部分)让我更加困惑。 如果我理解正确,这是拼接字符串的简单方法:

mySplice = "testSplice" ## testSplice
  where testSplice = return $ C.yieldRuntimeText $ do
          return "text to be spliced"

如果我需要多次运行拼接字符串,比如在5个表格中,我会这样做:

mySplices = C.manyWithSplices C.runChildren mySplice

这是对的吗?

我在试图在heist配置中添加拼接时遇到了大量错误。

addConfig h $ mempty
 {
   hcCompiledSplices = "mySplice" ## mySplice -- or mySplices
 }

我哪里错了?对不起,慢了。

我真正需要的(只是现在这样我才明白)是拼接并显示我从数据库收到的简单字符串。

- 更新2 -

感谢极端有用的丹尼尔的回答,我终于可以得到一些工作。

到目前为止,我得到了两种代码变体。

第一个,感谢Daniel

stringSplice :: Monad n => C.Splice n
stringSplice = C.manyWithSplices C.runChildren splicefuncs (return ["aa","bb","cc"])
  where
    splicefuncs = "string" ## (C.pureSplice . C.textSplice $ id)

和secod

testSplice :: C.Splice (Handler App App)
testSplice = return $ C.yieldRuntimeText $ return "text to be spliced"

其中

(C.pureSplice . C.textSplice $ id)

产生类似的结果

return $ C.yieldRuntimeText $ return "text to be spliced"

以上是否有区别?任何人都喜欢彼此的情况?它们似乎产生了相同的结果。

在编译的拼接库中有一个“deferMany”函数,根据文档,它在解释的lib中产生与mapSplices类似的结果。 我们可以用它代替“C.manyWithSplices C.runChildren”组合吗?

1 个答案:

答案 0 :(得分:6)

假设您要显示有关使用编译拼接的人员列表的信息(假设我们从snap init生成的脚手架开始。)

带有虚拟值的非常简单的_persons.tpl模板类似于

<body>
    <person>
        <div>
            <h1><name>dummy name</name></h1>
            <p><age>77</age></p> 
            <p><location>jauja</location></p> 
        </div>
    </person>
</body>

personnameagelocation是要拼接的标记。

我们定义一个包含信息的简单Snaplet

data Foo = Foo
    {
        _persons :: [Person]
    }

makeLenses ''Foo

data Person = Person
    {
        _name :: Text
    ,   _age :: Int
    ,   _location :: Text
    }   

makeLenses ''Person

我们将其添加到App记录中:

data App = App
    { _heist :: Snaplet (Heist App)
    , _sess :: Snaplet SessionManager
    , _auth :: Snaplet (AuthManager App)
    , _foo :: Snaplet Foo
    }

我们将以下内容添加到应用初始值设定项

f <- nestSnaplet "foo" foo $ makeSnaplet "foo" "Foo Snaplet" Nothing $ return $ Foo $ 
        [ Person "Ricardo" 33 "Los Cantones" 
        , Person "Luis" 38 "Montealto" 
        ]

...

return $ App h s a f

此函数构造一个Handler,返回人员列表(使用view中的Control.Lens):

personH :: SnapletLens b Foo -> Handler b b [Person] 
personH l = withTop l $ view persons <$> get 

此函数从RuntimeSplice构造适当的编译剪接,生成人员列表。 RuntimeSplice代表只能在运行时知道的信息,而不是加载时间:

personSplice :: Monad n => RuntimeSplice n [Person] -> C.Splice n
personSplice = C.manyWithSplices C.runChildren splicefuncs 
    where
    splicefuncs = mconcat  
        [ "name" ## (C.pureSplice . C.textSplice $ view name)
        , "age" ## (C.pureSplice . C.textSplice $ T.pack . show . view age)
        , "location" ## (C.pureSplice . C.textSplice $ view location)
        ]

此功能可用于在全局Heist配置中注册拼接。请注意,我们将Handler提升为RuntimeSplice

addPersonSplices :: HasHeist b => Snaplet (Heist b) -> 
                                  SnapletLens b Foo -> 
                                  Initializer b v ()
addPersonSplices h l = addConfig h $ mempty 
   {
      hcCompiledSplices = "person" ## (personSplice . lift $ personH l) 
   } 

请务必将此行添加到应用初始值设定项:

addPersonSplices h foo

并将以下对添加到应用程序的路线:

("/persons",  cRender "_persons")

如果您现在运行服务器,导航到http://127.0.0.1:8000/persons应显示列表。

<强>更新

对于您只想显示字符串列表的更简单的情况(没有复杂的记录,没有镜头)。

模板可能类似于:

<body>
    <strings>
        <p><string>dummy value</string></p>
    </strings>
</body>

顶级拼接将是:

stringSplice :: Monad n => C.Splice n
stringSplice = C.manyWithSplices C.runChildren splicefuncs (return ["aa","bb","cc"])
    where
    splicefuncs = "string" ## (C.pureSplice . C.textSplice $ id)

这意味着“当我们遇到与此拼接关联的标记时,执行生成字符串列表的操作,并为每个字符串渲染标记的内容,将当前字符串替换为string标记”

请注意manyWithSplices的签名强制(##)右侧的内容具有类型RuntimeSplice n Text -> Splice n。此处id的类型为Text -> TextC.TextSplice会将其转换为Text -> Builder类型的内容,而C.pureSplice会将最终转换为RuntimeSplice n Text -> Splice n

代替(return ["aa","bb","cc"]),您可以提供更复杂的操作,连接数据库并从中提取字符串。

注册此拼接的功能是:

addStringSplices :: HasHeist b => Snaplet (Heist b) -> Initializer b v ()
addStringSplices h = addConfig h $ mempty 
    {
          hcCompiledSplices = "strings" ## stringSplice
    }