# 模板語法

## 概述

本篇文章將介紹模板語法，透過使用變數和表達式，您可以輕鬆地構建所需的內容並進行置換。

而模板語法目前可套用於以下功能：

* 對話腳本中部分訊息操作。
* Webhook 腳本中的參數 Params 與回呼 (Callback)。

## 變數命名規則

如同多數的程式語言，如 python、JavaScript ..等，交談變數必須遵從以下規則：

1. 變數名稱必須以字母（a-z、A-Z）或下底線（\_）開頭。
2. 後續的字元可以是字母、數字（0-9）或下底線（\_）。
3. 變數的命名是區分大小寫的，大寫字母（A-Z）和小寫字母（a-z）被視為不同的字元。

以下是一些符合命名規則的變數名稱的範例：

* myVariable
* count
* first\_name
* age123

## 符號與運算子

### 分隔符

模板語法採用 `{{ ... }}`  與  `{% ... %}` 兩種符號表達，前者分隔符號將替換為實際字串輸出於內容中，如下面語法顯示，將實際輸出為「王小明，您好！」。

```javascript
{{ name }}，您好！
```

而也可以透過一個點.(dot)符號來顯示變數更深層的內容，例如

```php
{{ contact.first_name }}

{# 也能透過方括號存取內容 #}
{{ contact['first_name'] }}
```

而後者  `{% ... %}` 分隔符號，則用於執行邏輯操作，如 for、if ...等。

```php
{# 設定變數 name 為王小明 #}
{% set name = '王小明' %}

{# 這邊會顯示 0,1,2,3 依序到 10 #}
{% for i in range(0, 10) %}
    {{ i }}
{% endfor %}
```

### 算術運算子

模板提供簡易的運算符號，其他包括以下

| 運算子  | 語法範例           | 結果    | 說明                 |
| ---- | -------------- | ----- | ------------------ |
| `+`  | `{{ 1 + 2 }}`  | `3`   | 加法，只適用於數值，不可用來串接字串 |
| `-`  | `{{ 5 - 3 }}`  | `2`   | 減法                 |
| `*`  | `{{ 4 * 2 }}`  | `8`   | 乘法                 |
| `/`  | `{{ 5 / 2 }}`  | `2.5` | 除法                 |
| `//` | `{{ 7 // 2 }}` | `3`   | 整數除法（取商）           |
| `%`  | `{{ 11 % 7 }}` | `4`   | 取餘數                |

### 比較運算子

能直接透過 `==` 、`!=`、 `<`、 `>`、 `>=`  和 `<=`，並基於比較的結果回傳邏輯值。

* `==`：等於。&#x20;
* `-!`：不等於。
* `<`：小於。
* `>`：大於。
* `>=`：大於或等於。
* `<=`：小於或等於。

針對更為複雜的比較，則可使用 `matches`匹配操作符透過正則表達式比較。

```php
{% if phone_number matches '/^[\\d\\.]+$/' %}
{% endif %}
```

### 條件(三元)運算子

這個運算子能接受兩個運算元作為值並且一個運算元作為條件判斷。而 語法是：`條件 ? 數值1 : 數值2` ，下方為一些簡單範例。

```php
{{ name ? 'yes' : 'no' }}

{{ age >= 18 ? '成人' : '小孩' }}
```

### 邏輯運算子

能透過 ?? 判斷 OR 邏輯，假如 `運算式1` 可以為是的話，回傳 `運算式1`; 否則，反之回傳 `運算式2`。&#x20;

```php
{# 如果 age 已被不是空值，则顯示 name 的值，反之則顯示 unknown #}
{{ name ?? 'unknown' }}
```

## 流程控制

流程控制是指控製流程的條件語句，如`if`、`elseif`、`else`、`for`等。控制語法應放置在 `{% ... %}` 分隔符內容中。

### if...else

當條件成立的時候會執行 if 陳述式裡的語法，而不成立時則執行另外一個陳述式。

```php
{% if age >= 18 %}
    成年
{% else %}
    未成年
{% endif %}

{# 判斷數值是否存在 #}
{% if users is defined %}
  {{ user.username }}
{% endif %}
```

### for

不斷重複直到一個指定的條件式判斷為 false，直到條件不符合才停止執行，其中 for 的區塊內，你能使用內建的特殊變數。\
\
特殊變數如下：

| 變數名         | 描述                    |
| ----------- | --------------------- |
| loop.index  | 顯示當前 index（索引），由 1 開始 |
| loop.index0 | 顯示當前 index（索引），由 0 開始 |
| loop.length | 陣列的長度                 |
| loop.first  | 返回 true，若為陣列最初項目      |
| loop.last   | 返回 true，若為陣列最後項目      |

```php
{% for user in users %}
    {{ user.name }}
{% endfor %}

{# 你也可以搭配 else 判斷陣列是否空值時，如 #}
{% for user in users %}
    {{ loop.index }} - {{ user.name }}
{% else %}
    No users have been found.
{% endfor %}
```

以下是根據你提供的語氣與格式，為 `split` 用法撰寫的一段說明，可直接接續於原本的教學內容中使用：

***

## 文字過濾器

### 運算子

<table><thead><tr><th width="103.56640625">運算子 / 方法</th><th>語法範例</th><th>結果 / 功能</th><th>說明</th></tr></thead><tbody><tr><td><code>~</code></td><td><code>{{ 'Hello, ' ~ name }}</code></td><td><code>Hello, Eason</code></td><td><strong>字串拼接運算子</strong>，會自動將變數轉成字串，即使為 <code>null</code></td></tr></tbody></table>

### 字串分割

當需要將一段文字依照某個符號拆解為多個部分時，可使用 `split` 功能。例如將一段姓名依照每個字元拆分為清單資料，便能逐一取用各字：

```php
{{ name|split('') }}

{# 若 name 為「王小明」，執行後將得到： #}
['王', '小', '明']
```

也可以指定特定符號作為切割依據，例如以逗號分隔的顏色標籤：

```php
{{ 'red,blue,green'|split(',') }}

{# 結果為： #}
[['red', 'blue', 'green']
```

分割後的資料可透過 `for` 語法進行逐一處理，常用於顯示標籤、分解文字內容等需求。

## 日期過濾器

日期語法可接受字串、DateTime 物件。例如，要顯示當前日期，請將單字 “now” 作為語法的參數。

### 顯示當前時間

```php
// 輸出為 2022-05-12 22:21:10
{{ 'now' | date('Y-m-d H:i:s') }
```

### 指定時區

預設情況下，日期會套用 FIRST LINE 伺服器的時區顯示，但您可以透過明確指定時區來覆寫它：

```php
// 指定特殊時區換算
{{ 'now' | date('Y-m-d H:i:s', 'Asia/Tokyo') }}
```

如果日期已經是 DateTime 物件，且您想要保持其當前時區，請將時區值傳遞為 false。

```php
{{ product.created_at | date('Y-m-d H:i:s', false) }}
```
