Splice поддържа ли Unicode?

Това е моят код:

 testSplice :: C.Splice Handler
 testSplice = return $ C.yieldRuntimeText $ do
    return "中文"

И го свързвам с етикет:

  splices :: Splices (C.Splice Handler)
  splices =
      "testSplice" ## testSplice

И го използва на layout.tpl:

   <meta charset="UTF-8"> 
   <testSplice/>

И изходът в браузъра е

    -�

Какво съм направил грешно?


Съжалявам за закъснението, бях зает известно време и сега се връщам и мисля, че може да не направя въпроса достатъчно конкретен @mightybyte Ето кода, където възниква проблемът, надявам се, че ще направи въпроса по-конкретизиращ:

test.hs:

{-# LANGUAGE OverloadedStrings #-}
import Snap
import Heist
import qualified Heist.Compiled as C
import Data.Monoid
import Control.Monad.Trans.Either
import Data.Maybe

main :: IO ()
main = quickHttpServe site

site :: Snap ()
site = 
    route [("/", testSnap)]

testSnap :: Snap ()
testSnap = do
    hs <- liftIO $ load "template" splices
    let runtime = fromJust $ C.renderTemplate hs "test"
    builder <-liftIO  (fst runtime)
    writeBuilder builder
  where
    splices :: Splices (C.Splice IO)
    splices = 
        "testSplice" ## testSplice

load :: MonadIO n
    => FilePath
    -> Splices (C.Splice n)
    -> IO (HeistState n)
load baseDir splices = do
    tmap <- runEitherT $ do
        let t = loadTemplates baseDir
            hc = HeistConfig
                    defaultInterpretedSplices
                    defaultLoadTimeSplices
                    splices
                    mempty
                    [t]
        initHeist hc
    either (error . concat) return tmap

testSplice :: C.Splice IO
testSplice = return $ C.yieldRuntimeText $ do return "中文" 

шаблон/test.tpl

<html>
  <head>
    <meta charset="UTF-8">
  </head>
 <body>
     <testSplice/>
 </body>
 </html>

Сега опитах heist-0.13.0.2 и вече работи добре, страхотна работа Даниел!


person Lynton    schedule 12.10.2013    source източник
comment
Вероятно трябва да предоставите връзка към източника на тази библиотека. Не съм чувал за него и не мога да го намеря чрез hoogle/google.   -  person jtobin    schedule 12.10.2013
comment
Heist поддържа unicode. Вижте отговора ми тук за повече подробности.   -  person mightybyte    schedule 13.10.2013
comment
@mightybyte Но yieldRuntimeText не използва ли fromText, който идва от Blaze.ByteString.Builder.Char8? Съжалявам, ако греша, в такъв случай ще оттегля отговора си.   -  person danidiaz    schedule 13.10.2013
comment
@DanielDíazCarrete Ааа, да. Вие сте абсолютно прав. Не прочетох отговора ви достатъчно внимателно. Публикацията, към която свързах, е правилна, но изобразява низове директно с помощта на snap-core, вместо с помощта на Heist.   -  person mightybyte    schedule 13.10.2013
comment
@mightybyte Моля, вижте актуализирания изходен код, съжаляваме за забавянето.   -  person Lynton    schedule 20.10.2013


Отговори (1)


АКТУАЛИЗАЦИЯ: Проблемът, описан в този отговор, е коригиран във heist версия 0.13.0.2.

изходния код за yieldRuntimeText е:

yieldRuntimeText :: Monad n => RuntimeSplice n Text -> DList (Chunk n)
yieldRuntimeText = yieldRuntime .  liftM fromText

От кой модул идва тази fromText функция? В секцията за импортиране намираме:

import           Blaze.ByteString.Builder
import           Blaze.ByteString.Builder.Char8

документацията за последният пакет казва:

Забележка: Този пакет е предназначен за използване на ниско ниво като прилагане на протоколи. Ако трябва да сериализирате Unicode символи, използвайте едно от UTF кодировките (напр. „Blaze.ByteString.Builder.Char.UTF-8“).

и също:

fromText :: Text -> BuilderSource

O(n). Serialize the lower 8-bits of all characters in the strict text.

Ммммм, така че може би проблемът е, че кодирането от Text to Builder не се извършва в UTF-8? Опитайте да дефинирате своя собствена версия на yieldRuntimeText, с абсолютно същия код, но вместо това използвайте следното импортиране:

import           Blaze.ByteString.Builder
import           Blaze.ByteString.Builder.Char.Utf8

yieldRuntimeTextUtf8 :: Monad n => RuntimeSplice n Text -> DList (Chunk n)
yieldRuntimeTextUtf8 = yieldRuntime .  liftM fromText
person danidiaz    schedule 12.10.2013
comment
Отлична детективска работа. Току-що качих фиксирана версия на hackage като heist-0.13.0.2. Ако надстроите до тази версия, тя трябва да работи, без да дефинирате свой собствен yieldRuntimeTextUtf8. - person mightybyte; 13.10.2013