# 在 Liquid 中使用 metafields

> 在 Shoplazza 主题中用 Liquid 读取并渲染元字段：访问语法、各类型的输出方式，以及取不到值时的处理。

创建 metafield 后，你可以在 theme 中用 Liquid 读取并展示它的值。本指南介绍访问语法、各类型的渲染方式，以及如何处理缺失值。

关于 metafields 是什么、如何构成，见[概述](/zh-CN/docs/theme/theme-features/custom-data/metafields/overview)；完整的类型列表见[类型](/zh-CN/docs/theme/theme-features/custom-data/metafields/type)。

## 访问 metafield

通过父资源、namespace 和 key 访问 metafield：

```liquid
{{ resource.metafields.namespace.key }}
```

- **父资源（parent resource）**——metafield 所挂载的那个对象。在 Liquid 中，你从暴露了 `metafields` 属性的对象上读取 metafield，并通过相应页面访问：商品页用 [`product`](/zh-CN/docs/theme/references/liquid/objects/product)，集合页用 [`collection`](/zh-CN/docs/theme/references/liquid/objects/collection)。某个对象是否暴露 `metafields`，以该对象的参考页为准。
- **namespace（命名空间）**——把相关 metafield 归在一起、避免 key 冲突的容器（例如 `custom`）。
- **key（键）**——metafield 自身的名字（例如 `spec_text`）。

这返回一个 [metafield object](/zh-CN/docs/theme/references/liquid/objects/metafield)，而不是存储的值。要输出值，需追加 `.value`。

例如，假设某商品在 `custom` 命名空间下有一个名为 `spec_text` 的 `single_line_text_field`（单行文本）metafield，值为 `100% cotton`：

```liquid title="代码"
{{ product.metafields.custom.spec_text.value }}
```

```html title="输出"
100% cotton
```

:::warning
访问 metafield 始终返回一个 metafield object，即使该 metafield 不存在，结果也不是 `nil`。判断是否有值要检测 `.value`，而不是 metafield 本身。见[处理缺失值](#处理缺失值)。
:::

## 渲染各类型

如何读取 `.value` 取决于 metafield 的[类型](/zh-CN/docs/theme/theme-features/custom-data/metafields/type)。下面每个示例都假设该商品在 `custom` 命名空间下有对应名字的 metafield。

### 文本、数字、日期、布尔、颜色和 URL

这些标量类型直接从 `.value` 返回值。例如上面的单行文本字段 `spec_text`（值为 `100% cotton`）：

```liquid title="代码"
{{ product.metafields.custom.spec_text.value }}
```

```html title="输出"
100% cotton
```

`multi_line_text_field`、`number_integer`、`number_decimal`、`date`、`date_time`、`boolean`、`color`、`url` 都适用同样的写法。

### JSON

对于 `json` 类型的 metafield，`.value` 是一个已解析的对象。按属性名访问嵌套属性。假设 `details_json` 的值为 `{"foo": "bar"}`：

```liquid title="代码"
{{ product.metafields.custom.details_json.value.foo }}
```

```html title="输出"
bar
```

### 度量（重量、体积、尺寸）

这些类型返回一个 [measurement object](/zh-CN/docs/theme/references/liquid/objects/measurement)。分别读取数值和单位。例如一个值为 20 千克的 `weight` 字段 `net_weight`：

```liquid title="代码"
{{ product.metafields.custom.net_weight.value.value }} {{ product.metafields.custom.net_weight.value.unit }}
```

```html title="输出"
20 KILOGRAMS
```

### 评分

`rating` 类型的 metafield 返回一个 [rating object](/zh-CN/docs/theme/references/liquid/objects/rating)。例如一个满分为 10、评为 4 分的 `review_score`：

```liquid title="代码"
{{ product.metafields.custom.review_score.value.value }} / {{ product.metafields.custom.review_score.value.scale_max }}
```

```html title="输出"
4 / 10.0
```

### 文件（图片）

`file_reference` 类型的 metafield 把文件挂在 `value.image` 下。例如一个存有图片的 `spec_file`，可直接输出图片 URL，或将 `value` 传给 [`img_url`](/zh-CN/docs/theme/references/liquid/filters/media#img_url) 过滤器进行缩放：

```liquid title="代码"
<img src="{{ product.metafields.custom.spec_file.value.image.src }}">

<img src="{{ product.metafields.custom.spec_file.value | img_url: '400x' }}">
```

## 处理缺失值

由于访问 metafield 永远不会返回 `nil`，请在 `.value` 上做判断后再输出：

```liquid title="代码"
{% if product.metafields.custom.spec_text.value != blank %}
  <p>Material: {{ product.metafields.custom.spec_text.value }}</p>
{% endif %}
```

## 用 metafield 过滤器渲染

无需自己读取 `.value` 再拼装标记，[`metafield_tag` 和 `metafield_text`](/zh-CN/docs/theme/references/liquid/filters/metafield) 过滤器会根据 metafield 的类型直接输出内容：

* `metafield_tag` 把值包进适配该类型的 HTML 元素，并带上 `metafield-<类型>` 的 class——可直接放进页面。
* `metafield_text` 把值作为纯文本返回，适合需要原始字符串的场景。

以上面的 `spec_text` 字段（`100% cotton`）为例：

```liquid title="代码"
{{ product.metafields.custom.spec_text | metafield_tag }}
{{ product.metafields.custom.spec_text | metafield_text }}
```

```html title="输出"
<span class="metafield-single_line_text_field">100% cotton</span>
100% cotton
```

## 用 JavaScript 读取元字段

Liquid 在页面渲染时取元字段，而且只能取当前页面已有的对象。如果要在页面加载完之后读取，或者读取当前页面没有的对象，改用 Ajax Metafields API：它按对象 id 取值，可以读任意商品、专辑或店铺的元字段，也可以一次读多个对象。

参见 [Ajax Metafields API 参考](/docs/theme/references/ajax-api/metafields)。

## 下一步

- [Metafield object 参考](/zh-CN/docs/theme/references/liquid/objects/metafield)
- [Metafield 过滤器参考](/zh-CN/docs/theme/references/liquid/filters/metafield)
- [Metafield 类型](/zh-CN/docs/theme/theme-features/custom-data/metafields/type)
