gitit-0.15.1.2: Wiki using happstack, git or darcs, and pandoc.

Safe Haskell | Safe-Inferred
Language | Haskell2010

Network.Gitit.Interface

Description

Interface for plugins.

A plugin is a Haskell module that is dynamically loaded by gitit.

There are three kinds of plugins: `PageTransform`s, `PreParseTransform`s, and `PreCommitTransform`s. These plugins differ chiefly in where they are applied. `PreCommitTransform` plugins are applied just before changes to a page are saved and may transform the raw source that is saved. `PreParseTransform` plugins are applied when a page is viewed and may alter the raw page source before it is parsed as a `Pandoc` document. Finally, `PageTransform` plugins modify the `Pandoc` document that results after a page's source is parsed, but before it is converted to HTML:

                    +--------------------------+
                    | edited text from browser |
                    +--------------------------+
                                 ||         <----  PreCommitTransform plugins
                                 \/
                                 ||         <----  saved to repository
                                 \/
                 +---------------------------------+
                 | raw page source from repository |
                 +---------------------------------+
                                 ||         <----  PreParseTransform plugins
                                 \/
                                 ||         <----  markdown or RST reader
                                 \/
                        +-----------------+
                        | Pandoc document |
                        +-----------------+
                                 ||         <---- PageTransform plugins
                                 \/
                      +---------------------+
                      | new Pandoc document |
                      +---------------------+
                                 ||         <---- HTML writer
                                 \/
                      +----------------------+
                      | HTML version of page |
                      +----------------------+

Note that `PreParseTransform` and `PageTransform` plugins do not alter the page source stored in the repository. They only affect what is visible on the website. Only `PreCommitTransform` plugins can alter what is stored in the repository.

Note also that `PreParseTransform` and `PageTransform` plugins will not be run when the cached version of a page is used. Plugins can use the `doNotCache` command to prevent a page from being cached, if their behavior is sensitive to things that might change from one time to another (such as the time or currently logged-in user).

You can use the helper functions `mkPageTransform` and `mkPageTransformM` to create `PageTransform` plugins from a transformation of any of the basic types used by Pandoc (for example, `Inline`, `Block`, `[Inline]`, even `String`). Here is a simple (if silly) example:

    -- Deprofanizer.hs
    module Deprofanizer (plugin) where

    -- This plugin replaces profane words with "XXXXX".

    import Network.Gitit.Interface
    import Data.Char (toLower)

    plugin :: Plugin
    plugin = mkPageTransform deprofanize

    deprofanize :: Inline -> Inline
    deprofanize (Str x) | isBadWord x = Str "XXXXX"
    deprofanize x                     = x

    isBadWord :: String -> Bool
    isBadWord x = (map toLower x) `elem` ["darn", "blasted", "stinker"]
    -- there are more, but this is a family program

Further examples can be found in the `plugins` directory in the source distribution. If you have installed gitit using Cabal, you can also find them in the directory `CABALDIR/share/gitit-X.Y.Z/plugins`, where `CABALDIR` is the cabal install directory and `X.Y.Z` is the version number of gitit.

Synopsis

- data Plugin
  - = PageTransform (Pandoc -> PluginM Pandoc)
  - | PreParseTransform (String -> PluginM String)
  - | PreCommitTransform (String -> PluginM String)
- type PluginM = ReaderT PluginData (StateT Context IO)
- mkPageTransform :: Data a => (a -> a) -> Plugin
- mkPageTransformM :: Data a => (a -> PluginM a) -> Plugin
- data Config = Config {
  - repositoryPath :: FilePath
  - repositoryType :: FileStoreType
  - defaultPageType :: PageType
  - defaultExtension :: String
  - mathMethod :: MathMethod
  - defaultLHS :: Bool
  - showLHSBirdTracks :: Bool
  - withUser :: Handler -> Handler
  - requireAuthentication :: AuthenticationLevel
  - authHandler :: Handler
  - userFile :: FilePath
  - sessionTimeout :: Int
  - templatesDir :: FilePath
  - logFile :: FilePath
  - logLevel :: Priority
  - staticDir :: FilePath
  - pluginModules :: [String]
  - tableOfContents :: Bool
  - maxUploadSize :: Integer
  - maxPageSize :: Integer
  - address :: String
  - portNumber :: Int
  - debugMode :: Bool
  - frontPage :: String
  - noEdit :: [String]
  - noDelete :: [String]
  - defaultSummary :: String
  - deleteSummary :: String
  - accessQuestion :: Maybe (String, [String])
  - disableRegistration :: Bool
  - useRecaptcha :: Bool
  - recaptchaPublicKey :: String
  - recaptchaPrivateKey :: String
  - rpxDomain :: String
  - rpxKey :: String
  - compressResponses :: Bool
  - useCache :: Bool
  - cacheDir :: FilePath
  - mimeMap :: Map String String
  - mailCommand :: String
  - resetPasswordMessage :: String
  - markupHelp :: Text
  - useFeed :: Bool
  - baseUrl :: String
  - useAbsoluteUrls :: Bool
  - wikiTitle :: String
  - feedDays :: Integer
  - feedRefreshTime :: Integer
  - pandocUserData :: Maybe FilePath
  - xssSanitize :: Bool
  - recentActivityDays :: Int
  - githubAuth :: GithubConfig
  }
