diff of 64afa23d4a3fd2be8b057bf20c9e69872c9ecf7b

64afa23d4a3fd2be8b057bf20c9e69872c9ecf7b
diff --git a/aggressive-murja.asd b/aggressive-murja.asd
index ce79198..14f7f3e 100644
--- a/aggressive-murja.asd
+++ b/aggressive-murja.asd
@@ -85,6 +85,7 @@
 		   (:module "admin"
 		    :components ((:module "components"
 				  :components ((:file "tag-script")
+					       (:file "previouslies-script")
 					       (:file "editor")))
 				 (:file "post-list")
 				 (:file "new-post")))
diff --git a/resources/css/murja.css b/resources/css/murja.css
index f2b30ae..f7f5d27 100644
--- a/resources/css/murja.css
+++ b/resources/css/murja.css
@@ -460,6 +460,12 @@ input:required {
     margin: 3px;
 }
 
+.editor-previously-li {
+    display: flex;
+    justify-content: space-between;
+    margin: 5px;
+}
+
 @media only screen and (max-device-width:480px)
 {
     body {
diff --git a/src/middleware/auth.lisp b/src/middleware/auth.lisp
index d5696dc..9c74ebe 100644
--- a/src/middleware/auth.lisp
+++ b/src/middleware/auth.lisp
@@ -70,7 +70,7 @@
 								  :user-id user-id))
 	      "not authorized")))))
 
