Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use HStringTemplate template for pages.

- Added data/template.html (default template).
- Added configuration field for templateFile.
- Copy template file if it doesn't exist on wiki initialize.
- Removed unneeded logo, wiki title, footer config options.
  These things can now be changed by changing the template.
- Added HStringTemplate to cabal file dependencies.
- Use an IORef (initialized with unsafePerformIO) to
  store the page template.  Compile the page template
  on startup.
- Don't display tabs in print css.
- Fixed bottom border on selected tabs in screen css.
- Updated README.
  • Loading branch information...
commit f498fc6dc2125393313861b796eef1b0df624f01 1 parent 51a76cc
@jgm authored
View
117 Gitit.hs
@@ -56,10 +56,16 @@ import Network.HTTP (urlEncodeVars, urlEncode)
import System.Console.GetOpt
import System.Exit
import Text.Highlighting.Kate
+import Text.StringTemplate as T
+import Data.IORef
+import System.IO.Unsafe (unsafePerformIO)
gititVersion :: String
gititVersion = "0.3.1"
+template :: IORef (StringTemplate String)
+template = unsafePerformIO $ newIORef $ newSTMP "" -- initialize template to empty string
+
main :: IO ()
main = do
argv <- getArgs
@@ -68,6 +74,9 @@ main = do
gitPath <- findExecutable "git"
when (isNothing gitPath) $ error "'git' program not found in system path."
initializeWiki conf
+ -- initialize template
+ templ <- liftIO $ readFile (templateFile conf)
+ writeIORef template (newSTMP templ)
control <- startSystemState entryPoint
update $ SetConfig conf
-- read user file and update state
@@ -147,6 +156,7 @@ initializeWiki conf = do
let repodir = repositoryPath conf
let frontpage = frontPage conf <.> "page"
let staticdir = staticDir conf
+ let templatefile = templateFile conf
repoExists <- doesDirectoryExist repodir
unless repoExists $ do
postupdatepath <- getDataFileName $ "data" </> "post-update"
@@ -198,6 +208,11 @@ initializeWiki conf = do
"If you want support for math, copy the jsMath directory into " ++ staticdir ++ "/js/\n" ++
"jsMath can be obtained from http://www.math.union.edu/~dpvc/jsMath/\n" ++
replicate 80 '*'
+ templateExists <- doesFileExist templatefile
+ unless templateExists $ do
+ templatePath <- getDataFileName $ "data" </> "template.html"
+ copyFile templatePath templatefile
+ hPutStrLn stderr $ "Created " ++ templatefile
type Handler = ServerPart Response
@@ -842,52 +857,12 @@ formattedPage layout page params htmlContents = do
then gitGetSHA1 path' >>= return . fromMaybe ""
else return revision
user <- getLoggedInUser params
- cfg <- (query GetConfig)
- let stylesheetlinks =
- if pPrintable params
- then thelink ! [href "/css/print.css", rel "stylesheet", strAttr "media" "all", thetype "text/css"] << noHtml
- else thelink ! [href "/css/screen.css", rel "stylesheet",
- strAttr "media" "screen, projection", thetype "text/css"] << noHtml +++
- primHtml "<!--[if IE]>" +++
- thelink ! [href "/css/ie.css", rel "stylesheet",
- strAttr "media" "screen, projection", thetype "text/css"] << noHtml +++
- primHtml "<![endif]-->" +++
- thelink ! [href "/css/hk-pyg.css", rel "stylesheet",
- strAttr "media" "screen, projection", thetype "text/css"] << noHtml +++
- thelink ! [href "/css/print.css", rel "stylesheet", strAttr "media" "print", thetype "text/css"] << noHtml
let javascriptlinks = if null (pgScripts layout)
- then noHtml
- else concatHtml $ map
+ then ""
+ else renderHtmlFragment $ concatHtml $ map
(\x -> script ! [src ("/js/" ++ x), thetype "text/javascript"] << noHtml)
(["jquery.min.js", "jquery-ui.packed.js"] ++ pgScripts layout)
- let pageTitle' = pgTitle layout `orIfNull` page
- let title' = thetitle << (wikiTitle cfg ++ " - " ++ pageTitle')
- let head' = header << [title', stylesheetlinks, javascriptlinks]
- let searchbox = gui ("/_search") ! [identifier "searchform"] <<
- [ textfield "patterns"
- , submit "search" "Search" ]
- let sitenav = thediv ! [theclass "sitenav"] <<
- fieldset <<
- [ legend << "Site"
- , ulist << (map li
- [ anchor ! [href "/"] << "Front page"
- , anchor ! [href "/_index"] << "All pages"
- , anchor ! [href "/_random"] << "Random page"
- , anchor ! [href "/_activity"] << "Recent activity"
- , anchor ! [href "/_upload"] << "Upload a file"
- , anchor ! [href "/Help"] << "Help" ])
- , searchbox ]
- let tools = if pgShowPageTools layout
- then thediv ! [theclass "pageTools"] <<
- fieldset <<
- [ legend << "This page"
- , ulist << (map li
- [ anchor ! [href $ urlForPage page ++ "?revision=" ++ revision ++ "&showraw"] << "Raw page source"
- , anchor ! [href $ urlForPage page ++ "?revision=" ++ revision ++ "&printable"] << "Printable version"
- , anchor ! [href $ urlForPage page ++ "?revision=" ++ sha1] << "Permanent link"
- , anchor ! [href $ urlForPage page ++ "?delete"] << "Delete this page" ])
- , exportBox page params ]
- else noHtml
+ let pageTitle = pgTitle layout `orIfNull` page
let tabli tab = if tab == pgSelectedTab layout
then li ! [theclass "selected"]
else li
@@ -898,42 +873,34 @@ formattedPage layout page params htmlContents = do
if revision == "HEAD" then "" else "&" ++ urlEncodeVars [("logMsg", "Revert to " ++ revision)]] <<
if revision == "HEAD" then "edit" else "revert"
else Nothing
- let buttons = ulist ! [theclass "tabs"] << mapMaybe linkForTab (pgTabs layout)
- let userbox = thediv ! [identifier "userbox"] <<
- case user of
- Just u -> [ anchor ! [href ("/_logout?" ++ urlEncodeVars [("destination", page)])] <<
- ("Logout " ++ u) ]
- Nothing -> [ anchor ! [href ("/_login?" ++ urlEncodeVars [("destination", page)])] <<
- "Login"
- , primHtml "&nbsp;&bull;&nbsp;"
- , anchor ! [href ("/_register?" ++ urlEncodeVars [("destination", page)])] <<
- "Get an account" ]
+ let tabs = ulist ! [theclass "tabs"] << mapMaybe linkForTab (pgTabs layout)
+ let searchbox = gui ("/_search") ! [identifier "searchform"] <<
+ [ textfield "patterns"
+ , submit "search" "Search" ]
let messages = pMessages params
let htmlMessages = if null messages
then noHtml
else ulist ! [theclass "messages"] << map (li <<) messages
- let body' = body << thediv ! [identifier "container"] <<
- [ thediv ! [identifier "sidebar"] <<
- [ thediv ! [identifier "logo"] <<
- anchor ! [href "/", title "Go to top page"] <<
- case wikiLogo cfg of
- Nothing -> noHtml
- Just f -> image ! [src f]
- , sitenav
- , tools ]
- , userbox
- , thediv ! [identifier "maincol"] <<
- [ thediv ! [theclass "pageControls"] << buttons
- , thediv ! [identifier "content"] <<
- [ anchor ! [href $ urlForPage page] << (h1 ! [theclass "pageTitle"] << pageTitle')
- , if revision == "HEAD"
- then noHtml
- else h2 ! [theclass "revision"] << ("Revision " ++ revision)
- , htmlMessages
- , htmlContents ]
- , thediv ! [identifier "footer"] << primHtml (wikiFooter cfg) ]
- ]
- ok $ toResponse $ head' +++ body'
+ templ <- liftIO $ readIORef template
+ let filledTemp = T.render $
+ setAttribute "pagetitle" pageTitle $
+ setAttribute "javascripts" javascriptlinks $
+ setAttribute "pagename" page $
+ (case user of
+ Just u -> setAttribute "user" u
+ Nothing -> id) $
+ (if isPage page then setAttribute "ispage" "true" else id) $
+ (if pgShowPageTools layout then setAttribute "pagetools" "true" else id) $
+ (if pPrintable params then setAttribute "printable" "true" else id) $
+ setAttribute "revision" revision $
+ setAttribute "sha1" sha1 $
+ setAttribute "searchbox" (renderHtmlFragment searchbox) $
+ setAttribute "exportbox" (renderHtmlFragment $ exportBox page params) $
+ setAttribute "tabs" (renderHtmlFragment tabs) $
+ setAttribute "messages" (renderHtmlFragment htmlMessages) $
+ setAttribute "content" (renderHtmlFragment htmlContents) $
+ templ
+ ok $ setContentType "text/html" $ toResponse filledTemp
-- user authentication
loginForm :: Params -> Html
View
8 Gitit/State.hs
@@ -38,10 +38,8 @@ import GHC.Conc (STM)
data Config = Config {
repositoryPath :: FilePath, -- path of git repository for pages
userFile :: FilePath, -- path of users database
+ templateFile :: FilePath, -- path of page template file
staticDir :: FilePath, -- path of static directory
- wikiLogo :: Maybe String, -- Nothing, or Just path to an image to be displayed at top left
- wikiTitle :: String, -- title of wiki
- wikiFooter :: String, -- HTML to be included at bottom of pages
tableOfContents :: Bool, -- should each page have an automatic table of contents?
maxUploadSize :: Integer, -- maximum size of pages and file uploads
portNumber :: Int, -- port number to serve content on
@@ -59,10 +57,8 @@ defaultConfig :: Config
defaultConfig = Config {
repositoryPath = "wikidata",
userFile = "gitit-users",
+ templateFile = "template.html",
staticDir = "static",
- wikiLogo = Just "/img/logo.png",
- wikiTitle = "Wiki",
- wikiFooter = "powered by <a href=\"http://github.com/jgm/gitit/tree/master/\">gitit</a>",
tableOfContents = True,
maxUploadSize = 100000,
portNumber = 5001,
View
34 README.markdown
@@ -72,7 +72,8 @@ To run gitit, you'll need [git][] in your system path. Check this by doing
Switch to the directory where you want to run gitit. This should be a directory
where you have write access, since two directories, `static` and `wikidata`, and
-a file, `gitit-users`, will be created here. To start gitit, just type:
+two files, `gitit-users` and `template.html`, will be created here. To
+start gitit, just type:
gitit
@@ -80,7 +81,9 @@ If all goes well, gitit will do the following:
1. Create a git repository, `wikidata`, and add a default front page.
2. Create a `static` directory containing the scripts and CSS used by gitit.
- 3. Start a web server on port 5001.
+ 3. Create a `template.html` file containing an (HStringTemplate) template
+ for wiki pages.
+ 4. Start a web server on port 5001.
Check that it worked: open a web browser and go to http://localhost:5001.
@@ -93,10 +96,8 @@ option `-f [filename]`. A configuration file takes the following form:
Config {
repositoryPath = "wikidata",
userFile = "gitit-users",
+ templateFile = "template.html",
staticDir = "static",
- wikiLogo = Just "/img/logo.png",
- wikiTitle = "Wiki",
- wikiFooter = "Powered by Gitit\n<!-- Logo courtesy of http://flickr.com/photos/wolfhound/127936545/, licensed under Creative Commons Attribution license -->",
tableOfContents = False,
maxUploadSize = 100000,
portNumber = 5001,
@@ -112,24 +113,20 @@ option `-f [filename]`. A configuration file takes the following form:
the wiki's pages will be stored. If it does not exist, gitit will create
it on startup.
-- `gitit-users` is a file containing user login information (with hashed
+- `userFile` is a file containing user login information (with hashed
passwords). If it does not exist, gitit will start with an empty list
- of users. Gitit will write a new `gitit-users` file on shutdown.
+ of users. Gitit will write a new `userFile` on shutdown.
+
+- `templateFile` is a file containing an HTML template for the wiki pages.
+ If it does not exist, gitit will create a default template. (For most
+ purposes, this can be used just as it is, but some users may wish to
+ customize the look of their wiki.) `templateFile` is an
+ `HStringTemplate` template.
- `staticDir` is the (relative) path of a directory in which static content
(javascript, CSS, images) is stored. If it does not exist, gitit will
create it on startup.
-- `wikiLogo` is either `Nothing` (no logo) or `Just "/url/of/logo"`.
- By default, the logo is set to `/img/logo.png`, so the easiest way to
- change the logo is just to copy a new file to `static/img/logo.png`.
- Be sure to use an absolute URL.
-
-- `wikiTitle` is the title that will be shown on the browser's title bar,
- together with the name of the page being viewed.
-
-- `wikiFooter` is raw HTML that will be inserted in the footer of every page.
-
- `tableOfContents` is either `False` or `True`. If it is `True`, a table
of contents (derived from the page's headers) will appear on each page.
@@ -176,6 +173,9 @@ Changing the theme
To change the look of the wiki, modify `screen.css` in `static/css`.
To change the look of printed pages, modify `print.css`.
+The logo picture can be changed by copying a new PNG file to
+`static/img/logo.png`. For more radical changes, one can modify
+`template.html`.
Adding support for math
-----------------------
View
5 css/print.css
@@ -19,7 +19,7 @@ h2{font-size:17pt;}
h3{font-size:15pt;}
h4,h5,h6{font-size:12pt;}
-code { font: 10pt Courier, monospace; }
+code { font: 11pt Courier, monospace; }
blockquote { margin: 1.3em; padding: 1em; font-size: 10pt; }
hr { background-color: #ccc; }
@@ -46,8 +46,9 @@ tr {page-break-inside: avoid;}
#maincol { margin-left: 1em; margin-right: 1em; border: none; }
#content { border: none; }
-#sidebar, div.pageControls, #userbox, #footer {display:none;}
+#sidebar, #userbox, #footer {display:none;}
#toc { display: none; }
h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link { text-decoration: none; }
h1.pageTitle { font-size: 220%; }
td.lineNumbers { display: none; }
+ul.tabs { display: none; }
View
3  css/screen.css
@@ -269,7 +269,6 @@ body {
#sidebar ul li { color: #888; }
#maincol { position: absolute; margin-left: 13em; margin-top: 1em; padding-top: 0; margin-right: 0; }
#content { border: 1px solid #ccc; background-color: #fff; padding: 1em; font-size: 110%; line-height: 150%; }
-#pageControls { }
div#toc {
float: right;
background-color: #f9f9f9;
@@ -311,7 +310,7 @@ ul.tabs li {
line-height: 1.2em;
}
ul.tabs li.selected {
- border-bottom: 1px solid white;
+ border-bottom: 3px solid white;
}
ul.tabs li a {
text-decoration: none;
View
4 data/SampleConfig.hs
@@ -1,10 +1,8 @@
Config {
repositoryPath = "wikidata",
userFile = "gitit-users",
+templateFile = "template.html",
staticDir = "static",
-wikiLogo = Just "/img/logo.png",
-wikiTitle = "Wiki",
-wikiFooter = "Powered by Gitit\n<!-- Logo courtesy of http://flickr.com/photos/wolfhound/127936545/, licensed under Creative Commons Attribution license -->",
tableOfContents = False,
maxUploadSize = 100000,
portNumber = 5001,
View
70 data/template.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Wiki - $pagetitle$</title>
+ <link href="/css/screen.css" rel="stylesheet" media="screen, projection" type="text/css" />
+ <!--[if IE]><link href="/css/ie.css" rel="stylesheet" media="screen, projection" type="text/css" /><![endif]-->
+ <link href="/css/hk-pyg.css" rel="stylesheet" media="screen, projection" type="text/css" />
+ <link href="/css/print.css" rel="stylesheet" media="print" type= "text/css" />
+ $if(printable)$
+ <link href="/css/print.css" rel="stylesheet" media="all" type= "text/css" />
+ $endif$
+ $javascripts$
+ </head>
+ <body>
+ <div id="container">
+ <div id="sidebar">
+ <div id="logo">
+ <a href="/" title="Go to top page"><img src="/img/logo.png" /></a>
+ </div>
+ <div class="sitenav">
+ <fieldset>
+ <legend>Site</legend>
+ <ul>
+ <li><a href="/">Front page</a></li>
+ <li><a href="/_index">All pages</a></li>
+ <li><a href="/_random">Random page</a></li>
+ <li><a href="/_activity">Recent activity</a></li>
+ <li><a href="/_upload">Upload a file</a></li>
+ <li><a href="/Help">Help</a></li>
+ </ul>
+ $searchbox$
+ </fieldset>
+ </div>
+ $if(pagetools)$
+ <div class="pageTools">
+ <fieldset>
+ <legend>This page</legend>
+ <ul>
+ <li><a href="/$pagename$?revision=$revision$&amp;showraw">Raw page source</a></li>
+ <li><a href="/$pagename$?revision=$revision$&amp;printable">Printable version</a></li>
+ <li><a href="/$pagename$?revision=$sha1$">Permanent link</a></li>
+ <li><a href="/$pagename$?delete">Delete this page</a></li>
+ </ul>
+ $exportbox$
+ </fieldset>
+ </div>
+ $endif$
+ </div>
+ <div id="userbox">
+ $if(user)$
+ <a href="/_logout?destination=$pagename$">Logout $user$</a>
+ $else$
+ <a href="/_login?destination=$pagename$">Login</a> &bull; <a href="/_register?destination=$pagename$">Get an account</a>
+ $endif$
+ </div>
+ <div id="maincol">
+ $tabs$
+ <div id="content">
+ <h1 class="pageTitle"><a href="/$pagename$">$pagetitle$</a></h1>
+ $messages$
+ <div id="wikipage" ondblclick="window.location='/$pagename$?edit">
+ $content$
+ </div>
+ </div>
+ <div id="footer">powered by <a href="http://github.com/jgm/gitit/tree/master/">gitit</a></div>
+ </div>
+ </div>
+ </body>
+</html>
View
3  gitit.cabal
@@ -46,7 +46,8 @@ Executable gitit
network, old-time, highlighting-kate, bytestring,
utf8-string, HAppS-Server >= 0.9.3 && < 0.9.4,
HAppS-State >= 0.9.3 && < 0.9.4,
- HAppS-Data >= 0.9.3 && < 0.9.4, SHA > 1, HTTP
+ HAppS-Data >= 0.9.3 && < 0.9.4, SHA > 1, HTTP,
+ HStringTemplate
if impl(ghc >= 6.10)
build-depends: base >= 4, syb
ghc-options: -Wall -threaded
Please sign in to comment.
Something went wrong with that request. Please try again.