RootR FooR |] getFooR :: Handler Html getFooR = getRootR main :: IO () main = warp 3000 Slash ``` 首先我们看`joinPath`的实现。这几乎是从默认的Yesod实现中复制的,只有一点不同,我们在最后加了一个空字符串。处理路径片段时空字符串将转义为一个斜杠。 ## defaultLayout 大多数网站都喜欢把一个通用模板应用到他们的所有页面。`defaultLayout`就是做这个的。虽然您可以轻松的定义自己的函数并调用它。但是当你重写`defaultLayout`的时候所用Yesod生成的页面(错误页面,认证页面)会自动应用这个样式。 覆盖是非常简单的:我们使用widgetToPageContent将Widget转换为标题,head标签和body标签,然后使用withUrlRenderer将Hamlet模板转换为Html值。我们甚至可以在defaultLayout中添加额外的小部件组件,如Lucius模板。有关更多信息,请参阅有关小部件的上一章。 如果你是用的是模板项目,你可以修改`templates/default-layout.hamlet` 和`templates/default-layout-wrapper.hamlet`前者包含``标记的大部分内容,而后者包含HTML的其余部分,例如doctype和``标记。有关详细信息,请参阅这些文件 ## getMessage 尽管我们还没有讲到Session,但是我还是想在这里提一下`getMessage`,Web开发中的一种常见模式是在一个处理程序中设置消息并在另一个处理程序中显示它。例如,当用户`POST`了一个表单的时候,你可能想将他重定向到另一个"显示表格提交完成"显示页面。为了实现这一点,Yesod内置了一对函数:`setMessage`在Session中设置一些消息,`getMessage`获取这个消息(并清除它,所以他不会再次出现了)。建议您将getMessage的结果放入defaultLayout。 ```Haskell {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Yesod import Data.Time (getCurrentTime) data App = App mkYesod "App" [parseRoutes| / HomeR GET |] instance Yesod App where defaultLayout contents = do PageContent title headTags bodyTags <- widgetToPageContent contents mmsg <- getMessage withUrlRenderer [hamlet| $doctype 5 #{title} ^{headTags} $maybe msg <- mmsg #{msg} ^{bodyTags} |] getHomeR :: Handler Html getHomeR = do now <- liftIO getCurrentTime setMessage $ toHtml $ "You previously visited at: " ++ show now defaultLayout [whamlet|Try refreshing|] main :: IO () main = warp 3000 App ``` 在讨论Session时,我们将更详细地介绍getMessage / setMessage。 ## 自定义错误页面 专业网站的标志之一是设计合理的错误页面。Yesod通过默认的defaultLayout显示错误页面。但有时候,你会想自定义它。为此,您只需要覆盖errorHandler方法: ```Haskell {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Yesod data App = App mkYesod "App" [parseRoutes| / HomeR GET /error ErrorR GET /not-found NotFoundR GET |] instance Yesod App where errorHandler NotFound = fmap toTypedContent $ defaultLayout $ do setTitle "Request page not located" toWidget [hamlet| Not Found We apologize for the inconvenience, but the requested page could not be located. |] errorHandler other = defaultErrorHandler other getHomeR :: Handler Html getHomeR = defaultLayout [whamlet| Internal server error Not found |] getErrorR :: Handler () getErrorR = error "This is an error" getNotFoundR :: Handler () getNotFoundR = notFound main :: IO () main = warp 3000 App ``` 我们自定义了一个404页面。当我们不想为每种错误类型编写自定义处理程序时,我们可以使用`defaultErrorHandler`。由于类型限制我们需要去前面加上`fmap toTypedContent`。(我们将在下一章中详细了解TypedContent。)事实上,您甚至可以使用重定向等特殊响应: ```Haskell errorHandler NotFound = redirect HomeR errorHandler other = defaultErrorHandler other ``` > 即使你可以做到这一点,我实际上并没有推荐这样的做法。 404应该是404。 ## 外部CSS和Javascript > 此处描述的功能自动包含在scaffolded站点中,因此您无需担心自己实现此功能。 Yesod类型类中最强大的方法之一是addStaticContent。Widget由多个组件组成,包括CSS和Javascript。CSS / JS到底是如何到达用户的浏览器的?默认情况下,它们分别在页面的``,`
FooR |] getFooR :: Handler Html getFooR = getRootR main :: IO () main = warp 3000 Slash ``` 首先我们看`joinPath`的实现。这几乎是从默认的Yesod实现中复制的,只有一点不同,我们在最后加了一个空字符串。处理路径片段时空字符串将转义为一个斜杠。 ## defaultLayout 大多数网站都喜欢把一个通用模板应用到他们的所有页面。`defaultLayout`就是做这个的。虽然您可以轻松的定义自己的函数并调用它。但是当你重写`defaultLayout`的时候所用Yesod生成的页面(错误页面,认证页面)会自动应用这个样式。 覆盖是非常简单的:我们使用widgetToPageContent将Widget转换为标题,head标签和body标签,然后使用withUrlRenderer将Hamlet模板转换为Html值。我们甚至可以在defaultLayout中添加额外的小部件组件,如Lucius模板。有关更多信息,请参阅有关小部件的上一章。 如果你是用的是模板项目,你可以修改`templates/default-layout.hamlet` 和`templates/default-layout-wrapper.hamlet`前者包含``标记的大部分内容,而后者包含HTML的其余部分,例如doctype和``标记。有关详细信息,请参阅这些文件 ## getMessage 尽管我们还没有讲到Session,但是我还是想在这里提一下`getMessage`,Web开发中的一种常见模式是在一个处理程序中设置消息并在另一个处理程序中显示它。例如,当用户`POST`了一个表单的时候,你可能想将他重定向到另一个"显示表格提交完成"显示页面。为了实现这一点,Yesod内置了一对函数:`setMessage`在Session中设置一些消息,`getMessage`获取这个消息(并清除它,所以他不会再次出现了)。建议您将getMessage的结果放入defaultLayout。 ```Haskell {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Yesod import Data.Time (getCurrentTime) data App = App mkYesod "App" [parseRoutes| / HomeR GET |] instance Yesod App where defaultLayout contents = do PageContent title headTags bodyTags <- widgetToPageContent contents mmsg <- getMessage withUrlRenderer [hamlet| $doctype 5 #{title} ^{headTags} $maybe msg <- mmsg #{msg} ^{bodyTags} |] getHomeR :: Handler Html getHomeR = do now <- liftIO getCurrentTime setMessage $ toHtml $ "You previously visited at: " ++ show now defaultLayout [whamlet|Try refreshing|] main :: IO () main = warp 3000 App ``` 在讨论Session时,我们将更详细地介绍getMessage / setMessage。 ## 自定义错误页面 专业网站的标志之一是设计合理的错误页面。Yesod通过默认的defaultLayout显示错误页面。但有时候,你会想自定义它。为此,您只需要覆盖errorHandler方法: ```Haskell {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Yesod data App = App mkYesod "App" [parseRoutes| / HomeR GET /error ErrorR GET /not-found NotFoundR GET |] instance Yesod App where errorHandler NotFound = fmap toTypedContent $ defaultLayout $ do setTitle "Request page not located" toWidget [hamlet| Not Found We apologize for the inconvenience, but the requested page could not be located. |] errorHandler other = defaultErrorHandler other getHomeR :: Handler Html getHomeR = defaultLayout [whamlet| Internal server error Not found |] getErrorR :: Handler () getErrorR = error "This is an error" getNotFoundR :: Handler () getNotFoundR = notFound main :: IO () main = warp 3000 App ``` 我们自定义了一个404页面。当我们不想为每种错误类型编写自定义处理程序时,我们可以使用`defaultErrorHandler`。由于类型限制我们需要去前面加上`fmap toTypedContent`。(我们将在下一章中详细了解TypedContent。)事实上,您甚至可以使用重定向等特殊响应: ```Haskell errorHandler NotFound = redirect HomeR errorHandler other = defaultErrorHandler other ``` > 即使你可以做到这一点,我实际上并没有推荐这样的做法。 404应该是404。 ## 外部CSS和Javascript > 此处描述的功能自动包含在scaffolded站点中,因此您无需担心自己实现此功能。 Yesod类型类中最强大的方法之一是addStaticContent。Widget由多个组件组成,包括CSS和Javascript。CSS / JS到底是如何到达用户的浏览器的?默认情况下,它们分别在页面的``,`
Try refreshing|] main :: IO () main = warp 3000 App ``` 在讨论Session时,我们将更详细地介绍getMessage / setMessage。 ## 自定义错误页面 专业网站的标志之一是设计合理的错误页面。Yesod通过默认的defaultLayout显示错误页面。但有时候,你会想自定义它。为此,您只需要覆盖errorHandler方法: ```Haskell {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} import Yesod data App = App mkYesod "App" [parseRoutes| / HomeR GET /error ErrorR GET /not-found NotFoundR GET |] instance Yesod App where errorHandler NotFound = fmap toTypedContent $ defaultLayout $ do setTitle "Request page not located" toWidget [hamlet|
We apologize for the inconvenience, but the requested page could not be located. |] errorHandler other = defaultErrorHandler other getHomeR :: Handler Html getHomeR = defaultLayout [whamlet|
Internal server error Not found |] getErrorR :: Handler () getErrorR = error "This is an error" getNotFoundR :: Handler () getNotFoundR = notFound main :: IO () main = warp 3000 App ``` 我们自定义了一个404页面。当我们不想为每种错误类型编写自定义处理程序时,我们可以使用`defaultErrorHandler`。由于类型限制我们需要去前面加上`fmap toTypedContent`。(我们将在下一章中详细了解TypedContent。)事实上,您甚至可以使用重定向等特殊响应: ```Haskell errorHandler NotFound = redirect HomeR errorHandler other = defaultErrorHandler other ``` > 即使你可以做到这一点,我实际上并没有推荐这样的做法。 404应该是404。 ## 外部CSS和Javascript > 此处描述的功能自动包含在scaffolded站点中,因此您无需担心自己实现此功能。 Yesod类型类中最强大的方法之一是addStaticContent。Widget由多个组件组成,包括CSS和Javascript。CSS / JS到底是如何到达用户的浏览器的?默认情况下,它们分别在页面的``,`