]> gitweb @ CieloNegro.org - Rakka.git/commitdiff
we can now create new pages
authorpho <pho@cielonegro.org>
Sun, 16 Dec 2007 06:26:52 +0000 (15:26 +0900)
committerpho <pho@cielonegro.org>
Sun, 16 Dec 2007 06:26:52 +0000 (15:26 +0900)
darcs-hash:20071216062652-62b54-61857b2af474cb50fc497e41d96b630cd838523e.gz

Rakka/Storage/Repos.hs
Rakka/Wiki/Interpreter/Base.hs
defaultPages/SideBar/Right.xml
js/editPage.js
schemas/rakka-page-1.0.rng

index 81ab87611b68a51422aabb22e60fb7ea5fe30e83..0b53568b4290e9b0d433d71a291fbf1fec9b35d1 100644 (file)
@@ -6,6 +6,7 @@ module Rakka.Storage.Repos
     )
     where
 
+import           Control.Exception
 import           Control.Monad
 import           Data.List
 import qualified Data.Map as M
@@ -18,19 +19,20 @@ import           Rakka.Page
 import           Rakka.SystemConfig
 import           Rakka.Utils
 import           Rakka.W3CDateTime
-import           Subversion.Types
+import           Subversion.Error
 import           Subversion.FileSystem
 import           Subversion.FileSystem.DirEntry
 import           Subversion.FileSystem.Revision
 import           Subversion.FileSystem.Root
 import           Subversion.FileSystem.Transaction
 import           Subversion.Repository
+import           Subversion.Types
 import           System.FilePath.Posix
 
 
 mkPagePath :: PageName -> FilePath
 mkPagePath name
-    = "pages" </> encodePageName name <.> "page"
+    = "/pages" </> encodePageName name <.> "page"
 
 
 findAllPagesInRevision :: Repository -> RevNum -> IO (Set PageName)
@@ -151,44 +153,49 @@ loadPageInRepository repos name rev
 
 putPageIntoRepository :: Repository -> Page -> IO StatusCode
 putPageIntoRepository repos page
-    = do let Just ui = pageUpdateInfo page
-             name    = pageName page
-         ret <- doReposTxn
-                repos
-                (uiOldRevision ui)
-                "[Rakka]"
-                (Just "Automatic commit by Rakka for page updating")
-                $ do case uiOldName ui of
-                       Nothing      -> return ()
-                       Just oldName -> renamePage oldName name
-                     createPageIfNeeded name
-                     updatePage name
+    = filterSvnError $
+      do let name = pageName page
+         ret <- case pageUpdateInfo page of
+                  Just ui
+                      -> doReposTxn
+                         repos
+                         (uiOldRevision ui)
+                         "[Rakka]"
+                         (Just "Automatic commit by Rakka for page update")
+                         $ do case uiOldName ui of
+                                Nothing      -> return ()
+                                Just oldName -> renamePage oldName name
+                              updatePage name
+                  Nothing
+                      -> do fs  <- getRepositoryFS repos
+                            rev <- getYoungestRev fs
+                            doReposTxn repos
+                                         rev
+                                         "[Rakka]"
+                                         (Just "Automatic commit by Rakka for page creation")
+                                         $ do createPage name
+                                              updatePage name
          case ret of
-           Left _ ->
-               return Conflict
-           Right _ ->
-               return Created
+           Left  _ -> return Conflict
+           Right _ -> return Created
     where
       renamePage :: PageName -> PageName -> Txn ()
       renamePage oldName newName
           = fail "FIXME: renamePage: not implemented yet"
 
-      createPageIfNeeded :: PageName -> Txn ()
-      createPageIfNeeded name
+      createPage :: PageName -> Txn ()
+      createPage name
           = do let path = mkPagePath name
-               kind <- checkPath path
-               case kind of
-                 NoNode   -> do createParentDirectories path
-                                makeFile path
-                 FileNode -> return ()
-                 DirNode  -> fail ("createPageIfNeeded: already exists a directory: " ++ path)
+               createParentDirectories path
+               makeFile path
 
       createParentDirectories :: FilePath -> Txn ()
       createParentDirectories path
           = do let parentPath = takeDirectory path
                kind <- checkPath parentPath
                case kind of
-                 NoNode   -> createParentDirectories parentPath
+                 NoNode   -> do createParentDirectories parentPath
+                                makeDirectory parentPath
                  FileNode -> fail ("createParentDirectories: already exists a file: " ++ parentPath)
                  DirNode  -> return ()
 
