FaceFlow Lists — Dynamic Content Listings

The List system in FaceFlow enables you to create dynamic, data-driven pages that query and display collections of content — blog archives, product catalogs, team directories, portfolios, and more. Lists combine a powerful query builder with flexible rendering options (card layout or custom Handlebars templates) and built-in AJAX pagination.

列表 开发者文档

列表是 FaceFlow 中的动态内容层。

它们允许技术用户在页面体验中定义内容集合如何被选择、渲染、分页和发布,而无需将每个归档或目录转换为手工页面编辑。

核心职责

列表负责:

  • 选择内容集合
  • 对结果进行排序和限制
  • 一致地渲染每个项
  • 对较大的集合进行分页
  • 暴露可预测的浏览契约

列表应回答一个明确的问题:“此页面负责呈现哪个集合?”

列表模型

典型的列表组合了:

  • 查询定义
  • 结果排序策略
  • 页面大小
  • 渲染模式
  • 可选自定义字段
  • 可选项模板逻辑

概念上:

{
  "name": "resource-library",
  "query": {
    "template": "resource-item",
    "parent": "/resources/",
    "sort": "-published",
    "limit": 12
  },
  "display": {
    "mode": "custom-template",
    "pagination": true
  }
}

查询契约

技术团队应使列表查询明确且有界。

典型输入包括:

  • 内容类型
  • 区段边界
  • 排序
  • 结果限制
  • 额外的过滤约束

薄弱的查询会产生薄弱的输出。如果内容边界模糊,列表很快会变成垃圾场。

示例:

template=resource-item, parent=/resources/, sort=-published, limit=12

该查询是可以理解的。一个包含若干不相关类型的全方位归档通常不是好选择。

查询设计示例

良好的列表定义通常将选择规则与展示规则分离:

{
  "name": "case-studies",
  "query": {
    "template": "case-study",
    "parent": "/customers/",
    "sort": "-published",
    "limit": 9
  },
  "display": {
    "mode": "custom-template",
    "pagination": true
  }
}

这样在讨论展示之前更容易审查内容边界是否正确。

渲染模式

列表通常遵循两种模型之一。

卡片风格输出

在以下情况下使用:

  • 编辑人员需要低摩擦的配置路径
  • 归档遵循标准视觉模式
  • 一个一致的卡片契约就足够

自定义模板输出

在以下情况下使用:

  • 结果项需要更丰富的映射
  • 设计不是简单的卡片网格
  • 元数据、徽章或媒体需要自定义位置
  • 归档依赖于 Facet 逻辑

示例自定义项输出:

<div class="resource-grid">
  {{#each items}}
    <article class="resource-card">
      <a href="{{ this.url }}">
        <h3>{{ this.title }}</h3>
        <p>{{ this.summary }}</p>
      </a>
    </article>
  {{/each}}
</div>

分页

分页是列表契约的一部分,而不仅仅是视觉细节。

技术评审应定义:

  • 默认页面大小
  • 页面计数行为
  • 导航模式
  • 空状态行为

概念上:

page 1 -> items 1-12
page 2 -> items 13-24
page 3 -> items 25-36

如果预期列表会增长,分页应从首次发布时就有意为之。

与页面和组件的关系

清晰的心理模型是:

  • 布局 提供外壳
  • 页面 提供可发布的路由和周边体验
  • 列表 提供动态集合
  • 组件 可能在列表周围提供辅助部分

示例页面组成:

resource-layout
  -> archive-hero component
  -> resource-library list
  -> newsletter-signup component

这使得动态浏览与一次性页面内容分离。

列表模板示例

<section class="archive">
  <header class="archive-header">
    <h1>{{ page.title }}</h1>
  </header>

  <div class="archive-items">
    {{#each items}}
      <article class="archive-item">
        <a href="{{ this.url }}">{{ this.title }}</a>
      </article>
    {{/each}}
  </div>

  {{#if pagination}}
    <nav class="archive-pagination">
      {{{ pagination.links }}}
    </nav>
  {{/if}}
</section>

目标是列表查询与归档模板之间的稳定契约。

空状态与增长规则

技术评审还应考虑当集合形态发生变化时会发生什么:

  • 无结果
  • 单个结果
  • 多页结果
  • 某些项缺少可选字段

只有在能在所有四种情况下都不出现布局崩溃或混乱输出时,列表模板才算稳定。

技术评审检查清单

  • 查询边界是否清晰且狭窄?
  • 排序是否符合浏览意图?
  • 模板能否应对结果量的增长?
  • 分页是否是设计契约的一部分?
  • 列表是否在解决一个归档问题,而不是几个不相关的问题?

反模式

避免:

  • 仅因为可用就将不相关的内容类型混合到同一个归档中
  • 完全手工构建归档,重复手动卡片
  • 使用一个列表处理若干具有不兼容契约的视觉模式
  • 将结果排序留为隐式
  • 在内容量成为问题之前忽视空状态和分页

相关内容