【问题标题】:Render url with query parameters使用查询参数呈现 url
【发布时间】:2013-10-17 15:39:47
【问题描述】:

找不到简单问题的解决方案,答案应该很明显。如何在 hamlet 模板中使用查询参数呈现 url?

@{ItemsR} 将生成http://localhost:3000/items,我如何生成类似http://localhost:3000/items?page=10&sort=name 的东西?

【问题讨论】:

  • ItemsR 应该有一些参数,试试@{ItemsR 10 "name"}
  • 如果我理解正确,处理程序参数来自路径段。
  • 是的,如果您希望使用“传统参数”,您可以直接在模板上呈现您的网址(例如<a href=@{ItemsR}?page=^{pageNumber}&...)。但是路由更好(类型安全)。
  • 所以没有办法做类似@{ItemsR [("page", "10"), ("sort", "name")]}的事情?

标签: url haskell yesod query-parameters


【解决方案1】:

Yesod 是 RESTful,如果您希望使用 QueryString 格式,则应使用 url 格式的参数(例如 /items/page/10/sortby/name),然后,您将丢失 Yesod 类型的安全 url 管理。

下面的例子展示了如何使用不同的 RESTful 表示和重定向(呈现查询字符串 url)到从查询字符串读取参数的请求

{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiParamTypeClasses #-}
import Yesod
import Data.Text
import Network.Wai.Handler.Warp (run)

data RouteTest = RouteTest

mkYesod "RouteTest" [parseRoutes|
/item/all/page/#Int/sortby/#Text Items1R GET
/items/page/#Int/sortby/#Text Items2R GET
/items/#Int/#Text Items3R GET
/itemsquery ItemsQueryR GET
|]

instance Yesod RouteTest where
    defaultLayout widget = do
        pc <- widgetToPageContent widget
        hamletToRepHtml [hamlet|\<!DOCTYPE html><html lang="en"><body>^{pageBody pc}</body></html>|]

getItemsR :: Text -> Int -> Text -> HandlerT RouteTest IO Html
getItemsR path page sortby =
  defaultLayout [whamlet|
    <h1>Items Page ##{page} sorted by #{sortby}
    <h4>(Using #{path} path format)
    <p>Same request in query string format
      <a href="@{ItemsQueryR}?page=#{page}&sort=#{sortby}">
        here
  |]

getItems1R = getItemsR $ pack "large"
getItems2R = getItemsR $ pack "medium"
getItems3R = getItemsR $ pack "short"

getItemsQueryR = do
  req <- getRequest
  defaultLayout [whamlet|
    <h1>Query String arguments format
    <ul>
      $forall (k, v) <- reqGetParams req
        <li>
          <b>#{k}</b>: #{v}
  |]

main = run 8181 =<< toWaiApp RouteTest

当然,你可以写一个助手来获取一些像你的@{ItemsR page sortby}

renderItemsQueryR page sortby = hamletToRepHtml [hamlet|@{ItemsQueryR}?page=#{page}&sort=#{sortby}|]

但你必须使用 as

...
url <- renderItemsQueryR page sortby
defaultLayout [whamlet|
    ...
    <a href=#{url}>
    ...
|]

最后,您可以编写其他帮助程序来呈现任何查询字符串 url

renderQueryString path keyValues = do
  let querystring = intercalate "&" $ map (\(k, v) -> concat [k, "=", v]) keyValues
  hamletToRepHtml [hamlet|@{path}?#{querystring}|]

那么,renderItemsQueryR 可以写成

renderItemsQueryR page sortby = renderQueryString ItemsQueryR [("page"  , show page)
                                                              ,("sortby", sortby   )]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-11
    • 2018-08-01
    • 2015-01-29
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多