- data Request = Request {
  - rqSecure :: Bool
  - rqMethod :: Method
  - rqPaths :: [String]
  - rqUri :: String
  - rqQuery :: String
  - rqInputsQuery :: [(String, Input)]
  - rqInputsBody :: MVar [(String, Input)]
  - rqCookies :: [(String, Cookie)]
  - rqVersion :: HttpVersion
  - rqHeaders :: Headers
  - rqBody :: MVar RqBody
  - rqPeer :: Host
  }
- data User = User {
  - uUsername :: String
  - uPassword :: Password
  - uEmail :: String
  }
- data Context = Context {
  - ctxFile :: String
  - ctxLayout :: PageLayout
  - ctxCacheable :: Bool
  - ctxTOC :: Bool
  - ctxBirdTracks :: Bool
  - ctxCategories :: [String]
  - ctxMeta :: [(String, String)]
  }
- data PageType
  - = Markdown
  - | CommonMark
  - | RST
  - | LaTeX
  - | HTML
  - | Textile
  - | Org
  - | DocBook
  - | MediaWiki
- data PageLayout = PageLayout {
  - pgPageName :: String
  - pgRevision :: Maybe String
  - pgPrintable :: Bool
  - pgMessages :: [String]
  - pgTitle :: String
  - pgScripts :: [String]
  - pgShowPageTools :: Bool
  - pgShowSiteNav :: Bool
  - pgMarkupHelp :: Maybe Text
  - pgTabs :: [Tab]
  - pgSelectedTab :: Tab
  - pgLinkToFeed :: Bool
  }
- askConfig :: PluginM Config
- askUser :: PluginM (Maybe User)
- askRequest :: PluginM Request
- askFileStore :: PluginM FileStore
- askMeta :: PluginM [(String, String)]
- doNotCache :: PluginM ()
- getContext :: HasContext m => m Context
- modifyContext :: HasContext m => (Context -> Context) -> m ()
- inlinesToURL :: [Inline] -> String
- inlinesToString :: [Inline] -> String
- liftIO :: MonadIO m => IO a -> m a
- withTempDir :: FilePath -> (FilePath -> IO a) -> IO a
- module Text.Pandoc.Definition
- module Text.Pandoc.Generic

# Documentation

data Plugin Source #

Constructors

PageTransform (Pandoc -> PluginM Pandoc) |
PreParseTransform (String -> PluginM String) |
PreCommitTransform (String -> PluginM String) |

type PluginM = ReaderT PluginData (StateT Context IO) Source #

mkPageTransform :: Data a => (a -> a) -> Plugin Source #

Lifts a function from `a -> a` (for example, `Inline -> Inline`, `Block -> Block`, `[Inline] -> [Inline]`, or `String -> String`) to a `PageTransform` plugin.

mkPageTransformM :: Data a => (a -> PluginM a) -> Plugin Source #

Monadic version of `mkPageTransform`. Lifts a function from `a -> m a` to a `PageTransform` plugin.

data Config Source #

Data structure for information read from config file.

Constructors

Config |

Fields

- repositoryPath :: FilePath

  Path of repository containing filestore

- repositoryType :: FileStoreType

  Type of repository

- defaultPageType :: PageType

  Default page markup type for this wiki

- defaultExtension :: String

  Default file extension for pages in this wiki

- mathMethod :: MathMethod

  How to handle LaTeX math in pages?

- defaultLHS :: Bool

  Treat as literate haskell by default?

