{-# LANGUAGE OverloadedStrings #-} -- | Manipulate CSS urls. -- -- * Make relative urls absolute (useful when combining assets) module Yesod.EmbeddedStatic.Css.AbsoluteUrl ( -- * Absolute urls absoluteUrls , absoluteUrlsAt , absoluteUrlsWith , absCssUrlsFileProd , absCssUrlsProd ) where import Yesod.EmbeddedStatic.Generators import Yesod.EmbeddedStatic.Types import qualified Data.ByteString.Lazy as BL import qualified Data.Text as T import qualified Data.Text.Lazy as TL import qualified Data.Text.IO as T import qualified Data.Text.Lazy.Encoding as TL import Control.Monad ((>=>)) import Data.Maybe (fromMaybe) import System.FilePath (()) import Yesod.EmbeddedStatic.Css.Util ------------------------------------------------------------------------------- -- Generator ------------------------------------------------------------------------------- -- | Anchors relative CSS image urls absCssUrlsFileProd :: FilePath -- ^ Anchor relative urls to here -> FilePath -> IO BL.ByteString absCssUrlsFileProd dir file = do contents <- T.readFile file return $ TL.encodeUtf8 $ absCssUrlsProd dir contents absCssUrlsProd :: FilePath -- ^ Anchor relative urls to here -> T.Text -> TL.Text absCssUrlsProd dir contents = let css = either error id $ parseCssUrls contents in renderCssWith toAbsoluteUrl css where toAbsoluteUrl (UrlReference rel) = T.concat [ "url('/" , (T.pack $ dir T.unpack rel) , "')" ] -- | Equivalent to passing the same string twice to 'absoluteUrlsAt'. absoluteUrls :: FilePath -> Generator absoluteUrls f = absoluteUrlsAt f f -- | Equivalent to passing @return@ to 'absoluteUrlsWith'. absoluteUrlsAt :: Location -> FilePath -> Generator absoluteUrlsAt loc f = absoluteUrlsWith loc f Nothing -- | Automatically make relative urls absolute -- -- During development, leave CSS as is. -- -- When CSS is organized into a directory structure, it will work properly for individual requests for each file. -- During production, we want to combine and minify CSS as much as possible. -- The combination process combines files from different directories, messing up relative urls. -- This pre-processor makes relative urls absolute absoluteUrlsWith :: Location -- ^ The location the CSS file should appear in the static subsite -> FilePath -- ^ Path to the CSS file. -> Maybe (CssGeneration -> IO BL.ByteString) -- ^ Another filter function run after this one (for example @return . yuiCSS . cssContent@) or other CSS filter that runs after this filter. -> Generator absoluteUrlsWith loc file mpostFilter = return [ cssProductionFilter (absCssUrlsFileProd loc >=> postFilter . mkCssGeneration loc file) loc file ] where postFilter = fromMaybe (return . cssContent) mpostFilter