]> gitweb.factorcode.org Git - factor.git/commitdiff
Better support for rest parameters on URLs
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 12 Jun 2008 23:54:50 +0000 (18:54 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Thu, 12 Jun 2008 23:54:50 +0000 (18:54 -0500)
14 files changed:
extra/furnace/furnace.factor
extra/webapps/blogs/blogs.factor
extra/webapps/blogs/edit-post.xml
extra/webapps/blogs/list-posts.xml
extra/webapps/blogs/user-posts.xml
extra/webapps/blogs/view-post.xml
extra/webapps/wiki/articles.xml
extra/webapps/wiki/changes.xml
extra/webapps/wiki/diff.xml
extra/webapps/wiki/page-common.xml
extra/webapps/wiki/revisions.xml
extra/webapps/wiki/user-edits.xml
extra/webapps/wiki/view.xml
extra/webapps/wiki/wiki.factor

index 99ccf33eec83b555c35c53de6e5f220557399a76..6ddd84a2545478012a3f524f1b81741e49029d6e 100644 (file)
@@ -97,15 +97,21 @@ SYMBOL: exit-continuation
     dup empty?
     [ drop f ] [ "," split [ dup value ] H{ } map>assoc ] if ;
 
-CHLOE: atom
-    [ children>string ]
-    [ "href" required-attr ]
-    [ "query" optional-attr parse-query-attr ] tri
-    <url>
-        swap >>query
-        swap >>path
-    adjust-url relative-to-request
-    add-atom-feed ;
+: a-url-path ( tag -- string )
+    [ "href" required-attr ] [ "rest" optional-attr value ] bi
+    [ [ "/" ?tail drop "/" ] dip present 3append ] when* ;
+
+: a-url ( tag -- url )
+    dup "value" optional-attr [ ] [
+        <url>
+            swap
+            [ a-url-path >>path ]
+            [ "query" optional-attr parse-query-attr >>query ]
+            bi
+    ] ?if
+    adjust-url relative-to-request ;
+
+CHLOE: atom [ children>string ] [ a-url ] bi add-atom-feed ;
 
 CHLOE: write-atom drop write-atom-feeds ;
 
@@ -114,23 +120,11 @@ GENERIC: link-attr ( tag responder -- )
 M: object link-attr 2drop ;
 
 : link-attrs ( tag -- )
+    #! Side-effects current namespace.
     '[ , _ link-attr ] each-responder ;
 
 : a-start-tag ( tag -- )
-    [
-        <a
-            dup link-attrs
-            dup "value" optional-attr [ value f ] [
-                [ "href" required-attr ]
-                [ "query" optional-attr parse-query-attr ]
-                bi
-            ] ?if
-            <url>
-                swap >>query
-                swap >>path
-            adjust-url relative-to-request =href
-        a>
-    ] with-scope ;
+    [ <a [ link-attrs ] [ a-url =href ] bi a> ] with-scope ;
 
 CHLOE: a
     [ a-start-tag ]
@@ -158,11 +152,12 @@ CHLOE: a
     [
         [
             <form
-                "POST" =method
-                [ link-attrs ]
-                [ "action" required-attr resolve-base-path =action ]
-                [ tag-attrs non-chloe-attrs-only print-attrs ]
-                tri
+                {
+                    [ link-attrs ]
+                    [ "method" optional-attr "post" or =method ]
+                    [ "action" required-attr resolve-base-path =action ]
+                    [ tag-attrs non-chloe-attrs-only print-attrs ]
+                } cleave
             form>
         ]
         [ form-magic ] bi
index 8dbf7db6901ffafa7d29bc92c04974cde8a03de8..882584f014192d8a0e98e73af1dbe77ea52b4ce4 100644 (file)
@@ -164,6 +164,8 @@ M: comment entity-url
 
 : <edit-post-action> ( -- action )
     <page-action>
+        "id" >>rest
+
         [
             validate-integer-id
             "id" value <post> select-tuple from-object
index da88a78ab08cc6efeeed3a7b67b0ac45658e1245..4522f8606bb3d34aab174ee38c7c6cb8ceb1d0e8 100644 (file)
 
        <div class="posting-footer">
                Post by
-               <t:a t:href="$blogs/" t:query="author">
+               <t:a t:href="$blogs/by" t:rest="author">
                        <t:label t:name="author" />
                </t:a>
                on
                <t:label t:name="date" />
                |
-               <t:a t:href="$blogs/post" t:for="id">View Post</t:a>
+               <t:a t:href="$blogs/post" t:rest="id">View Post</t:a>
                |
                <t:button t:action="$blogs/delete-post" t:for="id,author" class="link-button link">Delete Post</t:button>
        </div>
index 9c9685fe747fdb462c6341106d61674d325fe81f..94a5a69775d0f2cfbdab10a0c908fcd2afabacc1 100644 (file)
@@ -7,7 +7,7 @@
        <t:bind-each t:name="posts">
 
                <h2 class="post-title">
-                       <t:a t:href="$blogs/post" t:query="id">
+                       <t:a t:href="$blogs/post" t:rest="id">
                                <t:label t:name="title" />
                        </t:a>
                </h2>
 
                <div class="posting-footer">
                        Post by
-                       <t:a t:href="$blogs/by" t:query="author">
+                       <t:a t:href="$blogs/by" t:rest="author">
                                <t:label t:name="author" />
                        </t:a>
                        on
                        <t:label t:name="date" />
                        |
-                       <t:a t:href="$blogs/post" t:query="id">
+                       <t:a t:href="$blogs/post" t:rest="id">
                                <t:label t:name="comments" />
                                comments.
                        </t:a>
index 95fae23b34ff945852d42ec4b11db9ea9b36a5ad..d94b598fc0e8c0d57e38f53fc766e2e792c9b8d4 100644 (file)
@@ -2,7 +2,7 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
-       <t:atom t:href="$blogs/by" t:query="author">
+       <t:atom t:href="$blogs/by" t:rest="author">
                Recent Posts by <t:label t:name="author" />
        </t:atom>
 
@@ -13,7 +13,7 @@
        <t:bind-each t:name="posts">
 
                <h2 class="post-title">
-                       <t:a t:href="$blogs/post" t:query="id">
+                       <t:a t:href="$blogs/post" t:rest="id">
                                <t:label t:name="title" />
                        </t:a>
                </h2>
 
                <div class="posting-footer">
                        Post by
-                       <t:a t:href="$blogs/by" t:query="author">
+                       <t:a t:href="$blogs/by" t:rest="author">
                                <t:label t:name="author" />
                        </t:a>
                        on
                        <t:label t:name="date" />
                        |
-                       <t:a t:href="$blogs/post" t:query="id">
+                       <t:a t:href="$blogs/post" t:rest="id">
                                <t:label t:name="comments" />
                                comments.
                        </t:a>
index 23bf51394629b7f31723de5ce049d206b268971c..fae9ff3e769eb9d77c4e10da57af9e567f95a1a7 100644 (file)
@@ -2,11 +2,11 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
-       <t:atom t:href="$blogs/post.atom" t:query="id">
+       <t:atom t:href="$blogs/post.atom" t:rest="id">
                <t:label t:name="author" />: <t:label t:name="title" />
        </t:atom>
 
-       <t:atom t:href="$blogs/by.atom" t:query="author">
+       <t:atom t:href="$blogs/by.atom" t:rest="author">
                Recent Posts by <t:label t:name="author" />
        </t:atom>
 
 
        <div class="posting-footer">
                Post by
-               <t:a t:href="$blogs/" t:query="author">
+               <t:a t:href="$blogs/" t:rest="author">
                        <t:label t:name="author" />
                </t:a>
                on
                <t:label t:name="date" />
                |
-               <t:a t:href="$blogs/edit-post" t:query="id">Edit Post</t:a>
+               <t:a t:href="$blogs/edit-post" t:rest="id">Edit Post</t:a>
                |
                <t:button t:action="$blogs/delete-post" t:for="id,author" class="link-button link">Delete Post</t:button>
        </div>
index e19c531d3d383ecf052af6bfa9e6895ac2142bf1..9b2ae930fbca7ec0c247cfd8f384c31fd65b4e9a 100644 (file)
@@ -7,7 +7,7 @@
        <ul>
                <t:bind-each t:name="articles">
                        <li>
-                               <t:a t:href="view" t:query="title"><t:label t:name="title"/></t:a>
+                               <t:a t:href="$wiki/view" t:rest="title"><t:label t:name="title"/></t:a>
                        </li>
                </t:bind-each>
        </ul>
index 5b3e9de2c4f914a292087228a0d7b114055d07cd..1515c4924a35c251dc1cb2b19a2795a59114de57 100644 (file)
@@ -4,16 +4,26 @@
 
        <t:title>Recent Changes</t:title>
 
-       <ul>
-               <t:bind-each t:name="changes">
-                       <li>
-                               <t:a t:href="view" t:query="title"><t:label t:name="title" /></t:a>
-                               on
-                               <t:a t:href="revision" t:query="id"><t:label t:name="date" /></t:a>
-                               by
-                               <t:a t:href="user-edits" t:query="author"><t:label t:name="author" /></t:a>
-                       </li>
-               </t:bind-each>
-       </ul>
+       <div class="revisions">
+
+               <table>
+
+                       <tr>
+                               <th>Article</th>
+                               <th>Date</th>
+                               <th>By</th>
+                       </tr>
+
+                       <t:bind-each t:name="changes">
+                               <tr>
+                                       <td><t:a t:href="$wiki/view" t:rest="title"><t:label t:name="title" /></t:a></td>
+                                       <td><t:a t:href="$wiki/revision" t:rest="id"><t:label t:name="date" /></t:a></td>
+                                       <td><t:a t:href="$wiki/user-edits" t:rest="author"><t:label t:name="author" /></t:a></td>
+                               </tr>
+                       </t:bind-each>
+
+               </table>
+
+       </div>
 
 </t:chloe>
index 35afe51b66dd66bf4974970e81fd25411f6eabf0..9d65531eb0ad4725f53b1a18feaf014a5ccbf990 100644 (file)
@@ -8,13 +8,13 @@
                <tr>
                        <th class="field-label">Old revision:</th>
                        <t:bind t:name="old">
-                               <td>Created on <t:label t:name="date" /> by <t:a t:href="user-edits" t:query="author"><t:label t:name="author" /></t:a>.</td>
+                               <td>Created on <t:label t:name="date" /> by <t:a t:href="user-edits" t:rest="author"><t:label t:name="author" /></t:a>.</td>
                        </t:bind>
                </tr>
                <tr>
                        <th class="field-label">New revision:</th>
                        <t:bind t:name="old">
-                               <td>Created on <t:label t:name="date" /> by <t:a t:href="user-edits" t:query="author"><t:label t:name="author" /></t:a>.</td>
+                               <td>Created on <t:label t:name="date" /> by <t:a t:href="user-edits" t:rest="author"><t:label t:name="author" /></t:a>.</td>
                        </t:bind>
                </tr>
        </table>
index 675cb8cd65747bee5fe119ce9c7a03d07d788dcb..0d029946f89ac18a593b9ec311bb32264261a379 100644 (file)
@@ -2,16 +2,16 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
-       <t:atom t:href="$wiki/revisions.atom" t:query="title">
+       <t:atom t:href="$wiki/revisions.atom" t:rest="title">
                Revisions of <t:label t:name="title" />
        </t:atom>
 
        <t:call-next-template />
 
        <div class="navbar">
-               <t:a t:href="$wiki/view" t:query="title">Latest</t:a>
-               | <t:a t:href="$wiki/revisions" t:query="title">Revisions</t:a>
-               | <t:a t:href="$wiki/edit" t:query="title">Edit</t:a>
+               <t:a t:href="$wiki/view" t:rest="title">Latest</t:a>
+               | <t:a t:href="$wiki/revisions" t:rest="title">Revisions</t:a>
+               | <t:a t:href="$wiki/edit" t:rest="title">Edit</t:a>
                | <t:button t:action="$wiki/delete" t:for="title" class="link-button link">Delete</t:button>
        </div>
 
index 2a909e6ab3a017680bd2eb26a2f757f12456c7f2..97a051cd96d95874ee0b5f6f1abe8bc9fe1ab15a 100644 (file)
@@ -8,14 +8,14 @@
                <table>
                        <tr>
                                <th>Revision</th>
-                               <th>Author</th>
+                               <th>By</th>
                                <th>Rollback</th>
                        </tr>
 
                        <t:bind-each t:name="revisions">
                                <tr>
-                                       <td> <t:a t:href="revision" t:query="id"><t:label t:name="date" /></t:a> </td>
-                                       <td> <t:a t:href="user-edits" t:query="author"><t:label t:name="author" /></t:a> </td>
+                                       <td> <t:a t:href="$wiki/revision" t:rest="id"><t:label t:name="date" /></t:a> </td>
+                                       <td> <t:a t:href="$wiki/user-edits" t:rest="author"><t:label t:name="author" /></t:a> </td>
                                        <td> <t:button t:action="rollback" t:for="id" class="link link-button">Rollback</t:button> </td>
                                </tr>
                        </t:bind-each>
@@ -24,7 +24,7 @@
 
        <h2>View Differences</h2>
 
-       <form action="diff" method="get">
+       <t:form t:action="$wiki/diff" t:method="get">
                <table>
                        <tr>
                                <th class="field-label">Old revision:</th>
@@ -51,6 +51,6 @@
                </table>
 
                <input type="submit" value="View" />
-       </form>
+       </t:form>
 
 </t:chloe>
index 6f22982f126265d269970ec124d3cc967f8898ac..6f6ada2dbdda91863f83d2cfae5e5f49066b605d 100644 (file)
@@ -2,7 +2,7 @@
 
 <t:chloe xmlns:t="http://factorcode.org/chloe/1.0">
 
-       <t:atom t:href="$wiki/user-edits.atom" t:query="author">
+       <t:atom t:href="$wiki/user-edits.atom" t:rest="author">
                Edits by <t:label t:name="author" />
        </t:atom>
 
@@ -11,9 +11,9 @@
        <ul>
                <t:bind-each t:name="user-edits">
                        <li>
-                               <t:a t:href="view" t:query="title"><t:label t:name="title" /></t:a>
+                               <t:a t:href="$wiki/view" t:rest="title"><t:label t:name="title" /></t:a>
                                on
-                               <t:a t:href="revision" t:query="id"><t:label t:name="date" /></t:a>
+                               <t:a t:href="$wiki/revision" t:rest="id"><t:label t:name="date" /></t:a>
                        </li>
                </t:bind-each>
        </ul>
index 30dfb71270eca5578e5badae38c79b9e874d88cb..7d2c7869b5a01f5e8a784c3e0e758b289f845b02 100644 (file)
@@ -8,6 +8,6 @@
                <t:farkup t:name="content" />
        </div>
 
-       <p><em>This revision created on <t:label t:name="date" /> by <t:a t:href="user-edits" t:query="author"><t:label t:name="author" /></t:a>.</em></p>
+       <p><em>This revision created on <t:label t:name="date" /> by <t:a t:href="$wiki/user-edits" t:rest="author"><t:label t:name="author" /></t:a>.</em></p>
 
 </t:chloe>
index 21a983fc7b4f6a51f918186b16a94f4a17d493e2..47912789743c5e0ebcc40bb249a71e4a6d7875be 100644 (file)
@@ -1,7 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors kernel hashtables calendar
-namespaces splitting sequences sorting math.order
+namespaces splitting sequences sorting math.order present
 html.components syndication
 http.server
 http.server.dispatchers
@@ -15,20 +15,19 @@ validators
 db.types db.tuples lcs farkup urls ;
 IN: webapps.wiki
 
-: view-url ( title -- url )
-    "$wiki/view/" prepend >url ;
+: wiki-url ( rest path -- url )
+    [ "$wiki/" % % "/" % % ] "" make
+    <url> swap >>path ;
 
-: edit-url ( title -- url )
-    "$wiki/edit" >url swap "title" set-query-param ;
+: view-url ( title -- url ) "view" wiki-url ;
 
-: revisions-url ( title -- url )
-    "$wiki/revisions" >url swap "title" set-query-param ;
+: edit-url ( title -- url ) "edit" wiki-url ;
 
-: revision-url ( id -- url )
-    "$wiki/revision" >url swap "id" set-query-param ;
+: revisions-url ( title -- url ) "revisions" wiki-url ;
 
-: user-edits-url ( author -- url )
-    "$wiki/user-edits" >url swap "author" set-query-param ;
+: revision-url ( id -- url ) "revision" wiki-url ;
+
+: user-edits-url ( author -- url ) "user-edits" wiki-url ;
 
 TUPLE: wiki < dispatcher ;
 
@@ -83,12 +82,9 @@ M: revision feed-entry-url id>> revision-url ;
 : <view-article-action> ( -- action )
     <action>
         "title" >>rest
-
         [
             validate-title
-            "view?title=" relative-link-prefix set
         ] >>init
-
         [
             "title" value dup <article> select-tuple [
                 revision>> <revision> select-tuple from-object
@@ -100,13 +96,13 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <view-revision-action> ( -- action )
     <page-action>
+        "id" >>rest
         [
             validate-integer-id
             "id" value <revision>
             select-tuple from-object
-            "view?title=" relative-link-prefix set
+            URL" $wiki/view/" adjust-url present relative-link-prefix set
         ] >>init
-
         { wiki "view" } >>template ;
 
 : add-revision ( revision -- )
@@ -121,15 +117,14 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <edit-article-action> ( -- action )
     <page-action>
+        "title" >>rest
         [
             validate-title
             "title" value <article> select-tuple [
                 revision>> <revision> select-tuple from-object
             ] when*
         ] >>init
-
         { wiki "edit" } >>template
-        
         [
             validate-title
             { { "content" [ v-required ] } } validate-params
@@ -148,6 +143,7 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <list-revisions-action> ( -- action )
     <page-action>
+        "title" >>rest
         [
             validate-title
             list-revisions "revisions" set-value
@@ -156,6 +152,7 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <list-revisions-feed-action> ( -- action )
     <feed-action>
+        "title" >>rest
         [ validate-title ] >>init
         [ "Revisions of " "title" value append ] >>title
         [ "title" value revisions-url ] >>url
@@ -164,20 +161,18 @@ M: revision feed-entry-url id>> revision-url ;
 : <rollback-action> ( -- action )
     <action>
         [ validate-integer-id ] >>validate
-
         [
             "id" value <revision> select-tuple clone f >>id
             [ add-revision ] [ title>> view-url <redirect> ] bi
         ] >>submit ;
 
 : list-changes ( -- seq )
-    "id" value <revision> select-tuples
+    f <revision> select-tuples
     reverse-chronological-order ;
 
 : <list-changes-action> ( -- action )
     <page-action>
         [ list-changes "changes" set-value ] >>init
-
         { wiki "changes" } >>template ;
 
 : <list-changes-feed-action> ( -- action )
@@ -189,7 +184,6 @@ M: revision feed-entry-url id>> revision-url ;
 : <delete-action> ( -- action )
     <action>
         [ validate-title ] >>validate
-
         [
             "title" value <article> delete-tuples
             f <revision> "title" value >>title delete-tuples
@@ -213,7 +207,6 @@ M: revision feed-entry-url id>> revision-url ;
             [ [ content>> string-lines ] bi@ diff "diff" set-value ]
             2bi
         ] >>init
-
         { wiki "diff" } >>template ;
 
 : <list-articles-action> ( -- action )
@@ -223,7 +216,6 @@ M: revision feed-entry-url id>> revision-url ;
             [ [ title>> ] compare ] sort
             "articles" set-value
         ] >>init
-
         { wiki "articles" } >>template ;
 
 : list-user-edits ( -- seq )
@@ -232,6 +224,7 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <user-edits-action> ( -- action )
     <page-action>
+        "author" >>rest
         [
             validate-author
             list-user-edits "user-edits" set-value
@@ -240,6 +233,7 @@ M: revision feed-entry-url id>> revision-url ;
 
 : <user-edits-feed-action> ( -- action )
     <feed-action>
+        "author" >>rest
         [ validate-author ] >>init
         [ "Edits by " "author" value append ] >>title
         [ "author" value user-edits-url ] >>url