Browse code
feature: improve rendering, polymorphic cleaning
Ed Langley authored on 06/11/2019 07:56:31
Showing 5 changed files
Showing 5 changed files
... | ... |
@@ -14,19 +14,25 @@ |
14 | 14 |
(:documentation |
15 | 15 |
"A simple wrapper that ties a ningle app to a clack handler")) |
16 | 16 |
|
17 |
+(defun redirect (target) |
|
18 |
+ (lambda (_) |
|
19 |
+ (declare (ignore _)) |
|
20 |
+ `(302 (:location ,target) ()))) |
|
17 | 21 |
|
18 | 22 |
(defmethod araneus:routes progn ((app rss-reader)) |
19 | 23 |
(araneus:defroutes (app app) |
20 |
- (("/") (serapeum:partial 'araneus:run-route (make-instance 'homepage))) |
|
24 |
+ (("/") (redirect (format nil "/f/~(~a~)" |
|
25 |
+ (feed-key |
|
26 |
+ (car |
|
27 |
+ (feeds app)))))) |
|
21 | 28 |
(("/f/:feed") (lambda (params) |
22 | 29 |
(optima:match params |
23 | 30 |
((optima.extra:alist (:feed . feed)) |
24 |
- (araneus:run-route (feed-page |
|
25 |
- (feeds app) |
|
26 |
- (serapeum:assocdr feed (feeds app) |
|
27 |
- :test 'string-equal)) |
|
28 |
- params))))) |
|
29 |
- (("/other") (serapeum:partial 'araneus:run-route 'other)))) |
|
31 |
+ (araneus:run-route (feed-page (feeds app) |
|
32 |
+ (find feed (feeds app) |
|
33 |
+ :key 'feed-key |
|
34 |
+ :test 'string-equal)) |
|
35 |
+ params))))))) |
|
30 | 36 |
|
31 | 37 |
(defun start (app) |
32 | 38 |
(setf (handler app) |
... | ... |
@@ -38,11 +44,39 @@ |
38 | 44 |
(defun unboundp (symbol) |
39 | 45 |
(not (boundp symbol))) |
40 | 46 |
|
47 |
+(defgeneric feed-key (object)) |
|
48 |
+(defgeneric feed-url (object)) |
|
49 |
+ |
|
50 |
+(fw.lu:defclass+ feed-reference () |
|
51 |
+ ((%key :initarg :key :reader feed-key) |
|
52 |
+ (%url :initarg :url :reader feed-url))) |
|
53 |
+ |
|
54 |
+(fw.lu:defclass+ plump-cleaner |
|
55 |
+ ((feed-reference (key url))) |
|
56 |
+ ()) |
|
57 |
+ |
|
58 |
+(defgeneric resolve-feed-reference (reference) |
|
59 |
+ (:method ((r feed-reference)) |
|
60 |
+ (alimenta.pull-feed:pull-feed (feed-url r)))) |
|
61 |
+ |
|
62 |
+(defgeneric prepare-feed-item-description (reference item) |
|
63 |
+ (:method ((r feed-reference) (item alimenta:item)) |
|
64 |
+ (alimenta:description item)) |
|
65 |
+ (:method ((r plump-cleaner) (item alimenta:item)) |
|
66 |
+ (let ((description (alimenta:description item))) |
|
67 |
+ (when description |
|
68 |
+ (format t "~&aaaaa~%") |
|
69 |
+ (plump:text |
|
70 |
+ (plump:parse |
|
71 |
+ description)))))) |
|
72 |
+ |
|
41 | 73 |
(defun main () |
42 | 74 |
(setf *app* |
43 | 75 |
(if (not (boundp '*app*)) |
44 | 76 |
(start |
45 | 77 |
(araneus:routes |
46 |
- (rss-reader `((:techcrunch . "https://techcrunch.com/feed/") |
|
47 |
- (:just-thomism . "https://thomism.wordpress.com/feed/"))))) |
|
78 |
+ (rss-reader (list |
|
79 |
+ (feed-reference :techcrunch "https://techcrunch.com/feed/") |
|
80 |
+ (plump-cleaner :coding-horror "http://feeds.feedburner.com/codinghorror") |
|
81 |
+ (feed-reference :daring-fireball "https://daringfireball.net/feeds/main"))))) |
|
48 | 82 |
*app*))) |
... | ... |
@@ -5,10 +5,13 @@ |
5 | 5 |
(defpackage :fwoar.rss-reader.ui |
6 | 6 |
(:use :cl :parenscript) |
7 | 7 |
(:export ui |
8 |
- #:homepage |
|
9 | 8 |
#:intercooler-debugger)) |
10 | 9 |
|
11 | 10 |
(defpackage :fwoar.rss-reader |
12 | 11 |
(:use :cl ) |
13 | 12 |
(:import-from :fwoar.rss-reader.utils #:defclass+) |
14 |
- (:export )) |
|
13 |
+ (:export |
|
14 |
+ #:feed-reference |
|
15 |
+ #:plump-cleaner |
|
16 |
+ #:resolve-feed-reference |
|
17 |
+ #:prepare-feed-item-description)) |
... | ... |
@@ -4,18 +4,35 @@ |
4 | 4 |
#:summary)) |
5 | 5 |
(in-package :fwoar.rss-render) |
6 | 6 |
|
7 |
-(defmethod alimenta.render:render-feed (feed (renderer (eql 'summary))) |
|
7 |
+(defmacro if-arg-not-nil ((op arg)) |
|
8 |
+ (alexandria:once-only (arg) |
|
9 |
+ `(when ,arg |
|
10 |
+ (,op ,arg)))) |
|
11 |
+ |
|
12 |
+(defmethod alimenta.render:render-feed ((feed alimenta.rss:rss-feed) (renderer fwoar.rss-reader:feed-reference)) |
|
13 |
+ (plump:parse |
|
14 |
+ (spinneret:with-html-string |
|
15 |
+ (:div.feed |
|
16 |
+ (:section |
|
17 |
+ (:h2.title (if-arg-not-nil |
|
18 |
+ (plump:decode-entities |
|
19 |
+ (alimenta:title feed)))) |
|
20 |
+ (:p.description (if-arg-not-nil |
|
21 |
+ (plump:decode-entities |
|
22 |
+ (alimenta:description feed))))) |
|
23 |
+ (:ul.items))))) |
|
24 |
+ |
|
25 |
+(defmethod alimenta.render:render-feed ((feed alimenta.atom::atom-feed) (renderer fwoar.rss-reader:feed-reference)) |
|
8 | 26 |
(plump:parse |
9 | 27 |
(spinneret:with-html-string |
10 | 28 |
(:div.feed |
11 | 29 |
(:section |
12 |
- (:h2.title (plump:decode-entities |
|
13 |
- (alimenta:title feed))) |
|
14 |
- (:p.description (plump:decode-entities |
|
15 |
- (alimenta:description feed)))) |
|
30 |
+ (:h2.title (if-arg-not-nil |
|
31 |
+ (plump:decode-entities |
|
32 |
+ (alimenta:title feed))))) |
|
16 | 33 |
(:ul.items))))) |
17 | 34 |
|
18 |
-(defmethod alimenta.render:render-item (item feed (renderer (eql 'summary))) |
|
35 |
+(defmethod alimenta.render:render-item (item feed (renderer fwoar.rss-reader:feed-reference)) |
|
19 | 36 |
(plump:first-element |
20 | 37 |
(plump:parse |
21 | 38 |
(spinneret:with-html-string |
... | ... |
@@ -24,10 +41,12 @@ |
24 | 41 |
(plump:decode-entities |
25 | 42 |
(alimenta:title item))) |
26 | 43 |
(:p.description |
27 |
- (plump:decode-entities |
|
28 |
- (alimenta:description item)))))))) |
|
44 |
+ (let ((description (fwoar.rss-reader:prepare-feed-item-description renderer item))) |
|
45 |
+ (when description |
|
46 |
+ (plump:decode-entities |
|
47 |
+ description))))))))) |
|
29 | 48 |
|
30 |
-(defmethod alimenta.render:add-rendered-item (feed-r item-r (renderer (eql 'summary))) |
|
49 |
+(defmethod alimenta.render:add-rendered-item (feed-r item-r (renderer fwoar.rss-reader:feed-reference)) |
|
31 | 50 |
(lquery:$ |
32 | 51 |
(inline feed-r) |
33 | 52 |
".items" |
... | ... |
@@ -1,23 +1,5 @@ |
1 | 1 |
(in-package :fwoar.rss-reader.ui) |
2 | 2 |
|
3 |
-(defun homepage (content) |
|
4 |
- (spinneret:with-html |
|
5 |
- (:h1 "Hello, World!") |
|
6 |
- (:div.main |
|
7 |
- (:nav |
|
8 |
- :data-ic-target "main" |
|
9 |
- :data-ic-replace-target "true" |
|
10 |
- (:a :data-ic-get-from "/" |
|
11 |
- "home") |
|
12 |
- (:a :data-ic-get-from "/other" |
|
13 |
- "other") |
|
14 |
- (:a :data-ic-get-from "/third" |
|
15 |
- "third") |
|
16 |
- (:a :data-ic-get-from "/fourth" |
|
17 |
- "fourth")) |
|
18 |
- (funcall content)))) |
|
19 |
- |
|
20 |
- |
|
21 | 3 |
(defun intercooler-debugger () |
22 | 4 |
(ps |
23 | 5 |
(defun cdnjs-library (name version &key (file name)) |
... | ... |
@@ -1,5 +1,8 @@ |
1 | 1 |
(in-package :fwoar.rss-reader) |
2 | 2 |
|
3 |
+(defmethod spinneret:html ((object plump:node)) |
|
4 |
+ (plump:serialize object spinneret:*html*)) |
|
5 |
+ |
|
3 | 6 |
(defclass rss-reader-route () |
4 | 7 |
((%feed-list :initarg :feed-list :reader feed-list))) |
5 | 8 |
|
... | ... |
@@ -54,17 +57,6 @@ the hook that pulls in CSS" |
54 | 57 |
((:or ul ol) |
55 | 58 |
:padding-left 2rem))) |
56 | 59 |
|
57 |
-(defclass+ feed-page ((rss-reader-route (feed-list)) fwoar.default-layout:default-layout) |
|
58 |
- ((%feed :initarg :feed :reader feed))) |
|
59 |
- |
|
60 |
-(defmethod araneus:controller ((route feed-page) params &key) |
|
61 |
- (funcall (if (equal (serapeum:assocdr "ic-request" params |
|
62 |
- :test 'equal) |
|
63 |
- "true") |
|
64 |
- 'partial-request |
|
65 |
- 'full-request) |
|
66 |
- (alimenta.pull-feed:pull-feed (feed route)))) |
|
67 |
- |
|
68 | 60 |
(defmacro with-layout ((render-type layout) &body content) |
69 | 61 |
`(let ((content (lambda () |
70 | 62 |
(spinneret:with-html |
... | ... |
@@ -75,11 +67,23 @@ the hook that pulls in CSS" |
75 | 67 |
(,layout content))) |
76 | 68 |
(:partial (funcall content))))) |
77 | 69 |
|
70 |
+(defclass+ feed-page ((rss-reader-route (feed-list)) fwoar.default-layout:default-layout) |
|
71 |
+ ((%feed :initarg :feed :reader feed))) |
|
72 |
+ |
|
73 |
+(defmethod araneus:controller ((route feed-page) params &key) |
|
74 |
+ (funcall (if (equal (serapeum:assocdr "ic-request" params |
|
75 |
+ :test 'equal) |
|
76 |
+ "true") |
|
77 |
+ 'partial-request |
|
78 |
+ 'full-request) |
|
79 |
+ (resolve-feed-reference (feed route)))) |
|
80 |
+ |
|
78 | 81 |
(defmethod araneus:view ((_ feed-page) (model intercooler-request)) |
79 | 82 |
(spinneret:with-html |
80 | 83 |
(:main#content |
81 | 84 |
(alimenta:render (request model) |
82 | 85 |
'fwoar.rss-render:summary)))) |
86 |
+ |
|
83 | 87 |
(defmethod araneus:view ((route feed-page) (model full-request)) |
84 | 88 |
(spinneret:with-html |
85 | 89 |
(:h1 "Hello, World!") |
... | ... |
@@ -88,36 +92,18 @@ the hook that pulls in CSS" |
88 | 92 |
:data-ic-push-url "true" |
89 | 93 |
:data-ic-target "main" |
90 | 94 |
:data-ic-replace-target "true" |
91 |
- (loop for (feed-id) in (feed-list route) |
|
92 |
- collect (:a :data-ic-get-from (format nil "/f/~a" (string-downcase feed-id)) |
|
93 |
- feed-id))) |
|
95 |
+ (loop for feed in (feed-list route) |
|
96 |
+ collect (:a :data-ic-get-from (format nil "/f/~a" (string-downcase (feed-key feed))) |
|
97 |
+ (feed-key feed)))) |
|
94 | 98 |
(:main#content |
95 | 99 |
(alimenta:render (request model) |
96 |
- 'fwoar.rss-render:summary))))) |
|
97 |
- |
|
98 |
-(defclass homepage (rss-reader-route fwoar.default-layout:default-layout) |
|
99 |
- ()) |
|
100 |
+ (feed route)))))) |
|
100 | 101 |
|
101 | 102 |
(defmethod fwoar.default-layout:border-color ((layout rss-reader-route)) |
102 | 103 |
"#BDE0F3") |
103 |
- |
|
104 |
-(defmethod araneus:controller ((route homepage) params &key) |
|
105 |
- (format t "~&~s~%" params) |
|
106 |
- (if (equal (serapeum:assocdr "ic-request" params |
|
107 |
- :test 'equal) |
|
108 |
- "true") |
|
109 |
- :partial |
|
110 |
- :full)) |
|
111 |
- |
|
112 |
-(defmethod araneus:view ((route homepage) model) |
|
113 |
- (with-layout (model fwoar.rss-reader.ui:homepage) |
|
114 |
- (:raw |
|
115 |
- (plump:serialize (alimenta:render (alimenta.pull-feed:pull-feed |
|
116 |
- "https://thomism.wordpress.com/feed/") |
|
117 |
- 'fwoar.rss-render:summary) |
|
118 |
- nil)))) |
|
119 |
- |
|
120 |
-(araneus:define-controller other (_) |
|
121 |
- (values)) |
|
122 |
-(araneus:define-view other (_) |
|
123 |
- "<main><h2>???</h2></main>") |
|
104 |
+(defmethod fwoar.default-layout:background-color ((layout rss-reader-route)) |
|
105 |
+ "#3f3f3f") |
|
106 |
+(defmethod fwoar.default-layout:text-color ((layout rss-reader-route)) |
|
107 |
+ "#DCDCCC") |
|
108 |
+(defmethod fwoar.default-layout:link-color ((layout rss-reader-route)) |
|
109 |
+ "#F5F5D6") |