4

少し前に同様の質問をしたと思いますが、APIが不安定なため回答がありませんでした。だから私は0.13が通り過ぎるのを待っていました。同様の質問をするのが正しいかどうかわかりません...?

runChildrenWith(Text)解釈さmapSplicesれ、コンパイルされたスプライスの世界に代わるものは何ですか? (この組み合わせが最も一般的なようです) 可能であれば、いくつかのコード例をいただければ幸いです。

私の理解が正しければ、すべてのアプリケーション スプライスをまとめて、heistInit. 誰でもそれを行う方法を教えてもらえますか?

スプライス バインディング タグは、アプリケーション全体で一意である必要がありますか?

utilising私が読んで学ぶことができるように、完成したスナッププロジェクトの新しい API とコンパイルされたスプライスはありますか?

ありがとうございました。

- アップデート -

以下の素晴らしい答え。しかし、残念ながら、一部のパーツ (レンズが付いているパーツ) はさらに混乱しました。私が正しく理解していれば、これは文字列を接合する簡単な方法です:

mySplice = "testSplice" ## testSplice
  where testSplice = return $ C.yieldRuntimeText $ do
          return "text to be spliced"

スプライスされた文字列を数回実行する必要がある場合、たとえば 5 つのテーブル raw で次のようにします。

mySplices = C.manyWithSplices C.runChildren mySplice

これは正しいです?

ヘイスト構成にスプライスを追加しようとすると、大量のエラーが発生します。

addConfig h $ mempty
 {
   hcCompiledSplices = "mySplice" ## mySplice -- or mySplices
 }

どこが間違っていますか?遅くなってごめんなさい。

私が本当に必要とするのは(今のところ理解できるように)、データベースから受け取った単純な文字列をつなぎ合わせて表示することだけです。

-- 更新 2 --

非常に役立つダニエルの回答のおかげで、私は最終的に何かを機能させることができます。

これまでのところ、コードの両方のバリアントが機能しています。

ダニエルのおかげで最初のもの

stringSplice :: Monad n => C.Splice n
stringSplice = C.manyWithSplices C.runChildren splicefuncs (return ["aa","bb","cc"])
  where
    splicefuncs = "string" ## (C.pureSplice . C.textSplice $ id)

そしてセカンド

testSplice :: C.Splice (Handler App App)
testSplice = return $ C.yieldRuntimeText $ return "text to be spliced"

どこ

(C.pureSplice . C.textSplice $ id)

と同様の結果を生成します

return $ C.yieldRuntimeText $ return "text to be spliced"

上記に違いはありますか?どちらかを優先するケースはありますか?それらは同じ結果を生み出すようです。

ドキュメントによると、コンパイルされた splices lib には「deferMany」関数があり、解釈された lib の mapSplices と同様の結果を生成します。「C.manyWithSplices C.runChildren」の組み合わせの代わりに使用できますか??

4

1 に答える 1

6

コンパイルされたスプライスを使用して人のリストに関する情報を表示したいとしましょう ( によって生成された足場から開始すると仮定しsnap initます)。

ダミー値を持つ非常に単純な_persons.tplテンプレートは次のようになります

<body>
    <person>
        <div>
            <h1><name>dummy name</name></h1>
            <p><age>77</age></p> 
            <p><location>jauja</location></p> 
        </div>
    </person>
</body>

personnameage、およびは接合locationするタグです。

情報を保持する簡単な Snaplet を定義します

data Foo = Foo
    {
        _persons :: [Person]
    }

makeLenses ''Foo

data Person = Person
    {
        _name :: Text
    ,   _age :: Int
    ,   _location :: Text
    }   

makeLenses ''Person

それをAppレコードに追加します。

data App = App
    { _heist :: Snaplet (Heist App)
    , _sess :: Snaplet SessionManager
    , _auth :: Snaplet (AuthManager App)
    , _foo :: Snaplet Foo
    }

アプリ初期化子に以下を追加します

f <- nestSnaplet "foo" foo $ makeSnaplet "foo" "Foo Snaplet" Nothing $ return $ Foo $ 
        [ Person "Ricardo" 33 "Los Cantones" 
        , Person "Luis" 38 "Montealto" 
        ]

...

return $ App h s a f

viewこの関数は、( from を使用してControl.Lens)人物のリストを返す Handler を構築します。

personH :: SnapletLens b Foo -> Handler b b [Person] 
personH l = withTop l $ view persons <$> get 

RuntimeSpliceこの関数は、Personのリストを生成するから適切なコンパイル済みスプライスを構築します。RuntimeSplices は、ロード時ではなく、実行時にのみ知ることができる情報を表します。

personSplice :: Monad n => RuntimeSplice n [Person] -> C.Splice n
personSplice = C.manyWithSplices C.runChildren splicefuncs 
    where
    splicefuncs = mconcat  
        [ "name" ## (C.pureSplice . C.textSplice $ view name)
        , "age" ## (C.pureSplice . C.textSplice $ T.pack . show . view age)
        , "location" ## (C.pureSplice . C.textSplice $ view location)
        ]

また、この関数を使用して、スプライスをグローバル Heist 構成に登録できます。を に持ち上げることに注意してHandlerくださいRuntimeSplice

addPersonSplices :: HasHeist b => Snaplet (Heist b) -> 
                                  SnapletLens b Foo -> 
                                  Initializer b v ()
addPersonSplices h l = addConfig h $ mempty 
   {
      hcCompiledSplices = "person" ## (personSplice . lift $ personH l) 
   } 

次の行をアプリの初期化子に必ず追加してください。

addPersonSplices h foo

そして、次のペアをアプリのルートに追加するには:

("/persons",  cRender "_persons")

サーバーを実行すると、に移動するとhttp://127.0.0.1:8000/personsリストが表示されます。

アップデート

文字列のリストのみを表示する単純なケース (複雑なレコードもレンズも使用しない) の場合。

テンプレートは次のようになります。

<body>
    <strings>
        <p><string>dummy value</string></p>
    </strings>
</body>

最上位のスプライスは次のようになります。

stringSplice :: Monad n => C.Splice n
stringSplice = C.manyWithSplices C.runChildren splicefuncs (return ["aa","bb","cc"])
    where
    splicefuncs = "string" ## (C.pureSplice . C.textSplice $ id)

これは、「このスプライスに関連付けられたタグに遭遇すると、文字列のリストを生成するアクションを実行し、文字列ごとにタグの内容をレンダリングして、タグを現在の文字列に置き換える」ことを意味しますstring

manyWithSplicesの署名により、 の右側にあるもの(##)が type を持つように強制されることに注意してくださいRuntimeSplice n Text -> Splice n。ここidに type がありText -> Textます。C.TextSpliceそれを 型のものに変換し、 への最終的な変換を実行しText -> Builderます。C.pureSpliceRuntimeSplice n Text -> Splice n

代わりに(return ["aa","bb","cc"])、データベースに接続してそこから文字列を抽出する、より複雑なアクションを提供できます。

このスプライスを登録する関数は次のようになります。

addStringSplices :: HasHeist b => Snaplet (Heist b) -> Initializer b v ()
addStringSplices h = addConfig h $ mempty 
    {
          hcCompiledSplices = "strings" ## stringSplice
    }  
于 2013-10-23T23:40:15.353 に答える