layout

User 69e88e27

发布于:2026-01-13

# layout 标签使用指南

## 概述

`layout` 标签用于设置模板使用的布局文件,或者禁用布局渲染。布局文件提供了页面的整体结构(如 HTML 骨架、导航栏、页脚等),模板内容会被插入到布局的指定位置。

## 语法

```liquid
{% layout "布局名称" %}  <!-- 使用指定布局 -->
{% layout none %}        <!-- 不使用布局 -->
```

## 布局文件位置

布局文件位于主题的 `layout/` 目录下,例如:
- `layout/theme.liquid` - 默认主题布局
- `layout/custom.liquid` - 自定义布局
- `layout/mobile.liquid` - 移动端布局

## 使用示例

### 1. 使用默认布局

如果不设置 `layout` 标签,模板会默认使用 `layout/theme.liquid` 布局。

```liquid
<h1>页面标题</h1>
<p>页面内容</p>
```

模板内容会被插入到布局文件的 `{{ content_for_layout }}` 位置。

### 2. 使用自定义布局

指定使用特定的布局文件。

```liquid
{% layout "custom" %}

<h1>页面标题</h1>
<p>页面内容</p>
```

这会使用 `layout/custom.liquid` 作为布局文件。

### 3. 禁用布局

当需要返回完整的 HTML 页面或非 HTML 格式的响应时,禁用布局。

```liquid
{% layout none %}

<html>
  <head>
    <title>独立页面</title>
  </head>
  <body>
    <h1>完整 HTML 页面</h1>
  </body>
</html>
```

### 4. 条件设置布局

根据条件动态选择不同的布局。

```liquid
{% if params.mobile == "true" %}
  {% layout "mobile" %}
{% else %}
  {% layout "desktop" %}
{% endif %}

<h1>页面标题</h1>
<p>页面内容</p>
```

### 5. 配合 response_type 使用

当使用非 HTML 响应类型时,必须禁用布局。

```liquid
{% response_type "json" %}
{% layout none %}

{
  "status": "success",
  "data": {}
}
```

```liquid
{% response_type "turbo_stream" %}
{% layout none %}

<turbo-stream action="replace" target="content">
  <template>
    <div id="content">更新后的内容</div>
  </template>
</turbo-stream>
```

## 布局文件结构

布局文件通常包含页面的基本结构,模板内容会被插入到 `content_for_layout` 变量位置。

**示例:`layout/theme.liquid`**

```liquid
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>{{ page.title }}</title>
  {% meta_tags %}
</head>
<body>
  <header>
    <!-- 导航栏 -->
  </header>
  
  <main>
    {{ content_for_layout }}
  </main>
  
  <footer>
    <!-- 页脚 -->
  </footer>
</body>
</html>
```

## 实际应用场景

### 场景 1:不同设备使用不同布局

```liquid
{% if params.device == "mobile" %}
  {% layout "mobile" %}
{% elsif params.device == "tablet" %}
  {% layout "tablet" %}
{% else %}
  {% layout "desktop" %}
{% endif %}

<h1>响应式页面</h1>
```

### 场景 2:API 接口不使用布局

```liquid
{% response_type "json" %}
{% layout none %}

{
  "articles": [
    {% for article in articles %}
      {
        "id": {{ article.id }},
        "title": {{ article.title | json }}
      }{% unless forloop.last %},{% endunless %}
    {% endfor %}
  ]
}
```

### 场景 3:错误页面使用特殊布局

```liquid
{% layout "error" %}
{% response_status 404 %}

<div class="error-page">
  <h1>404 - 页面未找到</h1>
  <p>抱歉,您访问的页面不存在。</p>
</div>
```

### 场景 4:打印页面使用简化布局

```liquid
{% layout "print" %}

<h1>{{ page.title }}</h1>
<div class="content">
  {{ page.body }}
</div>
```

## 注意事项

1. **布局包装**:使用布局时,模板内容会被包装在布局的 `content_for_layout` 变量位置,而不是直接输出

2. **禁用布局**:使用 `{% layout none %}` 时,模板内容会直接输出,不会被任何布局包装,此时模板需要包含完整的 HTML 结构(如果返回 HTML 格式)

3. **必须配合 response_type**:当使用非 HTML 响应类型(如 `turbo_stream`、`json`、`xml`)时,必须禁用布局,避免布局的 HTML 结构影响响应格式

4. **布局优先级**:如果模板和布局中都设置了 `response_type` 或 `response_status`,布局中的设置会覆盖模板中的设置

5. **标签顺序**:将 `layout` 标签放在模板的最前面,确保在渲染过程中正确设置布局

6. **布局文件存在性**:确保指定的布局文件存在于 `layout/` 目录中,否则会使用默认布局或报错

## 常见错误

### 错误 1:非 HTML 响应未禁用布局

```liquid
{%# ❌ 错误示例 %}
{% response_type "json" %}
<!-- 没有设置 layout none -->

{
  "status": "success"
}
```

**问题**:响应会被布局的 HTML 结构包装,导致 JSON 解析失败。

**解决**:

```liquid
{%# ✅ 正确示例 %}
{% response_type "json" %}
{% layout none %}

{
  "status": "success"
}
```

### 错误 2:禁用布局但内容不完整

```liquid
{%# ❌ 错误示例 %}
{% layout none %}

<h1>页面标题</h1>
<!-- 缺少完整的 HTML 结构 -->
```

**问题**:如果返回 HTML 格式,缺少完整的 HTML 结构可能导致页面显示异常。

**解决**:

```liquid
{%# ✅ 正确示例 - 返回完整 HTML %}
{% layout none %}

<!DOCTYPE html>
<html>
<head>
  <title>页面标题</title>
</head>
<body>
  <h1>页面标题</h1>
</body>
</html>
```

或者使用布局:

```liquid
{%# ✅ 正确示例 - 使用布局 %}
{% layout "theme" %}

<h1>页面标题</h1>
```

### 错误 3:布局文件不存在

```liquid
{%# ❌ 错误示例 %}
{% layout "nonexistent" %}

<h1>页面标题</h1>
```

**问题**:如果指定的布局文件不存在,可能会使用默认布局或报错。

**解决**:确保布局文件存在于 `layout/` 目录中,或使用存在的布局名称。

## 最佳实践

1. **非 HTML 响应禁用布局**:当使用 `response_type` 返回非 HTML 格式时,始终配合 `{% layout none %}` 禁用布局

2. **标签顺序**:将 `layout` 标签放在模板的最前面,与其他控制标签(如 `response_type`、`response_status`)一起

3. **条件布局**:根据设备、用户类型等条件动态选择布局,提供更好的用户体验

4. **布局复用**:创建通用的布局文件,减少重复代码

5. **测试验证**:确保在不同布局下页面显示正常,特别是响应式布局

## 总结

`layout` 标签用于控制模板的布局渲染,可以指定使用特定的布局文件,或者禁用布局。当需要返回非 HTML 格式的响应时,必须禁用布局以避免 HTML 结构污染响应内容。正确使用此标签可以实现灵活的页面布局控制和响应格式管理。

提交反馈