forked from jaspervdj/hakyll
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
86 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
-- | Module used for generating HTML redirect pages. This allows renaming pages | ||
-- to avoid breaking existing links without requiring server-side support for | ||
-- formal 301 Redirect error codes | ||
module Hakyll.Web.Redirect | ||
( Redirect (..) | ||
, createRedirects | ||
) where | ||
|
||
import Control.Applicative ((<$>)) | ||
import Control.Monad (forM_) | ||
import Data.Binary (Binary (..)) | ||
import Hakyll.Core.Compiler | ||
import Hakyll.Core.Identifier | ||
import Hakyll.Core.Routes | ||
import Hakyll.Core.Rules | ||
import Hakyll.Core.Writable (Writable (..)) | ||
|
||
-- | This function exposes a higher-level interface compared to using the | ||
-- 'Redirect' type manually. | ||
-- | ||
-- This creates, using a database mapping broken URLs to working ones, HTML | ||
-- files which will do HTML META tag redirect pages (since, as a static site, we | ||
-- can't use web-server-level 301 redirects, and using JS is gross). | ||
-- | ||
-- This is useful for sending people using old URLs to renamed versions, dealing | ||
-- with common typos etc, and will increase site traffic. Such broken URLs can | ||
-- be found by looking at server logs or by using Google Webmaster Tools. | ||
-- Broken URLs must be valid Haskell strings, non-URL-escaped valid POSIX | ||
-- filenames, and relative links, since they will be defined in a @hakyll.hs@ | ||
-- and during generation, written to disk with the filename corresponding to the | ||
-- broken URLs. (Target URLs can be absolute or relative, but should be | ||
-- URL-escaped.) So broken incoming links like <http://www.gwern.net/foo/> which | ||
-- should be <http://www.gwern.net/foobar> cannot be fixed (since you cannot | ||
-- create a HTML file named @"foo/"@ on disk, as that would be a directory). | ||
-- | ||
-- An example of a valid association list would be: | ||
-- | ||
-- > brokenLinks = [("/Black-market archive", "/Black-market%20archives")] | ||
-- | ||
-- In which case the functionality can then be used in `main` with a line like: | ||
-- | ||
-- > createRedirects brokenLinks | ||
-- | ||
-- The on-disk files can then be uploaded with HTML mimetypes | ||
-- (either explicitly by generating and uploading them separately, by | ||
-- auto-detection of the filetype, or an upload tool defaulting to HTML | ||
-- mimetype, such as calling @s3cmd@ with @--default-mime-type=text/html@) and | ||
-- will redirect browsers and search engines going to the old/broken URLs. | ||
-- | ||
-- See also <https://groups.google.com/d/msg/hakyll/sWc6zxfh-uM/fUpZPsFNDgAJ>. | ||
createRedirects :: [(Identifier, String)] -> Rules () | ||
createRedirects redirects = | ||
forM_ redirects $ \(ident, to) -> | ||
create [ident] $ do | ||
route idRoute | ||
compile $ makeItem $! Redirect to | ||
|
||
-- | This datatype can be used directly if you want a lower-level interface to | ||
-- generate redirects. For example, if you want to redirect @foo.html@ to | ||
-- @bar.jpg@, you can use: | ||
-- | ||
-- > create ["foo.html"] $ do | ||
-- > route idRoute | ||
-- > compile $ makeItem $ Redirect "bar.jpg" | ||
data Redirect = Redirect | ||
{ redirectTo :: String | ||
} deriving (Eq, Ord, Show) | ||
|
||
instance Binary Redirect where | ||
put (Redirect to) = put to | ||
get = Redirect <$> get | ||
|
||
instance Writable Redirect where | ||
write path = write path . fmap redirectToHtml | ||
|
||
redirectToHtml :: Redirect -> String | ||
redirectToHtml (Redirect working) = | ||
"<!DOCTYPE html><html><head><meta charset=\"utf-8\"/><meta name=\"generator\" content=\"hakyll\"/>" ++ | ||
"<meta http-equiv=\"refresh\" content=\"0; url=" ++ working ++ | ||
"\"><link rel=\"canonical\" href=\"" ++ working ++ | ||
"\"><title>Permanent Redirect</title></head><body><p>The page has moved to: <a href=\"" ++ working ++ | ||
"\">this page</a></p></body></html>" |