@@ -225,3 +232,14 @@ putPageIntoRepository repos page
       encodeFlag :: Bool -> Maybe String
       encodeFlag True  = Just "*\n"
       encodeFlag False = Nothing
+
+
+filterSvnError :: IO a -> IO a
+filterSvnError f = catchDyn f rethrow
+    where
+      rethrow :: SvnError -> IO a
+      rethrow err
+          = let code = svnErrCode err
+                msg  = svnErrMsg  err
+            in
+              fail $ "SvnError: " ++ (show code) ++ ": " ++ msg
index 70951e6884ab1d43936d0d830d35e41e3ac16a50..6feb92a77c82dcec77157cf3f0bff2929328a06f 100644 (file)
@@ -23,6 +23,7 @@ interpreters = [ lineBreakInterp
                , divInterp
                , pageNameInterp
                , otherLangsInterp
+               , newPageInterp
                , editPageInterp
                ]
 
@@ -100,6 +101,30 @@ otherLangsInterp
           = [Inline (PageLink (Just name) Nothing (Just langName))]
 
 
+-- <input type="button"
+--        value="Create new page"
+--        onclick="Rakka.newPage(\"http://example.org/\")"
+--        class="newButton" />
+newPageInterp :: Interpreter
+newPageInterp 
+    = InlineCommandInterpreter {
+        iciName      = "newPage"
+      , iciInterpret
+          = \ ctx (InlineCommand _ args _) ->
+            do BaseURI baseURI <- getSysConf (ctxSysConf ctx)
+               
+               let label = fromMaybe "Create new page" (lookup "label" args)
+                   uri   = uriToString id baseURI ""
+                   attrs = [ ("type"   , "button")
+                           , ("value"  , label)
+                           , ("onclick", "Rakka.newPage(\"" ++ uri ++ "\")")
+                           , ("class"  , "newButton")
+                           ]
+
+               return (Input attrs)
+      }
+
+
 -- <input type="button"
 --        value="Edit"
 --        onclick="Rakka.editPage(\"http://example.org/\", \"Foo\")"
index c43cef15a8f654edfe003d553907b56803c01c95..41699d1605238f155f772579142f6c3991f5d0f2 100644 (file)
@@ -4,6 +4,7 @@
       isBoring="yes">
   <textData><![CDATA[
 = Control =
+* <newPage />
 * <editPage />
 
 = In other languages =
index 0eb211edaff0ee9a793f9ee0e3305e2b0fb96303..43dc7766f5397a7874a63ac5b62cb6ae1cee111b 100644 (file)
@@ -33,11 +33,15 @@ Rakka.editPage = function (baseURI, pageName) {
     });
 };
 
+Rakka.newPage = function (baseURI) {
+    Rakka.displayPageEditor(baseURI, "", null, "rakka", null);
+};
+
 Rakka.displayPageEditor = function (baseURI, pageName, oldRevision, defaultType, source) {
     var $area = Rakka.switchScreen();
     $area.empty();
 
-    $area.append($.H1({}, "Edit page"));
+    $area.append($.H1({}, pageName == "" ? "Create page" : "Edit page"));
 
     var fldPageName
         = $.INPUT({type : "text", value: pageName});
index 29e4036aa012744ed8487b4346ca88ef3cb5448e..64660404f2279ec5ea0fb5b4409165fc97898396 100644 (file)
       <optional>
         <!-- text/css でなければ無視される -->
         <attribute name="isTheme">
-          <!-- これは HXT が對應してゐない。
-               <data type="string">
-               <param name="pattern">yes|no</param>
-               </data>
-          -->
-          <text />
+          <choice>
+            <value>yes</value>
+            <value>no</value>
+          </choice>
         </attribute>
       </optional>
 
       <optional>
         <!-- text/x-rakka でなければ無視される -->
         <attribute name="isFeed">
-          <!-- yes/no -->
-          <text />
+          <choice>
+            <value>yes</value>
+            <value>no</value>
+          </choice>
         </attribute>
       </optional>
 
       <optional>
         <!-- ログインしてゐないユーザーの編集を禁止するフラグ -->
         <attribute name="isLocked">
-          <!-- yes/no -->
-          <text />
+          <choice>
+            <value>yes</value>
+            <value>no</value>
+          </choice>
         </attribute>
       </optional>
 
       <optional>
         <!-- 更新履歴や RSS から削除されるフラグ -->
         <attribute name="isBoring">
-          <!-- yes/no -->
-          <text />
+          <choice>
+            <value>yes</value>
+            <value>no</value>
+          </choice>
         </attribute>
       </optional>