前回の続き。オレオレテンプレートの作り方をみてみる(*´ω`*)
公式ドキュメントだとこのあたり。
雛形の作成
$ mason new example ✓ Generated 5 file(s). (34ms) created example/brick.yaml created example/README.md created example/CHANGELOG.md created example/LICENSE created example/__brick__/HELLO.md
Bricksの構成
mason newを実行するとこれらを作ってくれる。
example/ ├── CHANGELOG.md ├── LICENSE ├── README.md ├── __brick__ │ └── HELLO.md └── brick.yaml
メインは__brick__とbrick.yamlの2つ。
brick.yaml
brick.yamlはbrickのマニフェストファイル。
名前(name)、説明(description)や受け取る引数(vars)を定義。
name: example description: A new brick created with the Mason CLI. version: 0.1.0+1 environment: mason: ">=0.1.0-dev.50 <0.1.0" vars: name: type: string description: Your name default: Dash prompt: What is your name?
__brick__
テンプレートの本体。HELLO.mdはこんな感じ。
# Hello {{name}}!
テンプレートの記法はmustache
- mustache/mustache.github.com: The {{official}} website
- mustache specification
- 各言語の実装されている: {{ mustache }}
- jonahwilliams/mustache: Mustache template Dart library
masonはこれを利用
- janl/mustache.js: Minimal templating with {{mustaches}} in JavaScript
- HandlebarsもMustache-compatible
- samskivert/jmustache: A Java implementation of the Mustache templating language.
- OpenAPI Generatorでも利用: Using Templates | OpenAPI Generator
- jonahwilliams/mustache: Mustache template Dart library
mustache記法
テンプレートの書き方はこのあたりを見るといい感じ。
- 🥸 Brick Syntax | BrickHub Docs
- mustache(5) - Logic-less templates.
- jonahwilliams/mustache: Mustache template Dart library
基本的な書き方
{{! コメント }}
{{! ** 変数 }}
{{name}} {{! HTMLエスケープあり }}
{{{name}}} {{! HTMLエスケープなし }}
{{! ** 分岐 }}
{{#flag}}
<b>trueの場合</b>
{{/flag}}
{{^flag}}
<b>falseの場合</b>
{{/flag}}
{{! ** ループ }}
{{#items}}
<b>{{name}}</b>
{{/repo}}
{{! ** 関数 }}
{{name.pascalCase()}}
使える関数(Lambdas)はこのあたり。
camelCase,constantCase,dotCaseなどいろいろある。
分岐とループが同じ{{# }}なのでパッと見分かりづらい。。
ファイルパス
ファイル名を動的に決めたい場合は、
ファイル名自体にmustacheを含めればOK
__brick__/{{name.snakeCase()}}.md
ファイル名だけじゃなく、パスを含めて動的に決める場合は、
{{% %}}を利用する。
__brick__/{{% url %}}というファイルがある場合、
mason make app_icon --url path/to/icon.pngとすると、
urlで指定したpath/to/icon.pngというファイルが作成される。
テンプレートの共通化/include
テンプレート内で他のテンプレートを使い回せるPartialsという機能もある。
例えば、ヘッダやフッタは共通化したいときなど。スニペット的なやつ。
{{~ xxx }}というファイルを用意すると他のテンプレートからincludeでき、
実行時に生成の対象にはならない。
├── HELLO.md
├── {{~ footer.md }}
└── {{~ header.md }}
Partialsをincludeするときは{{> xxx }}を使えばOK。
HELLO.mdの例だとこんな感じ。
{{> header.md }}
Hello {{name}}!
{{> footer.md }}
HELLO.md以外でも同じheader/footerを使いたい場合に便利。
もちろん、Partials内でも変数などは利用できる。
hooks
実行前後に追加処理を設定することもできる。
mason new example --hooksという感じに、
--hooksをつけるとhooks/ディレクトリも作成してくれる。
├── __brick__
├── brick.yaml
└── hooks
├── post_gen.dart
├── pre_gen.dart
└── pubspec.yaml
pre_gen.dartは実行前の処理。
変数の読み取りや追加などの例。
// pre_gen.dart import 'dart:io'; import 'package:mason/mason.dart'; void run(HookContext context) { // Read vars. final name = context.vars['name']; // Use the `Logger` instance. context.logger.info('Hello $name!'); // Update vars. context.vars['current_year'] = DateTime.now().year; }
post_gen.dartは実行後の処理。
flutter packages getを実行する例。
// post_gen.dart import 'dart:io'; import 'package:mason/mason.dart'; Future<void> run(HookContext context) async { final progress = context.logger.progress('Installing packages'); // Run `flutter packages get` after generation. await Process.run('flutter', ['packages', 'get']); progress.complete(); }
作ったbrickを利用する
他のbrickと同様、mason.yamlに指定すればOK
bricks: # 公開されているbrick: brick名を指定 hello: 0.1.0+1 # Git上のbrick: URLとパスを指定 widget: git: url: https://github.com/felangel/mason.git path: bricks/widget # ローカルのbrick: パスを指定 example: bricks/example
mason addを利用する場合はこんな感じ。
$ mason add example --path bricks/example
おまけ: Bundle
作成したbrickをアプリに含めたり、アップロードしやすくなるよう、
1ファイルにまとめる機能がある。
$ mason new example --hooks $ mason bundle ./example/ -o ./bundle/ $ ls ./bundle example.bundle $ mason bundle ./example/ -t dart -o ./bundle/ $ ls ./bundle example_bundle.dart
バンドルには2つの形式があり、デフォルトはUniversal。
Dartを利用したい場合は-t dartをつけて実行する。
Universal- a platform-agnostic bundle primarily used when publishing to BrickHubDart- a Dart specific bundle which can be used to programmatically generate code from a brick in other Dart applications
バンドルをもとに戻すときは、mason unbundleを使う。
# Universal Bundle mason unbundle ./path/to/bundle -o ./path/to/destination/ # Dart Bundle mason unbundle ./path/to/bundle -t dart -o ./path/to/destination/
また、アプリ内でバンドルを利用する場合は、こんな感じらしい。
./path/to/my/bundle.dartは-t dartをつけたバンドル。
import 'package:mason/mason.dart'; import './path/to/my/bundle.dart'; Future<void> main() async { // Create a MasonGenerator from the existing bundle. final generator = MasonGenerator.fromBundle(myBundle); // Generate code based on the bundled brick. await generator.generate(...); }
以上!! なんかオレオレbrickが書ける気がしてきた(*´ω`*)