packages feed

informative 0.1.0.3 → 0.1.0.4

raw patch · 7 files changed

+550/−33 lines, 7 filesdep +highlighting-katePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: highlighting-kate

API changes (from Hackage documentation)

- Web.Informative.Data: instance Bounded TextFormat
- Web.Informative.Data: instance Enum TextFormat
+ Web.Informative: fmtLang :: TextFormat -> Text
+ Web.Informative: fmtLine :: TextFormat -> Int
+ Web.Informative: fmtNorm :: TextFormat -> TextFormat
+ Web.Informative: getCreateR :: Text -> WikiHandler Html
+ Web.Informative: getInsertR :: Int -> WikiHandler Html
+ Web.Informative: getPrependR :: Int -> WikiHandler Html
+ Web.Informative: postCreateR :: Text -> WikiHandler Html
+ Web.Informative: postDeleteR :: Int -> WikiHandler Html
+ Web.Informative: postDownR :: Int -> WikiHandler Html
+ Web.Informative: postEditR :: Int -> WikiHandler Html
+ Web.Informative: postInsertR :: Int -> WikiHandler Html
+ Web.Informative: postPrependR :: Int -> WikiHandler Html
+ Web.Informative: postUpR :: Int -> WikiHandler Html
+ Web.Informative: remCR :: [Char] -> [Char]
+ Web.Informative: sdFirstLine :: SectionData -> Int
+ Web.Informative: sdLang :: SectionData -> Text
+ Web.Informative: source :: TextFormat -> Text -> Int -> TextFormat
+ Web.Informative: toClassname :: Text -> [Char]
+ Web.Informative.Data: Source :: Text -> Int -> TextFormat
+ Web.Informative.Data: Textile :: TextFormat
- Web.Informative: SectionData :: TextKind -> TextFormat -> Textarea -> SectionData
+ Web.Informative: SectionData :: TextKind -> TextFormat -> Text -> Int -> Textarea -> SectionData
- Web.Informative: getEditR :: Text -> Int -> WikiHandler Html
+ Web.Informative: getEditR :: Int -> WikiHandler Html

Files

