kamidanacookiecutterのプロジェクトテンプレート上でsnakecase,kebabcase,camelcaseの変換のjinja2フィルターが使いたくなった。cookiecutter?scaffold用のツール。今の所python界隈で一番メジャー。github.comこのcookiecutterのscaffoldの最中で良い感じに自分独自のjinja2フィルターなどを使いたい。camelcaseはjinja2のフィルター。なって欲しい{{"fooBarBoo"|snakecase}}この記事中での依存関係は、kamidanaもcookiecutterもjinja2に依存しているということだけわかっていれば大丈夫。filter?フィルターの組み込みや実装自体の方法は以下のjinja2自体のドキュメントに書いてある。http://jinja.pocoo.org/docs/2.10/api/#custom-filtersざっくり言うと、jinja2.Environmentのfiltersやglobalsといったフィールドに良い感じに辞書を与えてあげれば良い。modulesというコンセプトがある(単に自分がそう呼んでいるだけだけれど)。modulesがある。以下の様な形で使える。{{"foo_bar_boo"|camelcase}}変換後。fooBarBooこの機能をcookiecutterでも使いたい。templateそもそもcookiecutterの利用方法がわからないと利用イメージがつかなそうな気がする。worldレベル)詳しいことが知りたかったり他の説明を読みたい場合には、一番分かりやすそうな説明はこのあたり。https://cookiecutter.readthedocs.io/en/latest/first_steps.html?highlight=Hello一番くわしい説明はこのあたりhttps://raphael.codes/blog/create-your-own-cookiecutter-template/かも。プロジェクトテンプレートの使いかたまず前提として、今回の例は以下のような構造。fileshelloというプロジェクトテンプレートから出力したときの生成結果が00out。これを生成するときのコマンドは以下。--no-inputを付けているのでデフォルトの値がそのまま利用されている。00outしているけれど、単にoverwriteしたいだけなら-fオプションを付けるだけでも良い。あとどのような機能が裏で動いているかわかりやすいように-vオプションを付けている。雑に言えば、以下の2つから良い感じに生成してくれるというようなもの。詳しくはドキュメントを。雛形となるディレクトリを作る。ディレクトリ名やファイル名にもjinja2テンプレートの記法が使えるところが特徴。{{cookiecutter.file_name}}.py。後者は出力後Howdy.pyになる。前者はデフォルトの設定として扱われる。prefix付きで利用できる。ここでHello.pyは以下のようなもの。{{cookiecutter.greeting_recipient}}!")つまりディレクトリも含めてjinja2テンプレート。テンプレートに渡すパラメーターを対話によって決める(あるいはJSONファイルとして渡す)。いうのがcookkiecutterのプロジェクトテンプレートということになる。プロジェクトテンプレートでsnakecase,kebabcase,camelcaseがしたいというところまでが説明のための準備でようやく本題。db名だったりファイル名だったりである特定の部分ではkebabcaseで、基本snakecase。JSとのやり取りの部分はcamelcaseなどということはまぁふつうにある。cookiecutterのプロジェクトテンプレートにこれらの機能を含んだもの渡したいということになるがその方法がなかなか見つからない。Contextの機能は期待したものとは異なりprimitiveな値(JSONで表現できるような値)程度しか送ることができない模様。無難なのはjinja2のExtensionを利用する方法。filters関係の議論で一番参考になりそうなのはこのPR(Openのまま)。Extensionでやりましょう説が濃厚。読み込んでくれるらしい。Extensionが使えるようになる。["jinja2_time.TimeExtension"]}jinja2のExtensionの定義jinja2のExtensionの定義自体はjinja2のドキュメントに書いてある。modulesをforwardingしてあげるようなExtensionを用意すれば良い。機能が便利なのでここで紹介。何やら表示が色々増えましたねという感じなのだけれど。そのままkebabcase,snakecaseなどが使えるようになるだけの穏やかな実装。それらが使いたいだけならこれを使うと良い。cookiecutter.jsonに以下の様な記述が増えることになる。["kamidana.extensions.NamingModuleExtension"]...}ただし、このように必要な機能の毎にExtensionを追加していく方針では、必ずExtensionを作らなくてはいけない。packageとしてimport可能な場所に置いておかなければいけない。いう注意事項が付いてくる。modulesとして読み込まれる)。いえkamidanaのコンセプトを尊重するのなら必要な機能ということで頑張った。実装自体もコールスタックを覗くというちょっとした黒魔術が入っている。いうフィールドを用意した形。kebabcaseなどをこのExtension経由で使いたい場合にはcookiecutter.jsonに以下の様な設定が追加される。参考になるかもしれない。出力結果)↑のexamplesでは以下のようなcookiecutter.jsonが使われている。"data.txt").rstrip()そしてtemplate中では以下のような形で使われている。modules"""{{about_kamidana()}}"""出力結果は以下のようなもの。ちなみに、コードが壊れていないか担保するCIの設定も実はちょっとおもしろいので参考になる人もいるかもしれない。diffでの差分がないことをokとする(ビジュアル?)リグレッションテスト。--addtionalsというオプションの名前が良くない。componentという機能を追加した月別アーカイブはてなブログをはじめよう!podhmoさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。