2016-11-26 8 views
1

私はTemplate Haskellにとって適切な場所であると思っていた興味深い問題に遭遇しました。私は、yesodとyesod-persistantを使用してデータベースにWebフロントエンドを取り組んでいます。私はmkPerist関数とpersistLowerCase準引用符を使って自分のデータベース型を生成しています。 私の問題は、データベースのフィールドを編集する方法が必要ですが、列ごとに6つの異なるページのためのハムレットコードを書くことは信じられないほど反復的なようです。 Template Haskellを使って、タイプが与えられたデータベースのその列を編集するためのテキストフィールドとチェックボックスを自動的に生成することができたと思いました。理想的には、型の名前をTemplate Haskell関数に渡して、THがページのHamletをすべて生成するようにするでしょう。私の質問は、Template Haskellをこのケースで使うことができますか?それは最善の解決策ですか?特に、Template Haskellは他の準引用符用のコードを生成できますか?特にハムレット?ここに私のプロジェクトへのリンクがあります:https://github.com/ProspectRidgeTech/PRADatabase事前に感謝! (PS。この問題にアプローチするより良い方法があるかどうか、私の質問に対する示唆された修正があるかどうか教えてください)テンプレートハスケルを使用してハムレットコードを生成することはできますか?

答えて

1

質問に答える:はい、私はそれをお勧めしません。準クォートは、単なる文字列を取り、いくつかのコードを生成する関数であるので、あなたは、あなたが

$(hamlet "blah blah") 

だから何もTHであなたを停止しないでそれを置き換える(または同等の)可能性が

[hamlet|blah blah|] 

を見たときコールハムレットに文字列を生成します。しかし、THのポイントの1つはタイプセーフティです。 文字列を生成してそれを解析し、そのオブジェクトを破棄します。また、この2ステップのコード生成はおそらくデバッグが難しいでしょう。

とにかく、永続エンティティ用のテーブルを生成するのが問題ならば、私はTHを必要とせず、永続フィールド情報を使用するだけと思います。私は同様の問題を抱え、エンティティのリストのHtmlテーブルを生成するコードを記述しました。入力を変更するのは難しいことではありません。

entitiesToTable :: PersistEntity a => (FieldDef -> Text) -> [Entity a] -> Html 
entitiesToTable getColumn entities = do 
    let eDef = entityDef (map entityVal entities) 
    [shamlet| 
<table.table.table-bordered.table-striped class="#{unHaskellName $ entityHaskell eDef}"> 
    <tr> 
    <th> Id 
    $forall field <- entityFields eDef 
     <th> #{getColumn field} 
    $forall Entity eit entity <- entities 
    <tr> 
     <td.id> #{renderPersistValue $ toPersistValue eit} 
     $forall (pfield, fieldDef) <- zip (toPersistFields entity) (entityFields eDef) 
     <td class="#{getHaskellName fieldDef}" > #{renderPersistValue $ toPersistValue pfield} 
|] 

フォームを処理してデータベースを更新するコードを書くことは、より難解でTHを必要とするかもしれませんが、このステップにはハムレットは含まれません。

+0

ありがとうございました! THを使わないでこの問題の少なくとも一部を解決できるかどうかは、それが最も確実な方法です。私はPersistentがこのようなタイプの情報を提供していることを知らなかった!迅速なフォローアップの質問として、パラメータ 'getColumn'はどこから来たのですか?特定の列からすべてのエンティティのリストを取得するために '(runDB $ selectList [] [])'のようなことをすることができますが、 '(FieldDef - > Text)'は何をしますか?また、これらの永続関数が定義されているモジュールにリンクすることはできますか?あなたの助けをありがとう! – thelostlambda

+0

'getColumn :: FieldDef - > Text'は、カラム名に使用するカラム定義から名前を抽出する単なる関数です。私は個人的に 'unDBNameを使用します。 fieldDB'のように変更することができます。 – mb14

+0

[there](https://hackage.haskell.org/package/persistent-2.6/docs/Database-Persist-Types.html) – mb14

関連する問題