【问题标题】:Using Servant with Yesod shakespeare (Hamlet, Julius, Lucius)将仆人与 Yesod 莎士比亚一起使用(哈姆雷特、朱利叶斯、卢修斯)
【发布时间】:2016-08-02 17:22:41
【问题描述】:

我如何将莎士比亚(来自 yesod)用于服务 Web 服务 API?

我试试:

type TestAPI 
    = "tests" :> Get '[JSON] [Test]
    :<|> "Test.html" :> Get '[HTML] Html

serverTestAPI :: ServerT TestAPI AppM
serverTestAPI = tests 
           :<|> test
           :<|> testHtml

tests :: AppM [Test]
tests = do return [ Test 1 "Test 1"
                  , Test 2 "Test 2"
                  ]

testHtml = [hamlet|
                $doctype 5
                 .........
                 |]

但我得到了错误!

【问题讨论】:

  • 显示哪个错误?
  • 查看shakespeare 的文档,看起来hamlet QQ 产生了HtmlUrl 类型的东西,但shamlet 产生了Html 类型的东西。使用shamlet 代替hamlet 有效吗?
  • 显示错误:无法将类型 't0 -> 标记'与 'transformers-0.4.2.0:Control.Monad.Trans.Reader.ReaderT Config (Control.Monad.Trans.Either. EitherT ServantErr IO) (blaze-markup-0.7.0.3:Text.Blaze.Internal.MarkupM ())' 预期类型:ServerT TestAPI AppM 实际类型:AppM [Test] : (AppM Test : (t0 -> Markup)) 在表达式中:tests : test : testHtml 在 'serverTestAPI' 的等式中: serverTestAPI = tests : test : testHtml
  • 小村庄和小村庄不起作用!
  • 我建议将签名添加到testHtml(可能是testHtml :: HTML) - 然后你的错误应该指向你的小村庄部分

标签: haskell yesod servant


【解决方案1】:

这是一个适合我的完整小例子:

{-# LANGUAGE DataKinds, PolyKinds, TypeOperators, DeriveGeneric #-}
{-# LANGUAGE QuasiQuotes #-}
module Main where

import Data.Aeson
import Data.Proxy
import GHC.Generics
import Network.Wai.Handler.Warp
import Servant.API
import Servant.HTML.Blaze
import Servant.Server
import Text.Blaze.Html
import Text.Hamlet

data Test = Test Int String
  deriving (Generic)

instance ToJSON Test

type TestAPI 
    =    "tests" :> Get '[JSON] [Test]
    :<|> "Test.html" :> Get '[HTML] Html

main :: IO ()
main = run 8080 (serve (Proxy :: Proxy TestAPI) serverTestAPI)

serverTestAPI :: Server TestAPI
serverTestAPI = tests :<|> testHtml

tests = return [ Test 1 "Test 1"
               , Test 2 "Test 2"
               ]

testHtml = return [shamlet|
  $doctype 5
  <html>
     <head>
       <title>This is a title
     <body>
       <p>This is text
  |]

【讨论】:

    【解决方案2】:

    正如@Carsten 指出的那样,在这种情况下,您想要的是shamlet。关键是实现ToMarkup 类型类的正确实例。我建议您阅读有关莎士比亚模板的excellent introduction。一个工作示例:

    data Person = Person
      { firstName :: String
      , lastName  :: String
      } deriving Generic 
    
    instance ToJSON Person
    
    type PersonAPI = "persons" :> Get '[JSON, HTML] [Person]
    
    people :: [Person]
    people =
      [ Person "Isaac"  "Newton"
      , Person "Albert" "Einstein"
      ]
    
    instance ToMarkup Person where
      toMarkup person = showPerson person
    
      -- this isn't properly implemented
      preEscapedToMarkup p = showPerson p
    
    -- HTML serialization of a list of persons
    instance ToMarkup [Person] where
      toMarkup persons = showPersons persons
    
      preEscapedToMarkup p = showPersons p
    
    showPerson :: Person -> Html
    showPerson p = [shamlet|
    <body>
        <p>This is my page.
        <h1>#{firstName p}
    |]
    
    showPersons :: [Person] -> Html
    showPersons p = [shamlet|
    <body>
        <p>This is my page.
         $forall person <- p
          <h1>#{firstName person}
    |]
    

    【讨论】:

      【解决方案3】:

      感谢大家的帮助!
      实现如下:

      <code>type TestAPI 
          = "tests" :> Get '[JSON] [Test]
          :<|> "test" :> Get '[JSON] Test
          :<|> "TestHTML.html" :> Get '[HTML] Page_TestHTML 
      
      serverTestAPI :: ServerT TestAPI AppM
      serverTestAPI = tests 
                 :<|> test
                 :<|> testHtml
      
      data Page_TestHTML = Page_TestHTML
      
      instance ToMarkup Page_TestHTML where
          toMarkup Page_TestHTML = builderHtml  
      
      testHtml = return Page_TestHTML
      
      builderHtml = [shamlet|
                      $doctype 5
                      <html>
                          <head>
                              <title>Greeting2
                      <body>
                          <h2> Hello world HTML Qqqqq |]</code>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-12
        • 1970-01-01
        • 1970-01-01
        • 2016-06-20
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        相关资源
        最近更新 更多