-
-
Notifications
You must be signed in to change notification settings - Fork 333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Translate Leaf to Japanese #1005
Changes from all commits
b7311dd
ae66e50
6d616f5
e9d7a60
2844462
293824c
820ab00
674c164
b33141d
2bcc80b
862d3ba
eb1634f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# カスタムタグ | ||
|
||
[`LeafTag`](https://api.vapor.codes/leafkit/documentation/leafkit/leaftag) プロトコルを使用して、カスタム Leaf タグを作成することができます。 | ||
|
||
これを実際に試してみるために、現在のタイムスタンプを表示するカスタムタグ `#now` を作成してみましょう。このタグは、日付形式を指定するためのオプションのパラメータもサポートします。 | ||
|
||
!!! tip | ||
もしカスタムタグが HTML をレンダリングする場合は、HTML がエスケープされないように、`UnsafeUnescapedLeafTag` に準拠させる必要があります。ユーザー入力のチェックやサニタイズを忘れないようにしましょう。 | ||
|
||
## `LeafTag` | ||
|
||
まず、`NowTag` というクラスを作成し、`LeafTag` に準拠させます。 | ||
|
||
```swift | ||
struct NowTag: LeafTag { | ||
func render(_ ctx: LeafContext) throws -> LeafData { | ||
... | ||
} | ||
} | ||
``` | ||
|
||
次に、`render(_:)` メソッドを実装します。このメソッドに渡される `LeafContext` は、必要なすべての情報を持っています。 | ||
|
||
```swift | ||
enum NowTagError: Error { | ||
case invalidFormatParameter | ||
case tooManyParameters | ||
} | ||
|
||
struct NowTag: LeafTag { | ||
func render(_ ctx: LeafContext) throws -> LeafData { | ||
let formatter = DateFormatter() | ||
switch ctx.parameters.count { | ||
case 0: formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" | ||
case 1: | ||
guard let string = ctx.parameters[0].string else { | ||
throw NowTagError.invalidFormatParameter | ||
} | ||
|
||
formatter.dateFormat = string | ||
default: | ||
throw NowTagError.tooManyParameters | ||
} | ||
|
||
let dateAsString = formatter.string(from: Date()) | ||
return LeafData.string(dateAsString) | ||
} | ||
} | ||
``` | ||
|
||
## タグの設定 | ||
|
||
`NowTag` を実装したので、Leaf にそれを伝えるだけです。このようにして、たとえ別のパッケージで定義されたタグでも追加することができます。通常、これを `configure.swift` で行います: | ||
|
||
```swift | ||
app.leaf.tags["now"] = NowTag() | ||
``` | ||
|
||
これで完了です!Leaf でカスタムタグを使用できるようになりました。 | ||
|
||
```leaf | ||
The time is #now() | ||
``` | ||
|
||
## コンテキストプロパティ | ||
|
||
`LeafContext` には、重要なプロパティが 2 つあります。それが `parameters` と `data` です。この 2 つで必要な情報はすべて揃っています。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
- `parameters`: タグのパラメータを含む配列です | ||
- `data`: コンテキストとして `render(_:_:)` に渡されたビューのデータを含む辞書です | ||
|
||
### Hello タグによる実例 | ||
|
||
これを理解するために、両方のプロパティを使ったシンプルな hello タグを実装してみましょう。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
|
||
#### parameters の使用 | ||
|
||
nameの値が提供される、1つ目のパラメータにアクセスできます | ||
|
||
```swift | ||
enum HelloTagError: Error { | ||
case missingNameParameter | ||
} | ||
|
||
struct HelloTag: UnsafeUnescapedLeafTag { | ||
func render(_ ctx: LeafContext) throws -> LeafData { | ||
guard let name = ctx.parameters[0].string else { | ||
throw HelloTagError.missingNameParameter | ||
} | ||
|
||
return LeafData.string("<p>Hello \(name)</p>") | ||
} | ||
} | ||
``` | ||
|
||
```leaf | ||
#hello("John") | ||
``` | ||
|
||
#### data の使用 | ||
|
||
data プロパティの中の "name" キーを使って名前の値にアクセスします。 | ||
|
||
```swift | ||
enum HelloTagError: Error { | ||
case nameNotFound | ||
} | ||
|
||
struct HelloTag: UnsafeUnescapedLeafTag { | ||
func render(_ ctx: LeafContext) throws -> LeafData { | ||
guard let name = ctx.data["name"]?.string else { | ||
throw HelloTagError.nameNotFound | ||
} | ||
|
||
return LeafData.string("<p>Hello \(name)</p>") | ||
} | ||
} | ||
``` | ||
|
||
```leaf | ||
#hello() | ||
``` | ||
|
||
_Controller_: | ||
|
||
```swift | ||
return try await req.view.render("home", ["name": "John"]) | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
# Leaf | ||
|
||
Leaf は、Swift にインスパイアされた構文を持つ強力なテンプレート言語です。これを使って、フロントエンドのウェブサイト向けに動的な HTML ページを生成したり、API から送信するリッチなメールを生成したりできます。 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Template Syntaxがあるので、Template Languageと混合しないためにはテンプレート言語の方が良さそうですね |
||
|
||
## Package | ||
|
||
Leaf を使用する最初のステップは、プロジェクトの SPM パッケージマニフェストファイルに依存関係として追加することです。 | ||
|
||
```swift | ||
// swift-tools-version:5.8 | ||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "MyApp", | ||
platforms: [ | ||
.macOS(.v10_15) | ||
], | ||
dependencies: [ | ||
/// Any other dependencies ... | ||
.package(url: "https://github.com/vapor/leaf.git", from: "4.4.0"), | ||
], | ||
targets: [ | ||
.target(name: "App", dependencies: [ | ||
.product(name: "Leaf", package: "leaf"), | ||
// Any other dependencies | ||
]), | ||
// Other targets | ||
] | ||
) | ||
``` | ||
|
||
## 設定 | ||
|
||
パッケージをプロジェクトに追加したら、Vapor を設定してそれを使用するように構成します。これは通常、[`configure.swift`](../getting-started/folder-structure.md#configureswift) で行います。 | ||
|
||
```swift | ||
import Leaf | ||
|
||
app.views.use(.leaf) | ||
``` | ||
|
||
これにより、コード内で `req.view` を呼び出すと、Vapor が `LeafRenderer` を使用するように指示します。 | ||
|
||
!!! note | ||
Leaf には、ページをレンダリングするための内部キャッシュがあります。`Application` の環境が `.development` に設定されている場合、このキャッシュは無効になり、テンプレートへの変更が即座に反映されます。`.production` やその他の環境では、キャッシュがデフォルトで有効になっており、テンプレートに加えた変更はアプリケーションを再起動するまで反映されません。 | ||
|
||
!!! warning | ||
Xcode から実行する際に Leaf がテンプレートを見つけられるようにするためには、 Xcode ワークスペースの [custom working directory](../getting-started/xcode.md#_1) を設定する必要があります。 | ||
## フォルダ構成 | ||
|
||
Leaf を設定したら、`.leaf` ファイルを格納するための `Views` フォルダを用意する必要があります。デフォルトでは、Leaf はプロジェクトのルートに対して `./Resources/Views` というフォルダを要求します。 | ||
|
||
JavaScript や CSS ファイルを提供する予定がある場合は、Vapor の [`FileMiddleware`](https://api.vapor.codes/vapor/documentation/vapor/filemiddleware) を有効にして、 `/Public` フォルダからファイルを提供できるようにすることも可能です。 | ||
|
||
``` | ||
VaporApp | ||
├── Package.swift | ||
├── Resources | ||
│ ├── Views | ||
│ │ └── hello.leaf | ||
├── Public | ||
│ ├── images (images resources) | ||
│ ├── styles (css resources) | ||
└── Sources | ||
└── ... | ||
``` | ||
|
||
## Viewのレンダリング | ||
|
||
Leaf が設定できたので、最初のテンプレートをレンダリングしてみましょう。`Resources/Views` フォルダ内に、次の内容で `hello.leaf` という新しいファイルを作成します。 | ||
|
||
```leaf | ||
Hello, #(name)! | ||
``` | ||
|
||
!!! tip | ||
もし、コードエディタとして VSCode を使用している場合、シンタックスハイライトを有効にするために、Leaf 拡張機能をインストールすることをお勧めします:[Leaf HTML](https://marketplace.visualstudio.com/items?itemName=Francisco.html-leaf) | ||
|
||
次に、View をレンダリングするルートを登録します。(通常は、`routes.swift` やコントローラで行います) | ||
|
||
```swift | ||
app.get("hello") { req -> EventLoopFuture<View> in | ||
return req.view.render("hello", ["name": "Leaf"]) | ||
} | ||
|
||
// or | ||
|
||
app.get("hello") { req async throws -> View in | ||
return try await req.view.render("hello", ["name": "Leaf"]) | ||
} | ||
``` | ||
|
||
ここでは、Leaf を直接呼び出すのではなく、`Request` の汎用 `view` プロパティを使用します。これにより、テスト時に別のレンダラーに切り替えることができます。 | ||
|
||
ブラウザを開き、`/hello` にアクセスしてください。 `Hello, Leaf!` と表示されているはずです。これで最初の Leaf ビューのレンダリングが完了です! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