◊(Local Yarn Code "Check-in [5b2f378a]")

Overview
Comment:Correct and clarify display of articles that do not specify a title.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5b2f378acade49a90e698474ebc8f13de4211e45d24119f9ef55064cf4b0e9f3
User & Date: joel on 2018-09-23 21:57:12
Other Links: manifest | tags
Context
2018-09-26
01:00
Additional CSS styles for block-quotes. Omit article footer tag when no footer text is present. check-in: 3911576e user: joel tags: trunk
2018-09-23
21:57
Correct and clarify display of articles that do not specify a title. check-in: 5b2f378a user: joel tags: trunk
21:04
Add functions for storing/reading booleans in SQLite check-in: 53e02bf3 user: joel tags: trunk
Changes

Modified crystalize.rkt from [2ee97a67] to [04b300fe].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
;; data; a maliciously crafted input could bomb the database. This is acceptable
;; since the database is merely a disposable cache, and since all the input
;; will be coming from me.

(require pollen/setup
         pollen/core
         pollen/template
         pollen/pagetree
         racket/string
         txexpr
         "sqlite-tools.rkt"
         "template-html.rkt"
         "dust.rkt")

;; ~~~ Provides ~~~

(provide spell-of-summoning!
         crystalize-article!)


;; ~~~ Private use ~~~

(define DBFILE (build-path (current-project-root) "vitreous.sqlite"))