-(defun @can? (ability next)
+(defun @can? (next ability)
   (if (and *user*
 	   (member ability 
 		   (gethash "permissions" *user*)
diff --git a/src/view/admin/components/editor.lisp b/src/view/admin/components/editor.lisp
index 9049f2a..88dec2f 100644
--- a/src/view/admin/components/editor.lisp
+++ b/src/view/admin/components/editor.lisp
@@ -2,10 +2,20 @@
   (:use :cl :binding-arrows :spinneret )
   (:export :editor)
   (:import-from :murja.view.admin.components.tag-script :tags-component-frontend)
-  (:import-from :murja.model.post :tags :article :post-title :post-hidden? :post-unlisted?))
+  (:import-from :murja.view.admin.components.previouslies-script :previouslies-component-frontend)
+  (:import-from :murja.model.post :tags :article :post-title :post-hidden? :post-unlisted?)
+  (:local-nicknames (:posts :murja.model.post)
+		    (:json :com.inuoe.jzon)))
 
 (in-package :murja.view.admin.components.editor)
 
+(defun previouslies (post)
+  (with-html
+    (:script (:raw (previouslies-component-frontend)))
+    (:div :id "previouslies-container"
+     (:input :type "text" ;; "hidden" 
+	     :name "previouslies" :id "previouslies" :value (json:stringify (posts:previouslies post))))))
+
 (defun tag-component (post)
   (with-html
     (:div.tag-component
@@ -32,7 +42,8 @@
   (with-html
     (:div.editor-top 
      (post-meta post)
-     (tag-component post))))
+     (tag-component post)
+     (previouslies post))))
 
 (defun editor (post)
   (with-html
diff --git a/src/view/admin/components/previouslies-script.lisp b/src/view/admin/components/previouslies-script.lisp
new file mode 100644
index 0000000..4aae247
--- /dev/null
+++ b/src/view/admin/components/previouslies-script.lisp
@@ -0,0 +1,82 @@
+(defpackage murja.view.admin.components.previouslies-script
+  (:use :cl :binding-arrows :parenscript)
+  (:export :previouslies-component-frontend)
+  (:documentation "All the parenscript logic hidden from making murja.view.admin.components.editor an eyesore"))
+
+(in-package :murja.view.admin.components.previouslies-script)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+
+  (named-readtables:defreadtable :murja.ps
+    (:merge :standard)
+    ;; this is required to make parenscript not mangle capitalization of ourSYMBOLS
+    (:case :invert))
+
+  (named-readtables:in-readtable :murja.ps))
+
+(defun previouslies-component-frontend ()
+  (ps
+    (defun remove-previously (id)
+      (lambda ()
+	(let* ((previouslies-input (chain document
+					  (query-selector "#previouslies")))
+	       (previouslies (chain JSON (parse (@ previouslies-input value)))))
+	  (setf (@ previouslies-input value)
+		(chain JSON
+		       (stringify 
+			(chain previouslies
+			       (filter 
+				(lambda (el)
+				  (not (= (@ el id) id))))))))
+
+	  (regenerate-previously-component nil))))
+    
+    (defun regenerate-previously-component (e)
+      
+      (let* ((previouslies-container (chain document
+					    (query-selector "#previouslies-container")))
+	     (previouslies-input (chain document
+					(query-selector "#previouslies")))
+	     (previouslies (chain JSON (parse (@ previouslies-input value))))
+
+	     (ul-root (chain document
+			     (create-element "ul"))))
+
+	;; drop the old previously DOM completely, holding on to the state-holding <input type="hidden"/> 
+	(setf (@ previouslies-container innerHTML) "")
+
+	;; generate list of links ->posts and buttons to remove them 
+	(dolist (el previouslies)
+	  (let ((li (chain document (create-element "li")))
+		(a (chain document (create-element "a")))
+		
+		(remove-btn (chain document (create-element "button"))))
+	    (setf (@ remove-btn inner-text) "X")
+	    (setf (@ a href) (+ "/blog/post/" (@ el id)))
+	    (setf (@ a inner-text) (@ el title))
+	    (chain remove-btn
+		   (add-event-listener "click" (remove-previously (@ el id))))
+
+	    (chain li
+		   (append-child a))
+	    (chain li
+		   (append-child remove-btn))
+
+	    (setf (@ li class-name) "editor-previously-li")
+	    
+	    (chain ul-root
+		   (append-child li))))
+
+	;; add the state-holding <input type="hidden" /> back to DOM 
+	(chain previouslies-container
+	       (append-child previouslies-input))
+
+	;; add the previously generated <ul> tree into DOM 
+	(chain previouslies-container
+	       (append-child ul-root))
+	
+	nil))
+    
+    (chain document
+	   (add-event-listener "DOMContentLoaded"
+			       #'regenerate-previously-component))))
diff --git a/src/view/admin/new-post.lisp b/src/view/admin/new-post.lisp
index 483afb8..4973106 100644
--- a/src/view/admin/new-post.lisp
+++ b/src/view/admin/new-post.lisp
@@ -21,3 +21,13 @@
 		       :inject-to-head (#'head-script))
   (let ((new-post (make-instance 'post :content "kissa" :title "titteli")))
     (editor new-post)))
+
+(deftab blog/post/editor (:url "/blog/post/editor/:id"
+			  :subtab murja.view.admin.post-list:blog/postadmin
+			  :require-login t
+			  :needed-abilities ("create-post" "delete-post" "edit-post")
+			  :inject-to-head (#'head-script)
+			  :captured-url-params (id))
+  (let ((old-post (get-post id :allow-hidden? t)))
+    (editor old-post)))
+			  
diff --git a/src/view/components/blogpost.lisp b/src/view/components/blogpost.lisp
index b10b5ad..cc817dc 100644
--- a/src/view/components/blogpost.lisp
+++ b/src/view/components/blogpost.lisp
@@ -1,5 +1,6 @@
 (defpackage murja.view.components.blogpost
   (:use :cl :binding-arrows :spinneret :murja.model.post :murja.model.user :cl-hash-util)
+  (:import-from :murja.middleware.auth :*user*)
   (:export :page :blogpost))
 
   
@@ -31,8 +32,9 @@
 	  (:p ("Written at ~a" (let ((lisp-fixup:*rfc822* t))
 				 (lisp-fixup:fix-timestamp created-at)))))
 
-	 ;; TODO
-	 ;; (:a :href ("/blog/post/edit/~d" id) "Edit this post")
+	 (when *user*
+	   ;; the old editor is in "/blog/post/edit/~d"
+	   (:a :href (format nil "/blog/post/editor/~d" id) "Edit this post"))
 	 (:article.content
 	  (:raw 
 	   content))
diff --git a/src/view/components/root.lisp b/src/view/components/root.lisp
index d7d67ef..2331d4f 100644
--- a/src/view/components/root.lisp
+++ b/src/view/components/root.lisp
@@ -33,11 +33,15 @@
 								       Title))))
 							  (gethash month by-month)))))))))))))))
 
-(defun sidebar/new-post ()  
-  (with-html
-    (if (and *user*
-	     (not (equalp "/blog/new-post" (hunchentoot:request-uri*))))
-	(:a :href "/blog/new-post" "NEW POST"))))
+(defun sidebar/new-post ()
+  (let ((disabled-routes (list "/blog/new-post"
+			       "/blog/post/editor")))
+    (with-html
+      (if (and *user*
+	       (not (member (cl-ppcre:regex-replace "/\\d+$" (hunchentoot:request-uri*) "")
+			    disabled-routes
+			    :test 'equal)))
+	  (:a :href "/blog/new-post" "NEW POST")))))
 	
 
 (defun loginform/user-widget ()