- showLHSBirdTracks :: Bool

  Show Haskell code with bird tracks

- withUser :: Handler -> Handler

  Combinator to set `REMOTE_USER` request header

- requireAuthentication :: AuthenticationLevel

  Handler for login, logout, register, etc.

- authHandler :: Handler

  Specifies which actions require authentication.

- userFile :: FilePath

  Path of users database

- sessionTimeout :: Int

  Seconds of inactivity before session expires

- templatesDir :: FilePath

  Directory containing page templates

- logFile :: FilePath

  Path of server log file

- logLevel :: Priority

  Severity filter for log messages (DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY)

- staticDir :: FilePath

  Path of static directory

- pluginModules :: [String]

  Names of plugin modules to load

- tableOfContents :: Bool

  Show table of contents on each page?

- maxUploadSize :: Integer

  Max size of file uploads

- maxPageSize :: Integer

  Max size of page uploads

- address :: String

  IP address to bind to

- portNumber :: Int

  Port number to serve content on

- debugMode :: Bool

  Print debug info to the console?

- frontPage :: String

  The front page of the wiki

- noEdit :: [String]

  Pages that cannot be edited via web

- noDelete :: [String]

  Pages that cannot be deleted via web

- defaultSummary :: String

  Default summary if description left blank

- deleteSummary :: String

  Delete summary

- accessQuestion :: Maybe (String, [String])

  `Nothing` = anyone can register. `Just (prompt, answers)` = a user will be given the prompt and must give one of the answers to register.

- disableRegistration :: Bool

  Disable Registration?

- useRecaptcha :: Bool

  Use ReCAPTCHA for user registration.

- recaptchaPublicKey :: String
- recaptchaPrivateKey :: String
- rpxDomain :: String

  RPX domain and key

- rpxKey :: String
- compressResponses :: Bool

  Should responses be compressed?

- useCache :: Bool

  Should responses be cached?

- cacheDir :: FilePath

  Directory to hold cached pages

- mimeMap :: Map String String

  Map associating mime types with file extensions

- mailCommand :: String

  Command to send notification emails

- resetPasswordMessage :: String

  Text of password reset email

- markupHelp :: Text

  Markup syntax help for edit sidebar

- useFeed :: Bool

  Provide an atom feed?

- baseUrl :: String

  Base URL of wiki, for use in feed

- useAbsoluteUrls :: Bool

  Title of wiki, used in feed

- wikiTitle :: String

  Should WikiLinks be absolute w.r.t. the base URL?

- feedDays :: Integer

  Number of days history to be included in feed

- feedRefreshTime :: Integer

  Number of minutes to cache feeds before refreshing

- pandocUserData :: Maybe FilePath

  Directory to search for pandoc customizations

- xssSanitize :: Bool

  Filter HTML through xss-sanitize

- recentActivityDays :: Int

  The default number of days in the past to look for "recent" activity

- githubAuth :: GithubConfig

  Github client data for authentication (id, secret, callback, authorize endpoint, access token endpoint)

data Request Source #

an HTTP request

Constructors

Request |

Fields

- rqSecure :: Bool

  request uses https://

- rqMethod :: Method

  request method

- rqPaths :: [String]

  the uri, split on /, and then decoded

- rqUri :: String

  the raw rqUri

- rqQuery :: String

  the QUERY_STRING

- rqInputsQuery :: [(String, Input)]

  the QUERY_STRING decoded as key/value pairs

- rqInputsBody :: MVar [(String, Input)]

  the request body decoded as key/value pairs (when appropriate)

- rqCookies :: [(String, Cookie)]

  cookies

- rqVersion :: HttpVersion

  HTTP version

- rqHeaders :: Headers

  the HTTP request headers

- rqBody :: MVar RqBody

  the raw, undecoded request body

- rqPeer :: Host

  (hostname, port) of the client making the request

#### Instances

Instances details

Show Request |
Instance details Defined in Happstack.Server.Internal.Types Methods showsPrec :: Int -> Request -> ShowS Source # show :: Request -> String Source # showList :: [Request] -> ShowS Source #
HasHeaders Request |
Instance details Defined in Happstack.Server.Internal.Types Methods updateHeaders :: (Headers -> Headers) -> Request -> Request headers :: Request -> Headers

data User Source #

Constructors

User |

Fields

- uUsername :: String
- uPassword :: Password
- uEmail :: String

#### Instances

Instances details

