[[Obsidian Web Clipper 簡介|Web Clipper]] 支援條件判斷、迴圈和變數賦值的範本邏輯。此語法靈感來自 [Twig](https://twig.symfony.com/) 和 [Liquid](https://shopify.github.io/liquid/) 範本語言。
> [!warning] 需要最新版本
> 邏輯功能需要 Obsidian Web Clipper 1.0.0,目前尚未在所有擴充功能商店通過審核。
## 條件判斷
使用 `{% if %}` 根據變數或表達式條件性地加入內容。
```twig
{% if author %}
Author: {{author}}
{% endif %}
```
使用 `{% else %}` 提供備用內容,使用 `{% elseif %}` 串聯多個條件:
```twig
{% if status == "published" %}
Live article
{% elseif status == "draft" %}
Draft article
{% else %}
Unknown status
{% endif %}
```
### 比較運算子
支援以下比較運算子:
| 運算子 | 說明 |
|----------|-------------|
| `==` | 等於 |
| `!=` | 不等於 |
| `>` | 大於 |
| `<` | 小於 |
| `>=` | 大於或等於 |
| `<=` | 小於或等於 |
| `contains` | 檢查字串是否包含子字串,或陣列是否包含值 |
範例:
- `{% if title == "Home" %}` — 字串相等
- `{% if price >= 100 %}` — 數值比較
- `{% if title contains "Review" %}` — 子字串檢查
- `{% if tags contains "important" %}` — 陣列成員檢查
### 邏輯運算子
使用邏輯運算子組合條件:
| 運算子 | 替代寫法 | 說明 |
| -------- | ----------- | ----------------------------------- |
| `and` | `&&` | 兩個條件都必須為真 |
| `or` | \|\| | 至少一個條件必須為真 |
| `not` | `!` | 否定條件 |
範例:
- `{% if author and published %}` — 兩者都必須存在
- `{% if draft or archived %}` — 任一條件
- `{% if not hidden %}` — 否定
- `{% if (premium or featured) and published %}` — 分組條件
### 真值判斷
當變數在沒有比較運算子的情況下使用時,會進行「真值」判斷:
- `false`、`null`、`undefined`、空字串 `""` 和 `0` 被視為**假值(falsy)**。
- 空陣列 `[]` 被視為**假值(falsy)**。
- 其他所有值都被視為**真值(truthy)**。
```twig
{% if content %}
Has content
{% endif %}
```
## 賦值變數
使用 `{% set %}` 在範本中建立或修改變數:
```twig
{% set slug = title|lower|replace:" ":"-" %}
File: {{slug}}.md
```
變數可以設定為:
- 其他變數:`{% set name = author %}`
- 字面值:`{% set count = 5 %}` 或 `{% set label = "Draft" %}`
- 帶過濾器的表達式:`{% set excerpt = content|truncate:100 %}`
- 選擇器結果:`{% set comments = selector:.comment %}`
使用 `{% set %}` 設定的變數可以用於後續的範本邏輯和 `{{variable}}` 輸出。
## 備用值
使用 `??` 運算子在變數為空或未定義時提供備用值:
```twig
{{title ?? "Untitled"}}
```
如果 `title` 為空、未定義或假值,將會使用備用值 `"Untitled"`。
這是以下等效 `if` 語句的簡寫:
```twig
{% if title %}{{title}}{% else %}Untitled{% endif %}
```
### 串聯備用值
你可以串聯多個備用值:
```twig
{{title ?? headline ?? "No title"}}
```
這會使用 `title`(如果可用),否則使用 `headline`,否則使用字串 `"No title"`。
### 搭配過濾器
過濾器的綁定優先度高於 `??`,因此過濾器會在備用值檢查之前套用:
```twig
{{title|upper ?? "UNTITLED"}}
```
這會先對 `title` 套用 `upper`,然後在結果為空時回退到 `"UNTITLED"`。若要對備用值套用過濾器,請使用括號或獨立的表達式:
```twig
{{title ?? "Untitled"|lower}}
```
如果 `title` 可用則使用 `title`,否則對備用值套用 `lower`,結果為 `"untitled"`。
## 迴圈
使用 `{% for %}` 遍歷陣列:
```twig
{% for item in schema:author %}
- {{item.name}}
{% endfor %}
```
### 迴圈來源
你可以遍歷:
- Schema 陣列:`{% for item in schema:author %}`
- 選擇器結果:`{% for comment in selector:.comment %}`
- 先前設定的變數:`{% set items = selector:.item %}{% for item in items %}`
### 迴圈變數
在迴圈內部,你可以存取具有以下屬性的 `loop` 物件:
| 變數 | 說明 |
|----------|-------------|
| `loop.index` | 目前迭代次數(從 1 開始) |
| `loop.index0` | 目前迭代次數(從 0 開始) |
| `loop.first` | 如果是第一次迭代則為 `true` |
| `loop.last` | 如果是最後一次迭代則為 `true` |
| `loop.length` | 項目總數 |
```twig
{% for tag in tags %}
{{loop.index}}. {{tag}}
{% if loop.last %} (end of list){% endif %}
{% endfor %}
```
為了向下相容,你也可以使用 `item_index`(其中 `item` 是你的迭代器變數名稱)來取得從 0 開始的位置:
```twig
{% for tag in tags %}
{{tag_index}}. {{tag}}
{% endfor %}
```
### 透過索引存取陣列項目
使用方括號表示法按索引存取陣列元素:
```twig
{{items[0]}}
{{items[loop.index0]}}
```
當你需要平行存取多個陣列中的項目時,這特別有用:
```twig
{% set transcripts = selector:.transcript-text %}
{% set timestamps = selector:.timestamp %}
{% for line in transcripts %}
{{timestamps[loop.index0]}} - {{line}}
{% endfor %}
```
方括號表示法也適用於物件屬性:
```twig
{{user["name"]}}
{{data["my-key"]}}
```
### 巢狀迴圈
迴圈可以巢狀使用以處理複雜的資料結構:
```twig
{% for section in sections %}
## {{section.title}}
{% for item in section.items %}
- {{item}}
{% endfor %}
{% endfor %}
```
## 組合邏輯
條件判斷和迴圈可以組合使用:
```twig
{% for item in items %}
{% if item.active %}
- {{item.name}}
{% endif %}
{% endfor %}
```
## 執行順序
範本邏輯按以下順序處理:
1. **範本邏輯** — `{% if %}`、`{% for %}`、`{% set %}` 和 `{{variables}}` 會最先被執行
2. **提示變數** — 如 `{{"summarize this"|prompt}}` 的[[變數#提示變數|提示變數]]會在範本邏輯完成後傳送給解讀器
這表示你可以使用範本邏輯動態建構提示,但提示結果無法用於條件判斷或迴圈中。