Web/Informative.hs view
@@ -5,6 +5,8 @@ import Control.Applicative import Control.Arrow import Control.Monad+import Data.Char+import Data.Monoid import qualified Data.Text as T import Data.Time.Clock import Data.Time.Format@@ -13,9 +15,12 @@ import Text.Cassius import Text.CSV import Text.Hamlet+import Text.Highlighting.Kate+import Text.Highlighting.Kate.Format.HTML+import Text.Highlighting.Kate.Types import qualified Text.Pandoc as P import Web.Informative.Data-import Yesod+import Yesod hiding (languages) import Yesod.Auth import Yesod.Form @@ -55,15 +60,30 @@ readFmt MediaWiki = P.readMediaWiki readFmt ReStructuredText = P.readRST readFmt LaTeX = P.readLaTeX+readFmt Textile = P.readTextile+convFmt :: TextFormat -> String -> Html convFmt Plain = toHtml-convFmt fmt = preEscapedToMarkup . P.writeHtml P.def . readFmt fmt P.def+convFmt (Source lg ln) = toHtml . formatHtmlBlock defaultFormatOpts{numberLines=True,startNumber=ln,containerClasses=["sourceCode","source-"<>toClassname lg],codeClasses=["source-"<>toClassname lg]} . highlightAs (T.unpack lg)+convFmt fmt = preEscapedToMarkup . P.writeHtml P.def{P.writerHtml5=True,P.writerHighlight=True,P.writerListings=True} . readFmt fmt P.def{P.readerSmart=True} convSect Table fmt = convTable fmt convSect Mapping fmt = convTable fmt-convSect _ fmt = Left . convFmt fmt . T.unpack+convSect _ fmt = Left . convFmt fmt . remCR . T.unpack convTable :: TextFormat -> T.Text -> Either Html [[Html]]-convTable fmt t = case parseCSV (T.unpack "wikipage") (T.unpack t) of+convTable fmt t = case parseCSV (T.unpack "wikipage") (remCR $ T.unpack t) of   Left err -> Left $ toHtml $ show err   Right csv -> Right $ map (map (convFmt fmt)) csv+source :: TextFormat -> T.Text -> Int -> TextFormat+source (Source _ _) lg ln = Source lg ln+source fmt _ _ = fmt+fmtNorm :: TextFormat -> TextFormat+fmtNorm (Source _ _) = Source "" 1+fmtNorm fmt = fmt+fmtLang (Source lg _) = lg+fmtLang _ = "haskell"+fmtLine (Source _ ln) = ln+fmtLine _ = 1+toClassname = filter isAlphaNum . T.unpack+remCR = filter (/=chr 13)  getArticleIdR :: Int -> WikiHandler Html getArticleIdR pageid = do@@ -123,6 +143,8 @@ data SectionData = SectionData {   sdKind :: TextKind,   sdFormat :: TextFormat,+  sdLang :: T.Text,+  sdFirstLine :: Int,   sdContent :: Textarea   } @@ -130,36 +152,433 @@ editSectionForm mdata = renderDivs $ SectionData                         <$> areq (selectFieldList kinds) "Kind:" (sdKind <$> mdata)                         <*> areq (selectFieldList formats) "Format:" (sdFormat <$> mdata)+                        <*> areq textField "Language:" (sdLang <$> mdata)+                        <*> areq intField "First line:" (sdFirstLine <$> mdata)                         <*> areq textareaField "Content:" (sdContent <$> mdata)-  where formats = map (T.pack . show &&& id) [minBound..maxBound]+  where formats :: [(T.Text,TextFormat)]+        formats = [("Markdown",Markdown),("MediaWiki",MediaWiki),("ReStructuredText",ReStructuredText),("LaTeX",LaTeX),("Textile",Textile),("Source code",Source "" 1),("Plain text",Plain)]         kinds = map (T.pack . show &&& id) [minBound..maxBound] -getEditR :: T.Text -> Int -> WikiHandler Html-getEditR page rid = do+getEditR :: Int -> WikiHandler Html+getEditR rid = do   seg <- liftM getSegment getYesod   pref <- liftM getPrefix getYesod-  (msect, mprec, kind, fmt, suggs) <- lift $ runDB $ do+  (msect, mprec, kind, fmt, suggs, page) <- lift $ runDB $ do     suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]     rel <- get (Key (PersistInt64 $ fromIntegral rid) :: WikirelId)     case rel of-      Nothing -> return (Nothing, Nothing, Error, Plain, suggs)+      Nothing -> return (Nothing, Nothing, Error, Plain, suggs, "none")       Just rel -> do         msect <- get $ wikirelSection rel-        case msect of-          Nothing -> return (Nothing, Nothing, Error, Plain, suggs)-          Just sect ->-            return (Just $ convSect (wikisectionKind sect) (wikisectionFormat sect) (wikisectionContent sect), Just $ wikisectionContent sect, wikisectionKind sect, wikisectionFormat sect, suggs)+        mpage <- get $ wikirelPage rel+        case (msect,mpage) of+          (Nothing,Nothing) -> return (Nothing, Nothing, Error, Plain, suggs, "none")+          (Just sect, Just page) ->+            return (Just $ convSect (wikisectionKind sect) (wikisectionFormat sect) (wikisectionContent sect), Just $ wikisectionContent sect, wikisectionKind sect, wikisectionFormat sect, suggs, wikipageTitle page)   toParent <- getRouteToParent   authR <- lift getAuthR   loggedIn <- lift isLoggedIn   mmsg <- getMessage-  (formw, enctype) <- lift $ generateFormPost $ editSectionForm $ liftM (\t -> SectionData kind fmt $ Textarea t) mprec+  (formw, enctype) <- lift $ generateFormPost $ editSectionForm $ liftM (\t -> SectionData kind (fmtNorm fmt) (fmtLang fmt) (fmtLine fmt) $ Textarea t) mprec   form <- lift $ widgetToPageContent formw+  submitR <- return $ toParent $ EditR rid   lift $ wikiLayout $ do     setTitle $ toHtml page     toWidget $ pageHead form     toWidget $(hamletFile "informative-edit.htm")     toWidget $(cassiusFile "informative.css")++getInsertR :: Int -> WikiHandler Html+getInsertR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  (suggs, page) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    rel <- get (Key (PersistInt64 $ fromIntegral rid) :: WikirelId)+    case rel of+      Nothing -> return (suggs, "none")+      Just rel -> do+        mpage <- get $ wikirelPage rel+        case mpage of+          Nothing -> return (suggs, "none")+          Just page -> return (suggs, wikipageTitle page)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  (formw, enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData Article MediaWiki "haskell" 1 $ Textarea ""+  form <- lift $ widgetToPageContent formw+  submitR <- return $ toParent $ InsertR rid+  msect <- return (Nothing :: Maybe (Either Html [[Html]]))+  kind <- return Article+  lift $ wikiLayout $ do+    setTitle $ toHtml page+    toWidget $ pageHead form+    toWidget $(hamletFile "informative-edit.htm")+    toWidget $(cassiusFile "informative.css")++getPrependR :: Int -> WikiHandler Html+getPrependR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  (suggs, page) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    rel <- get (Key (PersistInt64 $ fromIntegral rid) :: WikirelId)+    case rel of+      Nothing -> return (suggs, "none")+      Just rel -> do+        mpage <- get $ wikirelPage rel+        case mpage of+          Nothing -> return (suggs, "none")+          Just page -> return (suggs, wikipageTitle page)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  (formw, enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData Article MediaWiki "haskell" 1 $ Textarea ""+  form <- lift $ widgetToPageContent formw+  submitR <- return $ toParent $ PrependR rid+  msect <- return (Nothing :: Maybe (Either Html [[Html]]))+  kind <- return Article+  lift $ wikiLayout $ do+    setTitle $ toHtml page+    toWidget $ pageHead form+    toWidget $(hamletFile "informative-edit.htm")+    toWidget $(cassiusFile "informative.css")++getCreateR :: T.Text -> WikiHandler Html+getCreateR page = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  (suggs, exists) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    vs <- selectList [WikipageTitle ==. page] [LimitTo 1]+    return (suggs, not $ null vs)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  (formw, enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData Article MediaWiki "haskell" 1 $ Textarea ("= "<>page<>" =\n\nSome text about "<>page<>".")+  form <- lift $ widgetToPageContent (if exists then [whamlet|<div .error>Page does already exist.|] else formw)+  submitR <- return $ toParent $ CreateR page+  msect <- return (Nothing :: Maybe (Either Html [[Html]]))+  kind <- return Article+  lift $ wikiLayout $ do+    setTitle $ toHtml page+    toWidget $ pageHead form+    toWidget $(hamletFile "informative-edit.htm")+    toWidget $(cassiusFile "informative.css")++postEditR :: Int -> WikiHandler Html+postEditR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  let rid' = Key (PersistInt64 $ fromIntegral rid) :: WikirelId+  (msect, mprec, kind, fmt, suggs, page) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    rel <- get rid'+    case rel of+      Nothing -> return (Nothing, Nothing, Error, Plain, suggs, "none")+      Just rel -> do+        msect <- get $ wikirelSection rel+        mpage <- get $ wikirelPage rel+        case (msect,mpage) of+          (Nothing,Nothing) -> return (Nothing, Nothing, Error, Plain, suggs, "none")+          (Just sect, Just page) ->+            return (Just $ convSect (wikisectionKind sect) (wikisectionFormat sect) (wikisectionContent sect), Just $ wikisectionContent sect, wikisectionKind sect, wikisectionFormat sect, suggs, wikipageTitle page)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  user <- lift getUserName+  now <- liftIO getCurrentTime+  ((result, widget),enctype) <- lift $ runFormPost $ editSectionForm $ liftM (\t -> SectionData kind (fmtNorm fmt) (fmtLang fmt) (fmtLine fmt) $ Textarea t) mprec+  action <- lift $ runInputPost $ id <$> ireq textField "action"+  submitR <- return $ toParent $ EditR rid+  case (result,action) of+    (FormSuccess (SectionData k f lg ln (Textarea c)),"save") -> do+      lift $ runDB $ do+        Right sid <- insertBy $ Wikisection c (source f lg ln) k+        Right pid <- insertBy $ Wikipage page seg user now+        prel <- get rid'+        case prel of+          Nothing -> return ()+          Just prel -> do+            rels <- selectList [WikirelPage ==. wikirelPage prel] [Asc WikirelIndex]+            let nrels = map (\(Entity ri r) -> Wikirel pid (if ri==rid' then sid else wikirelSection r) (wikirelIndex r)) rels+            forM_ nrels insertBy+      setMessage $ toHtml ("Page has been edited." :: T.Text)+      lift $ redirect $ toParent $ ArticleR page+    (FormSuccess (SectionData k f lg ln (Textarea c)),_) -> do+      kind <- return k+      msect <- return $ Just $ convSect k (source f lg ln) c+      mprec <- return $ Just c+      (widget,enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData k f lg ln $ Textarea c+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")+    _ -> do+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")++postInsertR :: Int -> WikiHandler Html+postInsertR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  let rid' = Key (PersistInt64 $ fromIntegral rid) :: WikirelId+  (suggs, page) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    rel <- get rid'+    case rel of+      Nothing -> return (suggs, "none")+      Just rel -> do+        mpage <- get $ wikirelPage rel+        case mpage of+          Nothing -> return (suggs, "none")+          Just page ->+            return (suggs, wikipageTitle page)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  user <- lift getUserName+  now <- liftIO getCurrentTime+  msect <- return (Nothing :: Maybe (Either Html [[Html]]))+  ((result, widget),enctype) <- lift $ runFormPost $ editSectionForm $ Just $ SectionData Article MediaWiki "haskell" 1 $ Textarea ""+  action <- lift $ runInputPost $ id <$> ireq textField "action"+  kind <- return Article+  submitR <- return $ toParent $ InsertR rid+  case (result,action) of+    (FormSuccess (SectionData k f lg ln (Textarea c)),"save") -> do+      lift $ runDB $ do+        Right sid <- insertBy $ Wikisection c (source f lg ln) k+        Right pid <- insertBy $ Wikipage page seg user now+        prel <- get rid'+        case prel of+          Nothing -> return ()+          Just prel -> do+            rels <- selectList [WikirelPage ==. wikirelPage prel] [Asc WikirelIndex]+            let nrels1 = map (\(Entity _ r) -> r) $ takeWhile (\(Entity ri _) -> ri /= rid') rels+                nrels2 = map (\(Entity _ r) -> r) $ drop (length nrels1) rels+                nrels3 = nrels1 ++ [head nrels2] ++ [Wikirel pid sid 0] ++ tail nrels2+                nrels = map (\(i,Wikirel _ s _) -> Wikirel pid s i) $ zip [1..] nrels3+            forM_ nrels insertBy+      setMessage $ toHtml ("Page has been edited." :: T.Text)+      lift $ redirect $ toParent $ ArticleR page+    (FormSuccess (SectionData k f lg ln (Textarea c)),_) -> do+      kind <- return k+      msect <- return $ Just $ convSect k (source f lg ln) c+      mprec <- return $ Just c+      (widget,enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData k f lg ln $ Textarea c+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")+    _ -> do+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")++postPrependR :: Int -> WikiHandler Html+postPrependR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  let rid' = Key (PersistInt64 $ fromIntegral rid) :: WikirelId+  (suggs, page) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    rel <- get rid'+    case rel of+      Nothing -> return (suggs, "none")+      Just rel -> do+        mpage <- get $ wikirelPage rel+        case mpage of+          Nothing -> return (suggs, "none")+          Just page ->+            return (suggs, wikipageTitle page)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  user <- lift getUserName+  now <- liftIO getCurrentTime+  msect <- return (Nothing :: Maybe (Either Html [[Html]]))+  ((result, widget),enctype) <- lift $ runFormPost $ editSectionForm $ Just $ SectionData Article MediaWiki "haskell" 1 $ Textarea ""+  action <- lift $ runInputPost $ id <$> ireq textField "action"+  kind <- return Article+  submitR <- return $ toParent $ PrependR rid+  case (result,action) of+    (FormSuccess (SectionData k f lg ln (Textarea c)),"save") -> do+      lift $ runDB $ do+        Right sid <- insertBy $ Wikisection c (source f lg ln) k+        Right pid <- insertBy $ Wikipage page seg user now+        prel <- get rid'+        case prel of+          Nothing -> return ()+          Just prel -> do+            rels <- selectList [WikirelPage ==. wikirelPage prel] [Asc WikirelIndex]+            let nrels1 = map (\(Entity _ r) -> r) $ takeWhile (\(Entity ri _) -> ri /= rid') rels+                nrels2 = map (\(Entity _ r) -> r) $ drop (length nrels1) rels+                nrels3 = nrels1 ++ [Wikirel pid sid 0] ++ nrels2+                nrels = map (\(i,Wikirel _ s _) -> Wikirel pid s i) $ zip [1..] nrels3+            forM_ nrels insertBy+      setMessage $ toHtml ("Page has been edited." :: T.Text)+      lift $ redirect $ toParent $ ArticleR page+    (FormSuccess (SectionData k f lg ln (Textarea c)),_) -> do+      kind <- return k+      msect <- return $ Just $ convSect k (source f lg ln) c+      mprec <- return $ Just c+      (widget,enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData k f lg ln $ Textarea c+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")+    _ -> do+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")++postCreateR :: T.Text -> WikiHandler Html+postCreateR page = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  (suggs, exists) <- lift $ runDB $ do+    suggs <- selectList [WikisuggSegment ==. seg] [Asc WikisuggIndex]+    vs <- selectList [WikipageTitle ==. page] [LimitTo 1]+    return (suggs, not $ null vs)+  toParent <- getRouteToParent+  authR <- lift getAuthR+  loggedIn <- lift isLoggedIn+  mmsg <- getMessage+  user <- lift getUserName+  now <- liftIO getCurrentTime+  msect <- return (Nothing :: Maybe (Either Html [[Html]]))+  ((result, widget),enctype) <- lift $ runFormPost $ editSectionForm $ Just $ SectionData Article MediaWiki "haskell" 1 $ Textarea ""+  action <- lift $ runInputPost $ id <$> ireq textField "action"+  kind <- return Article+  submitR <- return $ toParent $ CreateR page+  case (exists,result,action) of+    (False,FormSuccess (SectionData k f lg ln (Textarea c)),"save") -> do+      lift $ runDB $ do+        Right sid <- insertBy $ Wikisection c (source f lg ln) k+        Right pid <- insertBy $ Wikipage page seg user now+        insertBy $ Wikirel pid sid 1+      setMessage $ toHtml ("Page has been created." :: T.Text)+      lift $ redirect $ toParent $ ArticleR page+    (False,FormSuccess (SectionData k f lg ln (Textarea c)),_) -> do+      kind <- return k+      msect <- return $ Just $ convSect k (source f lg ln) c+      mprec <- return $ Just c+      (widget,enctype) <- lift $ generateFormPost $ editSectionForm $ Just $ SectionData k f lg ln $ Textarea c+      form <- lift $ widgetToPageContent widget+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")+    _ -> do+      form <- lift $ widgetToPageContent (if exists then [whamlet|<div .error>Page does already exist.|] else widget)+      lift $ wikiLayout $ do+        setTitle $ toHtml page+        toWidget $ pageHead form+        toWidget $(hamletFile "informative-edit.htm")+        toWidget $(cassiusFile "informative.css")++postDownR :: Int -> WikiHandler Html+postDownR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  user <- lift getUserName+  now <- liftIO getCurrentTime+  toParent <- getRouteToParent+  let rid' = Key (PersistInt64 $ fromIntegral rid) :: WikirelId+  page <- lift $ runDB $ do+    rel <- get rid'+    case rel of+      Nothing -> return "none"+      Just rel -> do+        page <- get $ wikirelPage rel+        case page of+          Nothing -> return "none"+          Just page -> do+            Right pid <- insertBy $ Wikipage (wikipageTitle page) seg user now+            rels <- selectList [WikirelPage ==. wikirelPage rel] [Asc WikirelIndex]+            let swap [Entity _ r] = [r]+                swap [] = []+                swap (Entity ri1 r1:Entity _ r2:rs)+                  | ri1 == rid' = r1{wikirelIndex=wikirelIndex r2}:r2{wikirelIndex=wikirelIndex r1}:swap rs+                swap (Entity _ r:rs) = r:swap rs+            forM (swap rels) $ \r -> insertBy r{wikirelPage=pid}+            return $ wikipageTitle page+  lift $ redirect $ toParent $ ArticleR page++postUpR :: Int -> WikiHandler Html+postUpR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  user <- lift getUserName+  now <- liftIO getCurrentTime+  toParent <- getRouteToParent+  let rid' = Key (PersistInt64 $ fromIntegral rid) :: WikirelId+  page <- lift $ runDB $ do+    rel <- get rid'+    case rel of+      Nothing -> return "none"+      Just rel -> do+        page <- get $ wikirelPage rel+        case page of+          Nothing -> return "none"+          Just page -> do+            Right pid <- insertBy $ Wikipage (wikipageTitle page) seg user now+            rels <- selectList [WikirelPage ==. wikirelPage rel] [Asc WikirelIndex]+            let swap [Entity _ r] = [r]+                swap [] = []+                swap (Entity _ r1:Entity ri2 r2:rs)+                  | ri2 == rid' = r1{wikirelIndex=wikirelIndex r2}:r2{wikirelIndex=wikirelIndex r1}:swap rs+                swap (Entity _ r:rs) = r:swap rs+            forM (swap rels) $ \r -> insertBy r{wikirelPage=pid}+            return $ wikipageTitle page+  lift $ redirect $ toParent $ ArticleR page++postDeleteR :: Int -> WikiHandler Html+postDeleteR rid = do+  seg <- liftM getSegment getYesod+  pref <- liftM getPrefix getYesod+  user <- lift getUserName+  now <- liftIO getCurrentTime+  toParent <- getRouteToParent+  let rid' = Key (PersistInt64 $ fromIntegral rid) :: WikirelId+  page <- lift $ runDB $ do+    rel <- get rid'+    case rel of+      Nothing -> return "none"+      Just rel -> do+        page <- get $ wikirelPage rel+        case page of+          Nothing -> return "none"+          Just page -> do+            Right pid <- insertBy $ Wikipage (wikipageTitle page) seg user now+            rels <- selectList [WikirelPage ==. wikirelPage rel] [Asc WikirelIndex]+            let nrels = map (\(Entity _ r) -> r) $ filter (\(Entity ri _) -> ri /=  rid') rels+            forM nrels $ \r -> insertBy r{wikirelPage=pid}+            return $ wikipageTitle page+  lift $ redirect $ toParent $ ArticleR page  instance (YesodWikiAuth master, YesodPersist master, YesodPersistBackend master ~ SqlPersistT) => YesodSubDispatch Informative (HandlerT master IO) where   yesodSubDispatch = $(mkYesodSubDispatch resourcesInformative)
Web/Informative/Data.hs view
@@ -10,10 +10,16 @@ mkYesodSubData "Informative" [parseRoutes|  /article/#Text ArticleR GET  /articleid/#Int ArticleIdR GET- /edit/#Text/#Int EditR GET+ /edit/#Int EditR GET POST+ /insert/#Int InsertR GET POST+ /prepend/#Int PrependR GET POST+ /down/#Int DownR POST+ /up/#Int UpR POST+ /delete/#Int DeleteR POST+ /create/#Text CreateR GET POST |] -data TextFormat = Markdown | MediaWiki | ReStructuredText | LaTeX | Plain deriving (Eq,Ord,Show,Read, Enum, Bounded)+data TextFormat = Markdown | MediaWiki | ReStructuredText | LaTeX | Textile | Source Text Int | Plain deriving (Eq,Ord,Show,Read) derivePersistField "TextFormat"  data TextKind = Article | Table | Mapping | Hint | Error deriving (Eq, Ord, Show, Read, Enum, Bounded)
informative-edit.htm view
@@ -23,7 +23,7 @@       $of (Left c, Hint)         <div .hint>           #{c}-      $of (Left c, Error)+      $of (Left c, _)         <div .error>           #{c}       $of (Right [], _)@@ -46,12 +46,9 @@               <tr>                 $forall c <- cols                   <td>#{c}-  $nothing-    <div .hint>-      You are creating a new section.   <div .content>     <p>-      <form method=post action=@{toParent $ EditR page rid} enctype=#{enctype}>+      <form method=post action=@{submitR} enctype=#{enctype}>         ^{pageBody form}         <button type="submit" name="action" value="save">Save         <button type="submit" name="action" value="preview" default>Preview
informative-test.hs view
@@ -22,7 +22,7 @@ instance Yesod Master where   authRoute _ = Just $ AuthR LoginR   isAuthorized (SubsiteR _) True = mayWrite-  isAuthorized (SubsiteR (EditR _ _)) _ = mayWrite+  isAuthorized (SubsiteR (EditR _)) _ = mayWrite   isAuthorized _ _ = return Authorized  mayWrite = do
informative.cabal view
@@ -10,7 +10,7 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.1.0.3+version:             0.1.0.4  -- A short (one-line) description of the package. synopsis:            A yesod subsite serving a wiki.@@ -59,7 +59,7 @@   -- other-extensions:          -- Other library packages from which modules are imported.-  build-depends:       base >=4.6 && <4.8, yesod >=1.2 && <1.3, text >=1.1 && <1.2, persistent-postgresql >=1.3 && <1.4, monad-logger >=0.3 && <0.4, persistent >=1.3 && <1.4, pandoc >=1.10, shakespeare >=2.0 && <2.1, time >=1.4 && <1.5, old-locale >= 1.0, csv >=0.1 && <0.2, yesod-auth >=1.3 && <1.4, http-conduit >=2.1 && <2.2, yesod-core >=1.2 && <1.3, yesod-form >=1.3 && <1.4+  build-depends:       base >=4.6 && <4.8, yesod >=1.2 && <1.3, text >=1.1 && <1.2, persistent-postgresql >=1.3 && <1.4, monad-logger >=0.3 && <0.4, persistent >=1.3 && <1.4, pandoc >=1.10, shakespeare >=2.0 && <2.1, time >=1.4 && <1.5, old-locale >= 1.0, csv >=0.1 && <0.2, yesod-auth >=1.3 && <1.4, http-conduit >=2.1 && <2.2, yesod-core >=1.2 && <1.3, yesod-form >=1.3 && <1.4, highlighting-kate >=0.5 && <0.6      -- Directories containing source files.   -- hs-source-dirs:      @@ -68,6 +68,6 @@   default-language:    Haskell2010    executable informative-test-  build-depends:       base >=4.6 && <4.8, yesod >=1.2 && <1.3, text >=1.1 && <1.2, persistent-postgresql >=1.3 && <1.4, monad-logger >=0.3 && <0.4, persistent >=1.3 && <1.4, pandoc >=1.10, shakespeare >=2.0 && <2.1, time >=1.4 && <1.5, old-locale >= 1.0, csv >=0.1 && <0.2, yesod-auth >=1.3 && <1.4, http-conduit >=2.1 && <2.2, yesod-core >=1.2 && <1.3, yesod-form >=1.3 && <1.4+  build-depends:       base >=4.6 && <4.8, yesod >=1.2 && <1.3, text >=1.1 && <1.2, persistent-postgresql >=1.3 && <1.4, monad-logger >=0.3 && <0.4, persistent >=1.3 && <1.4, pandoc >=1.10, shakespeare >=2.0 && <2.1, time >=1.4 && <1.5, old-locale >= 1.0, csv >=0.1 && <0.2, yesod-auth >=1.3 && <1.4, http-conduit >=2.1 && <2.2, yesod-core >=1.2 && <1.3, yesod-form >=1.3 && <1.4, highlighting-kate >=0.5 && <0.6   main-is:             informative-test.hs   default-language:    Haskell2010
informative.css view
@@ -131,16 +131,18 @@ div.table table p, div.mapping table p   margin: 0px; -div#content a+div#content a, div#content button.linkbutton   color: black;   text-decoration: none;+  border: none;+  background: none;  div#content div.content a:before, div#content div.table a:before, div#content div.mapping a:before   color: navy;   content: '->';   font-size: 11px; -div#content a:hover+div#content a:hover, div#content button.linkbutton:hover   text-decoration: underline;  div#content div.edit@@ -150,9 +152,21 @@   font-style: italic;   margin-top: -0.3cm; -div#content div.edit a+div#content div.edit a, div#content div.edit button.linkbutton   color: navy;+  display: inline;+  font-style: italic;+  font-size: 13px;+  margin: 0px;+  padding: 0px;+  cursor: pointer; +div#content div.edit form+  display: inline;+  margin: 0px;+  padding: 0px;+  border: none;+ textarea   width: 100em;   height: 30em;@@ -160,3 +174,71 @@ label   width: 10em;   float: left;++span.kw+  font-weight: bold+  +span.dt+  color: teal++span.dv, span.bn, span.fl, span.ch, span.st+  color: navy++span.co+  color: green++code.sourceCode+  display: block;+  border: 1px solid navy;+  background-color: #dddddd;+  padding: 4px;+  margin-right: 3px;++code.cs, code.source-cs+  background-color: #ffdddd+  color: purple+  border: 1px solid maroon;++code.cs span.co, code.cs span.dv, code.cs span.fl, code.cs span.ch, code.cs span.st, code.cs span.dt, code.source-cs span.co, code.source-cs span.dv, code.source-cs span.fl, code.source-cs span.ch, code.source-cs span.st, code.source-cs span.dt+  color: maroon++code.cs span.co:after, code.source-cs span.co:after+  content: '/\* I\'m a barbie girl in a barbie world \\o/ \*/';++code.php code.source-php+  background-color: #ffddff+  color: maroon+  border: 1px solid purple;++code.php span.co, code.php span.dv, code.php span.fl, code.php span.ch, code.php span.st, code.php span.dt, code.source-php span.co, code.source-php span.dv, code.source-php span.fl, code.source-php span.ch, code.source-php span.st, code.source-php span.dt+  color: purple++pre.haskell:before, pre.source-haskell:before+  content: 'Haskell';+  display: inline;+  border: 1px solid navy;+  padding: 2px;+  background-color: navy;+  color: yellow;+  border-bottom: none+  padding-bottom: 0px;++pre.php:before, pre.source-php:before+  content: 'PHP';+  display: inline;+  border: 1px solid purple;+  padding: 2px;+  background-color: purple;+  color: white;+  border-bottom: none+  padding-bottom: 0px;++pre.cs:before, pre.source-cs:before+  content: 'C#';+  display: inline;+  border: 1px solid maroon;+  padding: 2px;+  background-color: maroon;+  color: white;+  border-bottom: none+  padding-bottom: 0px;
informative.htm view
@@ -15,6 +15,11 @@   $maybe msg <- mmsg     <div .hint>       #{msg}+  $if not (null sects)+    $with (idx, (rid, sect, kind)) <- head sects+      $if ((mayEdit == Authorized) && (rid >= 0))+        <div .edit>+          <a href=@{toParent $ PrependR $ fromIntegral rid}>insert   $forall (idx, (rid, sect, kind)) <- sects     $case (sect, kind)       $of (Left c, Article)@@ -23,7 +28,7 @@       $of (Left c, Hint)         <div .hint>           #{c}-      $of (Left c, Error)+      $of (Left c, _)         <div .error>           #{c}       $of (Right [], _)@@ -46,14 +51,22 @@               <tr>                 $forall c <- cols                   <td>#{c}+    $if ((mayEdit == Authorized) && (rid < 0))+      <div .edit>+        <a href=@{toParent $ CreateR page}>create     $if ((mayEdit == Authorized) && (rid >= 0))       <div .edit>         $if idx > 1-          <a href=@{toParent $ EditR page $ fromIntegral rid}>up+          <form method=post action=@{toParent $ UpR $ fromIntegral rid}>+            <button .linkbutton>up         $if idx < length sects-          <a href=@{toParent $ EditR page $ fromIntegral rid}>down-        <a href=@{toParent $ EditR page $ fromIntegral rid}>insert-        <a href=@{toParent $ EditR page $ fromIntegral rid}>edit+          <form method=post action=@{toParent $ DownR $ fromIntegral rid}>+            <button .linkbutton>down+        $if length sects > 1+          <form method=post action=@{toParent $ DeleteR $ fromIntegral rid}>+            <button .linkbutton>delete+        <a href=@{toParent $ InsertR $ fromIntegral rid}>insert+        <a href=@{toParent $ EditR $ fromIntegral rid}>edit   <div .table>     <table>       <thead>