YesodのdefaultLayout

defaultLayoutがどうなっているのか気になったので、ソースコードを追いかけてみた。

messageの処理とwidget埋め込みをやるようになっていた。

defaultLayout :: GWidget sub a () -> GHandler sub a RepHtml
defaultLayout w = do
    p <- widgetToPageContent w
    mmsg <- getMessage
    hamletToRepHtml [hamlet|
$newline never
$doctype 5

<html>
    <head>
        <title>#{pageTitle p}
        ^{pageHead p}
    <body>
        $maybe msg <- mmsg
            <p .message>#{msg}
        ^{pageBody p}
|]

ProductName Developing Web Applications With Haskell and Yesod
Michael Snoyman
Oreilly & Associates Inc / 2805円 ( 2012-05-04 )


カクレモモジリ

捕まえた

1357096004

捕獲方法

あけましておめでとうございます

去年とは違い、まったりと年を越した。

1356990296 1356990299

今年はHaskellでひとつくらいはウェブアプリケーションを作るのと、AlloyでつくったiPhoneアプリを幾つかリリースできればと思っている。

それから山歩きくらいは再開したい。

飯綱高原スキー場に行ったら空いてて最高だった(レンタルボード以外は)

子供の雪遊びのために、そり遊びしてきた。それほど混んでなくて良かった。昨日の雨でちょっとアイスバーンっぽくなっていたけどソリにはまったく関係ないし。

1356939803

もともと、子供の面倒を見るつもり120%だったので、板を持っていかなかったのだけど、ちょっと滑れそうだったのでレンタルした。

けど、短いのしかないし、ビンががたがたしてるし、右足マイナス振ってないし(これはしょうがないけど)で、4,5本滑ったら良くなってしまった。

夜に美味しいワインが控えているので疲れる前にやめておいた。

というわけで今年の更新は最後だ。今からワインをがぶがぶしてくる。

YesodでAjax

Yesod本の写経。addJullius, AddHamletでtoWidgetを使えというdeprecated warningが出たので本家サイトのように書きなおした。

hamletはtoWidgetよりはwhamletのほうが見やすいかな。

