summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2011-11-20 16:17:57 +0100
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2011-11-20 16:17:57 +0100
commit9b1d5e260aab6f691fa3e2b39704334364a53fa3 (patch)
tree182133694cdef3eabac1d6bcb3346d44459f276d
parentbbb70dee15c88612ddc35565af6b2b9940357e8d (diff)
Make Wiki editable.
-rw-r--r--project.clj2
-rw-r--r--src/mulk/benki/auth.clj17
-rw-r--r--src/mulk/benki/db.clj3
-rw-r--r--src/mulk/benki/main.clj7
-rw-r--r--src/mulk/benki/util.clj26
-rw-r--r--src/mulk/benki/wiki.clj68
-rw-r--r--static/js/wiki.js70
7 files changed, 157 insertions, 36 deletions
diff --git a/project.clj b/project.clj
index d98fad6..9a077b2 100644
--- a/project.clj
+++ b/project.clj
@@ -30,7 +30,7 @@
;; Web app utilities
[ring "1.0.0-RC1"]
- [noir "1.2.2-SNAPSHOT"]
+ [noir "1.2.1"]
[hiccup "0.3.7"]
[cssgen "0.2.5-SNAPSHOT"]
;;[clj-http "0.2.3"]
diff --git a/src/mulk/benki/auth.clj b/src/mulk/benki/auth.clj
index 6dbce8d..d9b9d3e 100644
--- a/src/mulk/benki/auth.clj
+++ b/src/mulk/benki/auth.clj
@@ -19,12 +19,15 @@
(defonce manager (ConsumerManager.))
+(defn redirect [x]
+ {:status 302, :headers {"Location" x}, :body ""})
+
+
(defpartial return-from-openid-provider []
(let [parlist (ParameterList. (:query-params (request/ring-request)))
discovered (session/get :discovered)
;; Does the following work for POST requests?
- request-uri (str "http://localhost:3001/login/return"
- ;;(resolve-uri "/login/return")
+ request-uri (str (resolve-uri "/login/return")
(let [query-string (:query-string (request/ring-request))]
(if query-string
(str "?" query-string)
@@ -43,7 +46,9 @@
nil))]
(if user-id
(do (session/put! :user user-id)
- (layout "Authenticated!" [:p "Welcome back, " (:first_name user) "!"]))
+ (if-let [return-uri (session/flash-get)]
+ (redirect return-uri)
+ (layout "Authenticated!" [:p "Welcome back, " (:first_name user) "!"])))
(layout "Authentication Failed" [:p "Did not recognize OpenID."]))))
(layout "Authentication Failed" [:p "OpenID authentication failed."]))))
@@ -57,11 +62,9 @@
(defpage "/login/authenticate" {openid :openid}
(let [discoveries (.discover manager openid)
discovered (.associate manager discoveries)
- authreq (.authenticate manager discovered ;;(resolve-uri "/login/return")
- "http://localhost:3001/login/return"
- )]
+ authreq (.authenticate manager discovered (resolve-uri "/login/return"))]
(session/put! :discovered discovered)
- (response/redirect (.getDestinationUrl authreq true))))
+ (redirect (.getDestinationUrl authreq true))))
(defpage "/login" []
(layout "Benki Login"
diff --git a/src/mulk/benki/db.clj b/src/mulk/benki/db.clj
index 89ef768..468ce30 100644
--- a/src/mulk/benki/db.clj
+++ b/src/mulk/benki/db.clj
@@ -24,3 +24,6 @@
(defmacro query [query-string & params]
`(sql/with-query-results results# ~(into [] (concat [query-string] params))
(into '() results#)))
+
+(defmacro query1 [query-string & params]
+ `(first (query ~query-string ~@params)))
diff --git a/src/mulk/benki/main.clj b/src/mulk/benki/main.clj
index b1afa11..ea6e23f 100644
--- a/src/mulk/benki/main.clj
+++ b/src/mulk/benki/main.clj
@@ -5,7 +5,8 @@
[hiccup core page-helpers]
[mulk.benki util])
(:require [noir server options]
- [mulk.benki wiki auth]))
+ [mulk.benki wiki auth]
+ [ring.middleware.file]))
(defn wrap-utf-8 [handler]
@@ -26,7 +27,9 @@
(do-once ::init
(noir.server/add-middleware #(wrap-utf-8 %))
- (noir.server/add-middleware #(wrap-base-uri %)))
+ (noir.server/add-middleware #(wrap-base-uri %))
+ ;;(noir.server/add-middleware #(ring.middleware.static/wrap-static ))
+ (noir.server/add-middleware #(ring.middleware.file/wrap-file % "static")))
(defonce server (doto (Thread. #(noir.server/start 3001))
(.setDaemon true)
diff --git a/src/mulk/benki/util.clj b/src/mulk/benki/util.clj
index 5b2e484..c2729f9 100644
--- a/src/mulk/benki/util.clj
+++ b/src/mulk/benki/util.clj
@@ -1,6 +1,7 @@
(ns mulk.benki.util
(:refer-clojure)
- (:use [hiccup core page-helpers]
+ (:use [hiccup core page-helpers]
+ [clojure.core.match.core :only [match]]
noir.core))
@@ -21,6 +22,27 @@
;; defpartial is just defn + html.
(defpartial layout [title & content]
(html5
- [:head [:title title]]
+ [:head
+ [:title title]
+ ;; jQuery
+ [:script {:type "text/javascript"
+ :src (resolve-uri "/3rdparty/jquery/jquery-1.7.min.js")}]
+ ;; Aloha Editor
+ [:link {:rel "stylesheet"
+ :href (resolve-uri "/3rdparty/alohaeditor/aloha/css/aloha.css")}]
+ [:script {:type "text/javascript"
+ :src (resolve-uri "/3rdparty/alohaeditor/aloha/lib/aloha.js")
+ :data-aloha-plugins "common/format,common/highlighteditables,common/list,common/link,common/undo,common/paste,common/block"}]
+ ;; JavaScript
+ [:script {:type "text/javascript"
+ :src (resolve-uri "/js/wiki.js")}]]
[:body [:h1 title]
content]))
+
+
+(defn fresolve [s & args]
+ (resolve-uri (apply fmt nil s args)))
+
+(defn link [& args]
+ (match [(vec args)]
+ [[:wiki title & xs]] (fresolve "/wiki/~a~@[?~a~]" title (name (first xs)))))
diff --git a/src/mulk/benki/wiki.clj b/src/mulk/benki/wiki.clj
index 9615f0b..45b3270 100644
--- a/src/mulk/benki/wiki.clj
+++ b/src/mulk/benki/wiki.clj
@@ -4,35 +4,55 @@
(:use [clojure repl pprint]
[clojure.contrib error-kit]
[hiccup core page-helpers]
- [mulk.benki util]
+ [mulk.benki util db]
[clojure.core.match.core
:only [match]]
- [ring.util.response
- :only [redirect]]
- clojureql.core
- [clojure.java.jdbc
- :only [transaction]]
- noir.core))
+ [clojureql core predicates]
+ noir.core)
+ (:require [noir.session :as session]
+ [noir.response :as response]
+ [clojure.java.jdbc :as sql]))
-(def page_revisions (table :page_revisions))
-(def pages (table :pages))
+(def page_revisions (table :wiki_page_revisions))
+(def pages (table :wiki_pages))
(defpage "/wiki" []
- (redirect (resolve-uri "/wiki/Home")))
+ (response/redirect (resolve-uri "/wiki/Home")))
-(defpage "/wiki/:id" {id :id, revision-id :revision}
- (let [page (-> pages
- (select (if (number? id)
- (where (= :id id))
- (where (= :title id)))))
- revisions (-> page_revisions
- (join page (where (= :pages.id :page_revisions.page)))
- ;;(project [:page_revisions.*])
- (project page_revisions))
- revision (if revision-id
- (select revisions (where (= :id revision-id)))
- (first (sort revisions [:published#desc])))]
- (layout (fmt nil "~A — Benki~@[/~A~] " id revision-id)
- [:pre (prn-str revision)])))
+(defpage "/wiki/:title" {title :title, revision-id :revision}
+ (let [revisions (-> page_revisions
+ (select (where (=* :title title)))
+ (select (where (if revision-id
+ (=* :id revision-id)
+ (=* 0 0)))))
+ revision (with-dbt (first @revisions))]
+ (layout (fmt nil "~A — Benki~@[/~A~] " title revision-id)
+ (if revision
+ [:div#wiki-page-content (:content revision)]
+ [:div#wiki-page-content [:p "This page does not exist yet."]])
+ [:hr]
+ [:div#wiki-page-footer {:style "text-align: right"}
+ [:a {:href (link :wiki title :edit)} "Edit"
+ ]])))
+
+(defn insert-empty-page []
+ (sql/with-query-results results ["insert into wiki_pages default values returning *"]
+ (first (into () results))))
+
+(defpage [:post "/wiki/:title"] {title :title, content :content}
+ (with-dbt
+ (let [revisions (-> page_revisions
+ (select (where (=* :title title))))
+ revision (first @revisions)
+ page (:page revision)]
+ (println "For page: " title " (id " page "); got content: " content)
+ (if-let [user (Integer. (session/get :user))]
+ (let [page-id (if page page (:id (insert-empty-page)))]
+ (sql/insert-values
+ :wiki_page_revisions
+ [:page :title :content :author :format]
+ [page-id title content user "html5"])
+ {:stetus 200, :headers {}, :body ""})
+ {:status 403, :headers {}, :body ""}))))
diff --git a/static/js/wiki.js b/static/js/wiki.js
new file mode 100644
index 0000000..3f61456
--- /dev/null
+++ b/static/js/wiki.js
@@ -0,0 +1,70 @@
+/*
+jQuery(function ($) {
+ $('#wiki-page-content').on('blur', function() {
+ // FIXME: Save.
+ document.designMode = 'off';
+ });
+ $('#wiki-page-content').on('focus', function() {
+ document.designMode = 'on';
+ });
+});
+*/
+
+
+jQuery(function ($) {
+ if (!window.Aloha) {
+ window.Aloha = {};
+ }
+ window.Aloha.settings = {
+ logLevels: {'error': true, 'warn': true, 'info': true, 'debug': false},
+ errorhandling : false,
+ ribbon: true,
+
+ "i18n": {
+ "current": "de"
+ },
+ "repositories": {
+ },
+ "plugins": {
+ "format": {
+ config : [ 'b', 'i','sub','sup'],
+ editables : {
+ '#title' : [ ],
+ 'div' : [ 'b', 'i', 'del', 'sub', 'sup' ],
+ '.article' : [ 'b', 'i', 'p', 'title', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'removeFormat']
+ }
+ },
+ "list": {
+ },
+ "link": {
+ config : [ 'a' ],
+ },
+ "table": {
+ config : [ ],
+ },
+ "image": {
+ }
+ }
+ };
+
+ Aloha.ready(function() {
+ var $$ = Aloha.jQuery;
+ $$('#wiki-page-content').aloha();
+ var save = function() {
+ console.log('Saving changes.');
+ $.ajax({
+ url: "?save",
+ data: { content: $('#wiki-page-content').html() },
+ type: "POST",
+ success: function() {
+ console.log('Success.');
+ },
+ error: function() {
+ console.log('Error.');
+ }
+ });
+ };
+ $('#wiki-page-content').on('blur', save);
+ //$('#wiki-page-content').on('datachanged', save);
+ });
+});