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

あのねノート

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

ユーザ間でブログの内容を同期する~Racketチュートリアル中級編をやってみた(第4回)

勉強 Racket

まだまだ形にならないのでせっせと進めていきます。
チュートリアルはこちら↓
Continue: Web Applications in Racket

中級チュートリアル第1回はこちら↓
momo-moemoe.hatenablog.com

前回は、新規投稿したあと別ユーザーがブログを表示すると初期状態から始まってしまう(新規投稿した記事がない)状態になっていました。
別々のブラウザで独立してブログを表示する状態なのが問題なわけで、それを解決していきます。

ブログを変更可能にしないといけないので、postのリストであるblog構造体を作って、mutableにします。

;blogの構造体も定義する
;postsはpostのリスト
(struct blog (posts) #:mutable)

初期状態であるBLOGもblog構造体に入れないといけません。

;ブログ本体
(define BLOG (blog (list (post "ふたつめ"
                         "表示されてるかな?")
                   (post "ひとつめ"
                         "はじめてだよ!")
                   )))
;blog-insert-post!:blog post->void
;blog構造体とpost構造体を1つずつ受け取って、post構造体をblog構造体に追加する
(define (blog-insert-post! a-blog a-post)
  (set-blog-posts! a-blog
                   (cons a-post (blog-posts a-blog))))

書き換え→破壊的代入なのでset!って感じなのかな。

start関数にはBLOGが要らなくなるみたいです。確かに、BLOGつけたままだと呼び出すたびに初期状態BLOGが来てしまいそう。

(define (start request)
  (render-blog-page request))

render-blog-pageもresponseを返さなくなります。

(define (render-blog-page request)

  (define (response-generator embed/url)
    (response/xexpr
     `(html (head (title "My Blog"))
            (body
             (h1 "My Blog")
             ,(render-posts)
             (form ((action ;入力フォーム
                     ,(embed/url insert-post-handler))) ;入力フェーズへの遷移
                   (input ((name "title")))
                   (input ((name "body")))
                   (input ((type "submit"))))))))
 
  (define (insert-post-handler request)
    (blog-insert-post! ;新規投稿を追加
     BLOG (parse-post (request-bindings request)))
    (render-blog-page request))
  
  (send/suspend/dispatch response-generator))

新規投稿を追加する関数がblog-insert-post!に変わったので変更されています。あとrender-postsの引数が消えた。

問題のrender-postsです。

(define (render-posts)
  `(div ((class "posts"))
        ,@(map render-post (blog-posts BLOG))))

初期状態にblog構造体の持つリストpostsを追加する形になってるから引数が要らないみたい。

実行してみると、別ウインドウから開き直しても新たに更新した後のページが表示されるようになっていました。

次はコメントを追加できるようにするみたいです。