tl; dr - Вы можете использовать пакет Beerend Lauwers's hakyll-extra
(похоже, на hackage
), который обеспечивает макрос relativizeUrl
. Или выполните свою собственную работу следующим образом:
Если у вас слишком много ссылок и не нужно вводить парсер CSS только для этого, вы можете просто создать поле функции - эффективно, макрос - который позволяет вам звонить, напримерrelativize("/some/url")
изнутри. (Я столкнулся с подобной проблемой, потому что мне хотелось релятивизировать ссылки на таблицу стилей для использования только старыми версиями Internet Explorer, а до TagSoup
ссылки выглядели так, как если бы они были в комментариях, поэтому они не обрабатывали их.)
Во-первых, нам нужно написать версию relativizeUrls
которая просто работает на одном URL:
import Data.List as L
-- | Relativize URL. Same logic as "relativizeUrlsWith" in
-- Hakyll.Web.Html.RelativizeUrls, but for just one url.
relativizeUrl :: String --^Path to the site root
-> String --^link to relativize
-> String --^Resulting link
relativizeUrl root = rel
where
isRel :: String -> Bool
isRel x = "/" `L.isPrefixOf` x && not ("//" `L.isPrefixOf` x)
rel x = if isRel x then root ++ x else x
Затем мы определяем «поле функции», который может быть добавлен в контекстах.
import Data.Maybe (maybe)
-- ugh. ugly name.
relativizeFuncField :: Context a
relativizeFuncField = functionField "relativize" relativize
where
relativize :: [String] -> Item a -> Compiler String
relativize args item = do
siteRoot <- getRoot <$> (getRoute $ itemIdentifier item)
arg <- case args of
[arg] -> return arg
_ -> error "relativize: expected only 1 arg"
return $ relativizeUrl siteRoot arg
getRoot :: Maybe String -> String
getRoot = maybe (error "relativize: couldn't get route") toSiteRoot
Затем, в любом месте вы хотите использовать этот макрос, вместо того, чтобы использовать, скажем, defaultContext
, используйте relativizeFuncField <> defaultContext
. например .:
import Data.Monoid((<>))
main =
-- ...
match (fromList ["about.rst", "contact.markdown"]) $ do
route $ setExtension "html"
compile $ pandocCompiler
>>= loadAndApplyTemplate "templates/default.html" (relativizeFuncField <> defaultContext)
>>= relativizeUrls
Таким образом, в конце концов, это означает, что в файле, вы можете написать $relativize("/path/to/file")$
в любом месте, где TagSoup
еще не релятивизации ссылки.
Надеется, что это использование :)
(Это было с помощью Hakyll 4.9.0.0, но я предполагаю, что другие версии 4.X являются почти таким же.)
редактируемых: пса, многие благодаря Beerend Lauwers, который объяснил функциональные поля Hakyll в своем посте here
отредактировал еще раз: d'oh. Я не видел, что Beerend на самом деле уже положил функцию relativizeUrl
в свой пакет hakyll-extra
.
О да, это определенно хорошее решение. –