;; Since the DB exists to serve as a high-speed cache, the tables are constructed so that
;; the most commonly needed data can be grabbed quickly with extremely simple queries. In
;; the even that you want to do something fancy and custom rather than using the pre-cooked
;; HTML, enough info is provided in the other columns to allow you to do so.
;;
(define table_articles-fields
  '(pagenode
    title_plain
    title_html_flow

    published
    updated
    author
    conceal
    series_pagenode
    noun_singular 
    note_count







<









|
>














>







30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
;; data; a maliciously crafted input could bomb the database. This is acceptable
;; since the database is merely a disposable cache, and since all the input
;; will be coming from me.

(require pollen/setup
         pollen/core
         pollen/template

         racket/string
         txexpr
         "sqlite-tools.rkt"
         "template-html.rkt"
         "dust.rkt")

;; ~~~ Provides ~~~

(provide spell-of-summoning!
         crystalize-article!
         article-plain-title)

;; ~~~ Private use ~~~

(define DBFILE (build-path (current-project-root) "vitreous.sqlite"))

;; Since the DB exists to serve as a high-speed cache, the tables are constructed so that
;; the most commonly needed data can be grabbed quickly with extremely simple queries. In
;; the even that you want to do something fancy and custom rather than using the pre-cooked
;; HTML, enough info is provided in the other columns to allow you to do so.
;;
(define table_articles-fields
  '(pagenode
    title_plain
    title_html_flow
    title_specified
    published
    updated
    author
    conceal
    series_pagenode
    noun_singular 
    note_count
116
117
118
119
120
121
122

123
124

125
126
127
128
129
130
131
132
133
134
135
136
137

138
139
140
141
142
143
144
(define (crystalize-article! pagenode doc)
  (define pubdate (select-from-metas 'published (current-metas)))
  (define-values (body-txpr note-txprs) (doc->body/notes doc))
  (define doc-html (->html (cdr body-txpr)))
  
  (define-values (disposition disp-note-id)
    (notes->last-disposition-values note-txprs))

  (define-values (title-plain title-html-flow)
    (make-article-titles (maybe-meta 'title (default-title pubdate)) disposition))

  (define series-node (maybe-meta 'series))
  (define header (html$-article-open title-html-flow pubdate))

  (define footertext (make-article-footertext pagenode series-node disposition disp-note-id (length note-txprs)))
  (define footer (html$-article-close footertext))
  
  (define notes-section-html (crystalize-notes! pagenode title-plain note-txprs))

  ;; Values must come in the order defined in table_article_fields
  (define article-record
    (list (symbol->string pagenode)
          title-plain
          title-html-flow

          pubdate
          (maybe-meta 'updated)
          (maybe-meta 'author default-authorname)
          (maybe-meta 'conceal)
          series-node
          (maybe-meta 'noun (series-noun))
          (length note-txprs)







>

<
>

|











>







117
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
(define (crystalize-article! pagenode doc)
  (define pubdate (select-from-metas 'published (current-metas)))
  (define-values (body-txpr note-txprs) (doc->body/notes doc))
  (define doc-html (->html (cdr body-txpr)))
  
  (define-values (disposition disp-note-id)
    (notes->last-disposition-values note-txprs))
  (define title-specified? (non-empty-string? (maybe-meta 'title)))
  (define-values (title-plain title-html-flow)

    (title-plain+html-values body-txpr disposition))
  (define series-node (maybe-meta 'series))
  (define header (html$-article-open title-specified? title-html-flow pubdate))

  (define footertext (make-article-footertext pagenode series-node disposition disp-note-id (length note-txprs)))
  (define footer (html$-article-close footertext))
  
  (define notes-section-html (crystalize-notes! pagenode title-plain note-txprs))

  ;; Values must come in the order defined in table_article_fields
  (define article-record
    (list (symbol->string pagenode)
          title-plain
          title-html-flow
          (bool->int title-specified?)
          pubdate
          (maybe-meta 'updated)
          (maybe-meta 'author default-authorname)
          (maybe-meta 'conceal)
          series-node
          (maybe-meta 'noun (series-noun))
          (length note-txprs)
152
153
154
155
156
157
158
159







160
161
162
163
164
165
166
167
  (apply query! (make-insert/replace-query 'articles table_articles-fields) article-record)
          
  ◊string-append{◊header ◊doc-html ◊notes-section-html ◊footer})

;; ~~~ Article-related helper functions ~~~
;;

;; Given a disposition and title, return both a plain-text and HTML version of the title







(define (make-article-titles title-val disposition)
  (define disposition-part
    (cond [(non-empty-string? disposition)
           (define-values (mark _) (disposition-values disposition))
           (format "<span class=\"disposition-mark\">~a</span>" mark)]
          [else ""]))
  
  (cond [(txexpr? title-val)







|
>
>
>
>
>
>
>
|







155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  (apply query! (make-insert/replace-query 'articles table_articles-fields) article-record)
          
  ◊string-append{◊header ◊doc-html ◊notes-section-html ◊footer})

;; ~~~ Article-related helper functions ~~~
;;

;; Return both a plain-text and HTML version of a title for the current article,
;; supplying a default if no title was specified in the metas.
(define (title-plain+html-values body-tx disposition)
  (define title (maybe-meta 'title ""))
  (define title-val
    (cond [(and (string? title) (string=? title ""))
           (format "“~a…”" (first-words (tx-strs body-tx) 5))]
          [else title]))
  
  (define disposition-part
    (cond [(non-empty-string? disposition)
           (define-values (mark _) (disposition-values disposition))
           (format "<span class=\"disposition-mark\">~a</span>" mark)]
          [else ""]))
  
  (cond [(txexpr? title-val)
264
265
266
267
268
269
270



                           " AND `note_id` = ?2), ~a)")
            (list->sql-fields table_notes-fields)
            (list->sql-parameters table_notes-fields)))
  (apply query! save-note-query note-record)
  
  ;; return html$ of note
  (html$-note-in-article note-id note-date content-html author author-url))










>
>
>
274
275
276
277
278
279
280
281
282
283
                           " AND `note_id` = ?2), ~a)")
            (list->sql-fields table_notes-fields)
            (list->sql-parameters table_notes-fields)))
  (apply query! save-note-query note-record)
  
  ;; return html$ of note
  (html$-note-in-article note-id note-date content-html author author-url))

(define (article-plain-title pagenode)
  (query-value (sqltools:dbc) "SELECT `title_plain` FROM `articles` WHERE `pagenode` = ?1" (symbol->string pagenode)))

Modified dust.rkt from [9b28a908] to [27351ca1].

38
39
40
41
42
43
44

45
46
47
48
49
50
51
         attr-present?  ; Test if an attribute is present
         disposition-values
         ymd->english
         ymd->dateformat
         default-authorname
         default-title
         tx-strs

         build-note-id
         notes->last-disposition-values
         )

(define default-authorname "Joel Dueck")

(define (default-title date)







>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
         attr-present?  ; Test if an attribute is present
         disposition-values
         ymd->english
         ymd->dateformat
         default-authorname
         default-title
         tx-strs
         first-words
         build-note-id
         notes->last-disposition-values
         )

(define default-authorname "Joel Dueck")

(define (default-title date)
78
79
80
81
82
83
84







85
86
87
88
89
90
91

(define (tx-strs xpr)
  (cond
    [(txexpr? xpr) (apply string-append (map tx-strs (get-elements xpr)))]
    [(string? xpr) xpr]
    [else ""]))








(module+ test
  (require rackunit)
  (define test-metas (hash 'name "Fiver" 'size "Small"))
  (define test-attrs '([name "Hazel"] [rank "Chief"]))

  (parameterize ([current-metas test-metas])
    (check-equal? (maybe-meta 'name) "Fiver") ; present meta







>
>
>
>
>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

(define (tx-strs xpr)
  (cond
    [(txexpr? xpr) (apply string-append (map tx-strs (get-elements xpr)))]
    [(string? xpr) xpr]
    [else ""]))

(define (first-words str n)
  (define trunc
    (apply string-append
         (add-between (take (string-split str) n) " ")))
  ;; Remove trailing punctuation (commas, etc.)
  (regexp-replace #px"\\W+$" trunc ""))

(module+ test
  (require rackunit)
  (define test-metas (hash 'name "Fiver" 'size "Small"))
  (define test-attrs '([name "Hazel"] [rank "Chief"]))

  (parameterize ([current-metas test-metas])
    (check-equal? (maybe-meta 'name) "Fiver") ; present meta

Modified sqlite-tools.rkt from [8c6dcaa3] to [8bbac284].

32
33
34
35
36
37
38

39
40
41
42
43
44
45
         racket/function
         racket/contract
         sugar/coerce)

(module+ test
  (require rackunit))


(provide sqltools:dbc
         sqltools:log-queries?)

(provide
 (contract-out
  ;; Utility functions
  [log-query                 (string? . -> . void?)]







>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
         racket/function
         racket/contract
         sugar/coerce)

(module+ test
  (require rackunit))

(provide (all-from-out db/base db/sqlite3))
(provide sqltools:dbc
         sqltools:log-queries?)

(provide
 (contract-out
  ;; Utility functions
  [log-query                 (string? . -> . void?)]

Modified template-html.rkt from [259532dd] to [add48486].

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
         html$-note-title
         html$-note-contents
         html$-note-listing-full
         html$-note-in-article
         html$-notes-section)

(define (html$-page-head [title #f])
  (define title-part (if title (format ": ~a" title) ""))
  ◊string-append{<head>
 <title>◊|title|</title>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <link rel="stylesheet" type="text/css" href="/web-extra/martin.css">
 </head>})

(define (html$-page-body-open)
  ◊string-append{<body><main>
 <a href="/"><header>
 <img src="/web-extra/logo.png" height="103" width="129" class="logo">
 <h1>The Local Yarn</h1>
 </header></a>})

(define (html$-article-open title-html-flow published)
  (define published (select-from-metas 'published (current-metas)))
  (cond
    [title-html-flow
     ◊string-append{<article class="with-title hentry">
      <h1 class="entry-title">◊|title-html-flow|</h1>
      <p class="time"><a href="#" class="rel-bookmark">
      <time datetime="◊published" class="published">◊ymd->english[published]</time>
      </a></p>
      <section class="entry-content">}]
    [else







<

|












|


|







37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
         html$-note-title
         html$-note-contents
         html$-note-listing-full
         html$-note-in-article
         html$-notes-section)

(define (html$-page-head [title #f])

  ◊string-append{<head>
 <title>◊if[title title ""] </title>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <link rel="stylesheet" type="text/css" href="/web-extra/martin.css">
 </head>})

(define (html$-page-body-open)
  ◊string-append{<body><main>
 <a href="/"><header>
 <img src="/web-extra/logo.png" height="103" width="129" class="logo">
 <h1>The Local Yarn</h1>
 </header></a>})

(define (html$-article-open title? title-html-flow published)
  (define published (select-from-metas 'published (current-metas)))
  (cond
    [title?
     ◊string-append{<article class="with-title hentry">
      <h1 class="entry-title">◊|title-html-flow|</h1>
      <p class="time"><a href="#" class="rel-bookmark">
      <time datetime="◊published" class="published">◊ymd->english[published]</time>
      </a></p>
      <section class="entry-content">}]
    [else

Modified template.html.p from [b0e9b3b5] to [406d1c49].

1
2




3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>




◊html$-page-head[(select-from-metas 'title here)]

◊html$-page-body-open[]

◊spell-of-summoning![]crystalize-article![here doc]

◊html$-page-body-close[]

</html>



>
>
>
>
|



<
|





1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
<!DOCTYPE html>
<html>
◊spell-of-summoning![]

◊(define article-html (crystalize-article! here doc))
◊(define page-title (article-plain-title here))
◊html$-page-head[page-title]

◊html$-page-body-open[]


◊article-html

◊html$-page-body-close[]

</html>