読者です 読者をやめる 読者になる 読者になる

あのねノート

せんせいあのね、パソコンで字が書けるようになったよ

ブログに投稿機能をつける~Racketチュートリアル中級編をやってみた(第2回)

勉強 Racket

めげずに第2回です。第1回では中級チュートリアル(Continue: Web Applications in Racket)第4章まで進みました。
第1回はこちら↓
momo-moemoe.hatenablog.com

第1回まででブログのタイトルと本文を合わせた構造体postとそのリストBLOGを定義し、ブラウザの画面に表示できるようにしました。
ここまでの状態だと新規投稿をする際、ソースコードをいじってリストBLOGの中に新たなpost構造体を追加しなければなりませんが、ここからはページ上から新たな投稿を追加できるようにするみたいです。
実現するために、requestの部分を書き換えるみたいです。

(define (start request)
  (define a-blog
    (cond [(can-parse-post? (request-bindings request))
           (cons (parse-post (request-bindings request))
                 BLOG)]
          [else
           BLOG]))
  (render-blog-page a-blog request))

condの中身も四角いカッコにしていいんですね…数学の大かっこみたいなイメージなのかしら。can-parse-post?の説明がまだなのでどんな条件かわかりませんが、can-parse-post?が#fなら従来と同様にBLOGをページに表示したらいいようです。

(define (can-parse-post? bindings)
  (and (exists-binding? 'title bindings)
       (exists-binding? 'body bindings)))

exists-binding?という条件が必要みたい。チュートリアルの英語コメントを読む限り、bindings(って何なんだろう…)がtitleとbodyとしての値をそれぞれ持つかどうかを判定する関数のようです。

;parse-port:binding->post
;bindingを受け取ってpost構造体にして返す
(define (parse-post bindings)
  (post (extract-binding/single 'title bindings)
        (extract-binding/single 'body bindings)))

うーん、ユーザーが書きこんだ新規投稿がbindingsになるってことかしら。それならそのbindingsをpostに置き換えてBLOGに追加すればできそうな感じがします。

ここまでの定義に対応してrender-blog-pageも書きかえる必要があります。

(define (render-blog-page a-blog request)
  (response/xexpr
   `(html (head (title "My Blog"))
          (body
           (h1 "My Blog")
           ,(render-posts a-blog)
           (form
            (input ((name "title")))
            (input ((name "body")))
            (input ((type "submit"))))))))

下の方に入力フォームらしきものが!なるほど、そこに入力したものを取り込むわけですね。

あとは変更がないようです。bindingって何なんだろうな~という感じですがどうやら入力関係っぽい。
実行するとこんな感じ。入力窓ができています。
f:id:momo_moemoe:20160814225216p:plain

書き込みもできました。
f:id:momo_moemoe:20160814225354p:plain
f:id:momo_moemoe:20160814225356p:plain

しかしもう1つ書き込みをしようとすると
f:id:momo_moemoe:20160814225629p:plain
f:id:momo_moemoe:20160814225638p:plain
上書きされてしまう…!ううどうしよう、というわけで次に続きます。1章しか進んでません。