1

我如何将莎士比亚(来自 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
                 .........
                 |]

但我得到错误!

4

3 回答 3

2

这是一个对我有用的小完整示例:

{-# 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
  |]
于 2016-04-12T12:46:17.173 回答
1

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

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}
|]
于 2016-04-12T12:36:31.133 回答
1

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

<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>
于 2016-04-12T12:56:57.760 回答