{-# LANGUAGE QuasiQuotes, TypeFamilies, OverloadedStrings #-}
{-# LANGUAGE MultiParamTypeClasses, TemplateHaskell #-}

import Yesod
data R = R

mkYesod "R" [parseRoutes|
/ RootR GET
/#String NameR GET
|]

instance Yesod R

getRootR = defaultLayout $ do
  setTitle "Homepage"
  addScriptRemote "http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"
  toWidget [julius|
$(function(){
  $("#ajax a").click(function(){
    jQuery.getJSON($(this).attr("href"), function(o){
      $("div").text(o.name);
    });
    return false;
  });
});
|]

  let names = words "Larry Moe Curly"
  [whamlet|
<h2>AJAX Version
<div #results>
  AJAX results will be placed here when you click #
  the names below
<ul #ajax>
  $forall name <- names
    <li>
      <a href=@{NameR name}>#{name}
<h2>HTML Version
<p>
  Clicking the names below will redirect the page #
  to an HTML version
<ul #html>
  $forall name <- names
    <li>
      <a href=@{NameR name}>#{name}
|]

getNameR name = do
  let widget = do
        setTitle $ toHtml name
        [whamlet|Looks like you have Javascript off Name: #{name}|]
  let json = object ["name" .= name]
  defaultLayoutJson widget json

main = warpDebug 3000 R

ProductName Developing Web Applications With Haskell and Yesod
Michael Snoyman
Oreilly & Associates Inc / 2805円 ( 2012-05-04 )


長野に遊びにきた

流れで、長野で年越しをすることになった。獺祭久しぶりに飲んだわ。

1356901647

ひたし豆

1356901645

わらび

1356901640

つけもの。奈良漬けが美味しかった。

1356901641

きりたんぽ。鶏が重要なファクター

1356901644

YesodのWidgetsとMessage

Yesodを使ってみて混乱したのがどこまでがHamletの構文でどこからがYesodの拡張なのだろうかというあたり。

WidgetsはYesodで追加された仕組みで、whamletとか^{footer}といった記法もYesodのものだと理解した。ついでにCore見て確認しておいた。

{-# LANGUAGE OverloadedStrings, TypeFamilies, TemplateHaskell,
             QuasiQuotes, MultiParamTypeClasses #-}
import Yesod

data Messages = Messages

mkYesod "Messages" [parseRoutes|
/            RootR       GET
/set-message SetMessageR POST
|]

instance Yesod Messages where
  defaultLayout widget = do
    pc <- widgetToPageContent widget
    mmsg <- getMessage
    hamletToRepHtml [hamlet|
$doctype 5
<html>
  <head>
    <title>#{pageTitle pc}
    ^{pageHead pc}
  <body>
    $maybe msg <- mmsg
      <p>Your message was: #{msg}
    ^{pageBody pc}
|]

instance RenderMessage Messages FormMessage where
  renderMessage _ _ = defaultFormMessage

getRootR :: Handler RepHtml
getRootR = defaultLayout $ do
  setTitle "My Page Title"
  toWidget [lucius| p { color: red; } |]
  toWidgetHead [hamlet| <meta name=keywords content="session sample">|]
  [whamlet|
<form method=post action=@{SetMessageR}>
             My Message is: #
             <input type=text name=message>
             <input type=submit>
|]

postSetMessageR :: Handler ()
postSetMessageR = do
  msg <- runInputPost $ ireq textField "message"
  setMessage $ toHtml msg
  redirect RootR

main :: IO ()
main = warpDebug 3000 Messages

Wisgetsのようにjs,css,htmlをまとめて管理できる仕組みはいいかもと思う反面、デザイナーとの分業って難しくなるんじゃないのかなぁと思うんだけどどうなんだろ?僕の場合は全部独りでやるからこういう仕組みのほうがあってるかなと思うんだけど。

それからcssの設定とか競合しないもんかね?

ProductName Developing Web Applications With Haskell and Yesod
Michael Snoyman
Oreilly & Associates Inc / 2805円 ( 2012-05-04 )


BlazeHtmlを使ってみた

高速だと言われているBlazeHtmlのチュートリアルをトレースしてみた。

{-# LANGUAGE OverloadedStrings #-}

import Control.Monad (forM_)
import Text.Blaze.Html5 
import qualified Text.Blaze.Html5 as H
import Text.Blaze.Html.Renderer.String

numbers :: Int -> Html
numbers n = docTypeHtml $ do
            H.head $ H.title "BlazeTest"
            H.body $ do
              p "A list of natural numbers:"
              ul $ forM_ [1 .. n] (li . toHtml)

main :: IO ()
main = putStrLn $ renderHtml $ numbers 5

あれ、このヒトってHakyllの作者じゃないか。

APIドキュメント見たら、やはりHakyll.Web.Blazeで使えるようになっていた。

shakespeare-textで値を文字列に埋め込む

Shakespearean Templatesを読んでいてHTML,CSS,Javaxcriptじゃなくてふつうの文字列でもデータ埋め込みが出来ることを知った。

{-# LANGUAGE QuasiQuotes, OverloadedStrings #-}
import Text.Shakespeare.Text
import qualified Data.Text.Lazy.IO as TLIO
import Data.Text (Text)
import Control.Monad (forM_)

data Item = Item
    { itemName :: Text
    , itemQty :: Int
    }

items :: [Item]
items =
    [ Item "apples" 5
    , Item "bananas" 10
    ]

main :: IO ()
main = forM_ items $ \item -> TLIO.putStrLn
    [lt|You have #{show $ itemQty item} #{itemName item}.|]

pythonのformatメソッドのように使えそうだ。

ProductName Developing Web Applications With Haskell and Yesod
Michael Snoyman
Oreilly & Associates Inc / 2805円 ( 2012-05-04 )


ペーパーマリオ スーパーシール面白い

本を100冊位処分したら4000円くらいになったので子供の暇つぶし用にペーパーマリオを買ってやったんだが、これはなかなかおもしろい。

ProductName ペーパーマリオ スーパーシール

任天堂 / 3891円 ( 2012-12-06 )


アクションを極めなくても、コインとスロットと強力なシールを組み合わせれば子供でも進めていけそうだし、バランス良くできているなぁと思った。