Haskell 在Yesod处理程序中使用查询参数创建路由

Haskell 在Yesod处理程序中使用查询参数创建路由,haskell,yesod,Haskell,Yesod,我想将分页结果添加到站点地图。比如说/blog,/blog?page=1 我的路线定义如下所示: /blog BlogR GET 页面参数是可选的。如何将/blog?page=1添加到站点地图。站点地图模块需要路由应用程序。因此,我只能链接BlogR,但无法找出如何使用参数创建路由。对于重定向,只需使用 redirect (BlogR, [("page", 1)]) // /blog?page=1 还有模板的插值。但我不知道如何在处理程序中创建路由应用程序 getPage :: Int

我想将分页结果添加到站点地图。比如说/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
函数),没有提供查询参数的规定

您最好的选择可能是从使用查询参数切换到更友好的URL,如
/blog/page/1
。更好的是,不要使用基于页面的系统,而是将URL基于博客帖子ID号来开始页面,这样
/blog/start/15
就可以显示以帖子编号15开始的博客。如果你走这条路线(双关语),你会自动得到一个永久的URL(这样,
/blog/start/15
总是从同一个博客条目开始),你可以安排一些事情,这样你就可以“通常”翻页到可预测的起始编号,以便于缓存等等

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

我对管道一无所知,所以我不知道我的
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}
{-#语言类型族{-}
进口紫草
导入网站地图
导入数据。文本(Text)
--getSitemapR需要的东西
导入Text.XML.Stream.Render(renderBuilder)
导入数据。导管($=)、产量、齐平(…)
导入符合条件的数据.conductor.List作为CL
导入数据。默认值(def)
数据博客=博客
mkYesod“博客”[parseRoutes]|
/博客博客
/站点地图站点映射器获取
|]
实例日志
getBlogR::处理程序Html
getBlogR=do
页面[whamlet |博客顶部|]
只是n->[whamlet |博客|的第#{n}页]
--|站点地图路线是应用程序路线加上查询参数
数据SMRoute=SMRoute(路由博客)[(文本,文本)]
sitemapRoutes::[SitemapUrl SMRoute]
sitemapRoutes=map(\u->SitemapUrl u Nothing)
[SMRoute BlogR[]
,SMRoute BlogR[(“第页”,“第1页”)]
,SMRoute BlogR[(“第页”,“第2页”)]
,SMRoute BlogR[(“第页”,“第3页”)]
]    
getSitemapR::处理程序类型内容
getSitemapR=do
让URL=mapM_u生成sitemapRoutes
您可能感兴趣的渲染参数