gpt4 book ai didi

haskell - 在 Yesod Handler 中创建带有查询参数的路由

转载 作者:行者123 更新时间:2023-12-02 19:07:46 24 4
gpt4 key购买 nike

我想将分页结果添加到站点地图中。比方说/blog,/blog?page=1, ...

我的路线定义如下所示:

/blog BlogR GET

页面参数是可选的。如何将/blog?page=1 添加到站点地图。站点地图模块需要路线应用程序。所以我只能链接 BlogR 但无法弄清楚如何使用参数创建路由。重定向很容易,只需使用

redirect (BlogR, [("page", 1)])  // /blog?page=1

模板也有插值。但我不知道如何在处理程序内创建路线应用程序

 getPage :: Int -> Route App
getPage number = ???

非常感谢!

最佳答案

据我所知,如果不做大量工作,您就无法真正使用该签名定义 getPage 。假设您使用 mkYesod 生成样板文件,它已经生成了 Route App 数据类型(以及关联的 renderRoutes 函数),并且没有提供提供查询参数。

您最好的选择可能是从使用查询参数切换到更适合 Yesod 的 URL,例如 /blog/page/1。更好的是,不要使用基于页面的系统,而是根据博客文章 ID 号来启动页面,以便 /blog/start/15 显示您的博客以帖子编号 15 开头。如果您走这条路线(双关语),您会自动获得一个永久 URL(因此 /blog/start/15 始终以相同的博客条目开头),并且您可以安排事情,以便您“通常”页面可预测的起始数字以方便缓存等。

但是,如果您确实想欺骗 yesod-sitemap 生成带有查询参数的路由,以下独立示例可能会有所帮助。这里,getSitemapRYesod.Sitemap.sitemapList的重新实现,它使用getUrlRenderParams代替getUrlRender,它允许处理查询参数。

我对管道一无所知,所以我不知道我的 getSitemapR 实现是否特别智能 - 我只是从 yesod-sitemap< 复制和调整代码 直到进行类型检查。

{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Yesod
import Yesod.Sitemap

import Data.Text (Text)

-- stuff needed for getSitemapR
import Text.XML.Stream.Render (renderBuilder)
import Data.Conduit (($=), yield, Flush(..))
import qualified Data.Conduit.List as CL
import Data.Default (def)

data Blog = Blog

mkYesod "Blog" [parseRoutes|
/blog BlogR GET
/sitemap SitemapR GET
|]

instance Yesod Blog

getBlogR :: Handler Html
getBlogR = do
page <- lookup "page" . reqGetParams <$> getRequest
defaultLayout $ case page of
Nothing -> [whamlet|<p>Top of blog|]
Just n -> [whamlet|<p>Page #{n} of blog|]

-- |Sitemap route is app route plus query parameters
data SMRoute = SMRoute (Route Blog) [(Text, Text)]

sitemapRoutes :: [SitemapUrl SMRoute]
sitemapRoutes = map (\u -> SitemapUrl u Nothing Nothing Nothing)
[ SMRoute BlogR []
, SMRoute BlogR [("page", "1")]
, SMRoute BlogR [("page", "2")]
, SMRoute BlogR [("page", "3")]
]

getSitemapR :: Handler TypedContent
getSitemapR = do
let urls = mapM_ yield sitemapRoutes
renderParams <- getUrlRenderParams
let render (SMRoute r qs) = renderParams r qs
respondSource typeXml $ do
yield Flush
urls $= sitemapConduit render $= renderBuilder def $= CL.map Chunk

main :: IO ()
main = warp 3000 Blog

关于haskell - 在 Yesod Handler 中创建带有查询参数的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41208071/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com