在模板目录之外使用Heist渲染模板

时间:2014-03-07 18:41:00

标签: haskell-snap-framework heist

我正在使用Snap创建一个相当简单的产品组合,在大多数情况下,它只是将数据存储在数据库中并显示给用户。我希望拥有的功能之一是能够展示我的投资组合的退役设计。每个设计只不过是一个模板和一小撮资产(图像,CSS等)。出于组织目的,我希望将属于单一设计的所有内容保留在一起,并与我的投资组合的模板/资产分开。

src/Site.hs

static/images/logo.png
static/css/responsive.css

archives/foo.com/2012-03/index.html
archives/foo.com/2012-03/images/logo.png
archives/foo.com/2012-03/css/styles.css
archives/foo.com/2012-03/favicion.ico

archives/bar.com/2011-08/index.html
archives/bar.com/2011-08/images/logo.png
archives/bar.com/2011-08/css/styles.css
archives/bar.com/2011-08/favicion.ico

我尝试在serveDirectory上使用archives。正如人们所期望的那样请求example.com/bar.com/2012/03/个请求archives/bar.com/2012/03/index.html,这对某些情况来说很好。我希望能够使用一些编译的拼接或Charade,这样当原始内容无法复制时页面看起来不那么空(通常是因为它来自一个早已被遗忘的数据库)。 / p>

为此目的制作单独的snaplet更有意义吗?如果是这样,我该怎么做呢?作为参考,我的网站的snaplet是相当基本的,看起来像这样:

app :: SnapletInit App App
app = makeSnaplet "connex" "A snaplet for the connex site." Nothing $ do
    h <- nestSnaplet "heist" heist $ heistInit' "templates" defaultHeistState
    s <- nestSnaplet "session" sess $ initCookieSessionManager "config/site_key.txt" "session" (Just 86400)
    d <- nestSnaplet "db" db pgsInit

    addRoutes 
        [ ("/", indexH siteH)
        -- more routes here
        , ("", serveDirectory "static")
        ]
    return $ App h s d
    where
        defaultHeistState = mempty {
            hcInterpretedSplices = defaultInterpretedSplices,
            hcLoadTimeSplices = defaultLoadTimeSplices
        }

(PS我有一个类似但不相关的项目,允许用户自定义他们自己的“网站”的外观。目前,自定义仅限于图像和CSS。如果上述问题的解决方案可用于允许自定义每个用户的布局模板都很棒。如果没有,不用担心。)

2 个答案:

答案 0 :(得分:0)

您可能需要进行一些手动布线才能使其按照您希望的方式工作,但您可以使用一些帮助程序。首先,addTemplatesAt函数允许您在HeistState中包含外部模板。您可以将它与您自己的serveDirectory路由结合使用,以提供静态资源。一旦你完成了一个案例的工作,我相信你将能够找到一种方法将这两者结合在一个抽象中,让你可以很容易地添加你网站以前外观的多个版本。

答案 1 :(得分:0)

以下是我最终用于主要用例的详细解决方案:

app :: SnapletInit App App
app = makeSnaplet "app" "An snaplet example application." Nothing $ do
    h <- nestSnaplet "heist" heist $ heistInit' "templates" defaultHeistState
    s <- nestSnaplet "sess" sess $ initCookieSessionManager "site_key.txt" "sess" (Just 3600)
    d <- nestSnaplet "db" db pgsInit

    addRoutes routes
    addTemplatesAt h "archives" "archives" -- added this
    return $ App h s d
    where
        defaultHeistState = mempty
            { hcInterpretedSplices = defaultInterpretedSplices
            , hcLoadTimeSplices = defaultLoadTimeSplices
            }

为我的模板提供服务的处理程序看起来像这样(非常类似于heistServe的样子):

archiveServe :: AppHandler ()
archiveServe = do
    url <- withRequest (return . rqPathInfo)
    let
        splices = return ()
        template = "archives/" <> url <> "index"
    renderWithSplices template splices 

我的路线:

designH = route
    [ ("/", ifTop designIndexH)
    , ("/archives/", archiveServe)
    , ("/archives/", serveDirectory "archives")
    ]