如何用snap和heist显示utf8文本?

时间:2013-09-21 10:58:49

标签: haskell haskell-snap-framework heist

我使用了Snap中的writeBS writeText和来自抢劫的renderTemplate,但似乎没有一个支持unicode。

site :: Snap ()
site = do
    ifTop (writeBS "你好世界") <|>
    route [("test", testSnap)]

testSnap :: Snap ()
testSnap = do
     fromJust $ C.renderTemplate hs "test"

-- test.tpl

你好世界

我希望它为//test路由输出“你好世界”,但实际上它的输出只是一些杂乱的代码。

1 个答案:

答案 0 :(得分:0)

这里的问题不在于writeBS或writeText。它与OverloadedStrings扩展使用的转换有关。理解ByteString和Text之间的区别也很重要。 ByteString用于原始字节。没有字符或编码的概念。这就是Text的用武之地。Data.Text.Encoding模块有许多函数可以使用不同的编码在Text和ByteString之间进行转换。对我来说,以下两个都会产生相同的输出:

writeBS $ encodeUtf8 "你好世界"
writeText "你好世界"

您的代码无效的原因是因为您的字符串文字被OverloadedStrings扩展转换为ByteString,并且它没有为您提供所需的行为。解决方案是将其视为正确的类型......文本。

在Heist方面,以下对我来说很好:

route [("test", cRender "test")]

实际上,这个在我的浏览器中正确呈现,而前两个则没有。区别在于cRender设置了适当的内容类型。我发现使用以下代码片段来观察差异是很有启发性的。

site = route [ ("/test1", writeBS "你好世界")
             , ("/test2", writeBS $ encodeUtf8 "你好世界")
             , ("/test3", writeText "你好世界")
             , ("/test4", modifyResponse (setContentType "text/html;charset=utf-8") >> writeText "你好世界")
             , ("/testHeist", cRender "test")
             ]

在我的浏览器test4和testHeist正常工作。测试2和3为您提供了正确的行为,但由于缺少内容类型,浏览器可能无法正确呈现。