Read User Source # |
Instance details Defined in Network.Gitit.Types Methods readsPrec :: Int -> ReadS User Source # readList :: ReadS [User] Source # readPrec :: ReadPrec User Source # readListPrec :: ReadPrec [User] Source #
Show User Source # |
Instance details Defined in Network.Gitit.Types Methods showsPrec :: Int -> User -> ShowS Source # show :: User -> String Source # showList :: [User] -> ShowS Source #

data Context Source #

Constructors

Context |

Fields

- ctxFile :: String
- ctxLayout :: PageLayout
- ctxCacheable :: Bool
- ctxTOC :: Bool
- ctxBirdTracks :: Bool
- ctxCategories :: [String]
- ctxMeta :: [(String, String)]

#### Instances

Instances details

HasContext ContentTransformer Source # |
Instance details Defined in Network.Gitit.Types Methods getContext :: ContentTransformer Context Source # modifyContext :: (Context -> Context) -> ContentTransformer () Source #
HasContext PluginM Source # |
Instance details Defined in Network.Gitit.Types Methods getContext :: PluginM Context Source # modifyContext :: (Context -> Context) -> PluginM () Source #

data PageType Source #

Constructors

Markdown |
CommonMark |
RST |
LaTeX |
HTML |
Textile |
Org |
DocBook |
MediaWiki |

#### Instances

Instances details

Read PageType Source # |
Instance details Defined in Network.Gitit.Types Methods readsPrec :: Int -> ReadS PageType Source # readList :: ReadS [PageType] Source # readPrec :: ReadPrec PageType Source # readListPrec :: ReadPrec [PageType] Source #
Show PageType Source # |
Instance details Defined in Network.Gitit.Types Methods showsPrec :: Int -> PageType -> ShowS Source # show :: PageType -> String Source # showList :: [PageType] -> ShowS Source #
Eq PageType Source # |
Instance details Defined in Network.Gitit.Types Methods (==) :: PageType -> PageType -> Bool Source # (/=) :: PageType -> PageType -> Bool Source #

data PageLayout Source #

Abstract representation of page layout (tabs, scripts, etc.)

Constructors

PageLayout |

Fields

- pgPageName :: String
- pgRevision :: Maybe String
- pgPrintable :: Bool
- pgMessages :: [String]
- pgTitle :: String
- pgScripts :: [String]
- pgShowPageTools :: Bool
- pgShowSiteNav :: Bool
- pgMarkupHelp :: Maybe Text
- pgTabs :: [Tab]
- pgSelectedTab :: Tab
- pgLinkToFeed :: Bool

askConfig :: PluginM Config Source #

Returns the current wiki configuration.

askUser :: PluginM (Maybe User) Source #

Returns `Just` the logged in user, or `Nothing` if nobody is logged in.

askRequest :: PluginM Request Source #

Returns the complete HTTP request.

askFileStore :: PluginM FileStore Source #

Returns the wiki filestore.

askMeta :: PluginM [(String, String)] Source #

Returns the page meta data

doNotCache :: PluginM () Source #

Indicates that the current page or file is not to be cached.

getContext :: HasContext m => m Context Source #

modifyContext :: HasContext m => (Context -> Context) -> m () Source #

inlinesToURL :: [Inline] -> String Source #

Derives a URL from a list of Pandoc Inline elements.

inlinesToString :: [Inline] -> String Source #

Convert a list of inlines into a string.

liftIO :: MonadIO m => IO a -> m a Source #

Lift a computation from the `IO` monad. This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations (i.e. `IO` is the base monad for the stack).

### Example

Expand

    import Control.Monad.Trans.State -- from the "transformers" library

    printState :: Show s => StateT s IO ()
    printState = do
      state <- get
      liftIO $ print state

Had we omitted ``liftIO``, we would have ended up with this error:

    • Couldn't match type ‘IO’ with ‘StateT s IO’
     Expected type: StateT s IO ()
       Actual type: IO ()

The important part here is the mismatch between `StateT s IO ()` and ``IO` ()`.

Luckily, we know of a function that takes an ``IO` a` and returns an `(m a)`: ``liftIO``, enabling us to run the program and see the expected results:

    > evalStateT printState "hello"
    "hello"

    > evalStateT printState 3
    3

withTempDir :: FilePath -> (FilePath -> IO a) -> IO a Source #

Perform a function in a temporary directory and clean up.

module Text.Pandoc.Definition

module Text.Pandoc.Generic