mcpField
G
generating-flexipage

generating-flexipage

github.com/forcedotcom设计与 UI1.1k4.0k 次安装1 天前更新
代码仓库

关于 generating-flexipage

为 Salesforce 开发者和管理员提供创建及排查 Lightning FlexiPage 元数据的操作指南。新页面须先用 CLI 模板生成并部署验证,之后停止修改 XML。

主要功能

  1. 01用 CLI 模板初始化页面
  2. 02支持 RecordPage、AppPage 和 HomePage
  3. 03部署前验证元数据
  4. 04说明 XML 结构与字段引用
  5. 05整理常见部署错误及修复

适用场景

  1. 01生成新的 Lightning 页面
  2. 02验证 FlexiPage 部署问题
  3. 03了解字段区域和组件配置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill generating-flexipage

安装后在 Claude Code 中输入/generating-flexipage确认已加载。

详细介绍

适用场景

在以下情况下使用此技能:

  • 创建 Lightning 页面(RecordPage、AppPage、HomePage)
  • 生成 FlexiPage 元数据 XML
  • 向现有 FlexiPage 添加组件
  • 排查 FlexiPage 部署错误
  • 了解 FlexiPage 结构和组件配置
  • 使用页面布局或自定义 Lightning 页面
  • 编辑或更新任何 *.flexipage-meta.xml 文件

规范

FlexiPage 生成指南

概述

重要:创建新的 FlexiPage 时,必须始终从 CLI 模板命令开始。 切勿从头创建 FlexiPage XML——CLI 会提供有效的结构、正确的区域和正确的组件配置,避免部署错误。

使用 CLI 引导生成 Lightning 页面(RecordPage、AppPage、HomePage),以发现和配置组件。


快速入门工作流

步骤 1:使用 CLI 引导

新建页面的强制步骤:此步骤不可跳过。 创建新的 FlexiPage 时,始终使用 CLI 模板命令。CLI 会生成有效的 XML 结构、正确的区域和正确的元数据,避免常见的部署错误。仅在编辑现有 FlexiPage 文件时才跳过此步骤。

sf template generate flexipage \
  --name <PageName> \
  --template <RecordPage|AppPage|HomePage> \
  --sobject <SObject> \
  --primary-field <Field1> \
  --secondary-fields <Field2,Field3> \
  --detail-fields <Field4,Field5,Field6,Field7> \
  --output-dir force-app/main/default/flexipages

重要: 如果 sf template generate flexipage 命令失败,请停止。

  1. 安装模板插件:
    sf plugins install templates
    
  2. 重试 sf template generate flexipage 命令
  3. 确认 FlexiPage XML 文件已创建

在模板命令成功之前,请勿继续执行步骤 2。生成的 XML 是整个工作流的必需内容。

模板特定要求

RecordPage:

  • 需要 --sobject(例如 Account、Custom_Object__c)
  • 需要字段参数:
    • --primary-field:最重要的标识字段(例如 Name)
    • --secondary-fields:记录摘要(建议 4–6 个,最多 12 个)
    • --detail-fields:完整的记录详情,包括必填字段(例如 Name)

AppPage:

  • 无其他要求

HomePage:

  • 无其他要求
字段选择规则
  • 验证字段是否存在:在命令中指定字段之前,使用 MCP 工具或 describe 命令查找该对象可用的字段
  • 优先使用复合字段:如果有 Name(而非 FirstName/LastName)、BillingAddress(而非 BillingStreet/BillingCity/BillingState)、MailingAddress 等字段,请优先使用
  • 在 detail-fields 中包含必填字段:始终在 --detail-fields 参数中包含对象的必填字段(如 Name),即使这些字段也用于 --primary-field 或 --secondary-fields
生成内容
  • 结构正确的有效 FlexiPage XML
  • 预配置的区域和基本组件
  • 正确的字段引用和 facet 结构
  • 可直接部署,也可进一步增强
步骤 2:部署基础页面

对整个项目运行试运行部署,以验证页面及其依赖项:

sf project deploy start --dry-run -d "force-app/main/default" --test-level NoTestRun --wait 10 --json

重要: 继续操作前,请修复所有部署错误。页面必须通过验证。

步骤 3:停止——不要再进行其他修改

强制要求:步骤 2 后即停止。不要添加组件或编辑 FlexiPage XML。

即使用户要求以下内容,也同样适用:

  • 添加其他组件
  • 自定义页面
  • 配置组件

你可以做的事项:

  • 建议适用的组件
  • 说明可以进行哪些增强
  • 记录需要手动添加的内容

你不能做的事项:

  • 修改 XML 文件
  • 添加任何组件
  • 进行任何增强

关键 XML 规则

1. 属性值编码(最常见错误)

任何包含 HTML/XML 字符的属性值都必须按以下顺序手动编码(顺序错误会导致双重编码损坏):

1. & → &amp;   (FIRST! Encode this before others)
2. < → &lt;
3. > → &gt;
4. " → &quot;
5. ' → &apos;

错误示例:

<value><b>Important</b> text</value>

正确示例:

<value>&lt;b&gt;Important&lt;/b&gt; text</value>

检查 XML: 搜索 <value> 标签——其中绝不能包含未转义的 < 或 > 字符。

2. 字段引用

始终使用: Record.{FieldApiName}
绝不使用: {ObjectName}.{FieldApiName}


<fieldItem>Record.Name</fieldItem>

        
<fieldItem>Account.Name</fieldItem>
3. Region 与 Facet 类型

模板区域(header、main、sidebar):

<name>header</name>
<type>Region</type>

组件 Facet(如 fieldSection 列这样的内部插槽):

<name>Facet-12345</name>
<type>Facet</type>

**规则:**如果是模板区域名称,则使用 Region。如果是组件插槽,则使用 Facet。

4. fieldInstance 结构

每个 fieldInstance 都必须包含:

<itemInstances>
   <fieldInstance>
      <fieldInstanceProperties>
         <name>uiBehavior</name>
         <value>none</value> 
      </fieldInstanceProperties>
      <fieldItem>Record.FieldName__c</fieldItem>
      <identifier>RecordFieldName_cField</identifier>
   </fieldInstance>
</itemInstances>

规则:

  • 每个 fieldInstance 都必须使用单独的 <itemInstances> 包装
  • 必须包含带有 uiBehavior 的 fieldInstanceProperties
  • 使用 Record.{Field} 格式
5. 唯一标识符和区域名称(关键 — 避免重复错误)

整个 FlexiPage 文件中的每个标识符以及每个区域/Facet 名称都必须唯一。

关键规则:

  • ❌ 绝不要创建两个 <flexiPageRegions> 块并使用相同的 <name>
  • ✅ 如果多个组件属于同一个 Facet,请将它们合并到一个包含多个 <itemInstances> 的区域中
  • ❌ 绝不要重复使用相同的 <identifier> 值
  • ✅ 始终先读取整个文件,并提取所有现有标识符和名称

错误示例 — 将导致重复名称错误:


<flexiPageRegions>
   <itemInstances>
      <componentInstance>
         <identifier>flexipage_property_details_fieldSection</identifier>
         ...
      </componentInstance>
   </itemInstances>
   <name>detailTabContent</name>  
   <type>Facet</type>
</flexiPageRegions>


<flexiPageRegions>
   <itemInstances>
      <componentInstance>
         <identifier>flexipage_pricing_fieldSection</identifier>
         ...
      </componentInstance>
   </itemInstances>
   <name>detailTabContent</name>  
   <type>Facet</type>
</flexiPageRegions>

正确示例 — 将 itemInstances 合并到一个区域中:


<flexiPageRegions>
   <itemInstances>
      <componentInstance>
         <identifier>flexipage_property_details_fieldSection</identifier>
         ...
      </componentInstance>
   </itemInstances>
   <itemInstances>
      <componentInstance>
         <identifier>flexipage_pricing_fieldSection</identifier>
         ...
      </componentInstance>
   </itemInstances>
   <name>detailTabContent</name>  
   <type>Facet</type>
</flexiPageRegions>

何时合并或拆分:

  • 合并:逻辑上属于同一选项卡/区域的组件(例如,详情选项卡中的多个字段区域)
  • 拆分:属于不同选项卡/区域的组件(例如,detailTabContent 与 relatedTabContent)

常见部署错误

“无法检索或加载字段信息”

**原因:**字段 API 名称无效——对象上不存在该字段,或字段拼写错误 **修复方法:**使用 MCP 工具或 describe 命令查找有效字段,然后更新字段引用(参见字段选择规则)

“字段引用无效”

**原因:**使用了 ObjectName.Field 而不是 Record.Field
**修复方法:**改为 Record.{FieldApiName}

“元素 fieldInstance 重复”

**原因:**一个 itemInstances 中包含多个 fieldInstance
**修复方法:**每个 fieldInstance 都需要单独的 <itemInstances> 包装

“缺少 fieldInstanceProperties”

**原因:**未指定 uiBehavior
**修复方法:**添加带有 uiBehavior 的 fieldInstanceProperties

“未使用的 Facet”

**原因:**已定义 Facet,但没有组件引用它
**修复方法:**删除 Facet,或在组件属性中引用它

“XML 解析错误”

**原因:**属性值中包含未编码的 HTML/XML **修复方法:**手动对所有 <value> 标签中的 <、>、&、"、' 进行编码

“无法创建带有命名空间的组件”

**原因:**页面名称无效(页面名称不要使用 __c 后缀)
**修复方法:**使用 "Volunteer_Record_Page",而不是 "Volunteer__c_Record_Page"

“区域指定了父级不支持的模式”

**原因:**向区域添加了 <mode> 标签 **修复方法:**删除 <mode> 标签——标准区域不需要它们


生成唯一标识符

关键:在生成任何新标识符或 Facet 名称之前,请遵循上文“关键 XML 规则”第 5 节中的规则。

标识符生成算法:

1. Extract ALL existing <identifier> AND <name> values from XML
2. Generate base name: {componentType}_{context}
   Examples: "relatedList_contacts", "richText_header", "tabs_main"
3. Find first available number:
   - Try "{base}_1"
   - If exists, try "{base}_2", "{base}_3", etc.
   - Use first available

示例:

  • 第一个 contacts 相关列表:relatedList_contacts_1
  • 第二个 contacts 相关列表:relatedList_contacts_2
  • header 中的富文本:richText_header_1
  • 字段区域:fieldSection_details_1

Facet 命名 — 两种模式:

  1. 具名 Facet(用于主要内容区域):

    • detailTabContent(详情选项卡内容)
    • maintabs(主选项卡容器)
    • sidebartabs(侧边栏选项卡容器)
    • 当 Facet 表示有意义的内容区域时使用
  2. UUID Facet(用于内部结构):

    • 格式:Facet-{8hex}-{4hex}-{4hex}-{4hex}-{12hex}
    • 示例:Facet-66d5a4b3-bf14-4665-ba75-1ceaa71b2cde
    • 用于字段区域列、嵌套容器和匿名插槽

向现有文件添加组件时:

  • 检查目标 Facet 名称是否已存在
  • 如果已存在:向该现有区域添加新的 <itemInstances>(详情请参见上文第 5 节)
  • 如果不存在:创建具有唯一名称的新区域
区域选择

从文件解析区域——不要对名称进行硬编码。模板各不相同:

  • flexipage:recordHomeTemplateDesktop → header、main、sidebar
  • runtime_service_fieldservice:... → header、main、footer
  • 其他模板的区域名称可能不同

默认放置位置:目标区域末尾(最后一个 <itemInstances> 之后)

插入模式:

<flexiPageRegions>
   <name>main</name>  
   <type>Region</type>
   <itemInstances></itemInstances>
   <itemInstances></itemInstances>
   <itemInstances>
      
   </itemInstances>
</flexiPageRegions>

带有 Facet 的容器组件

标签页、折叠面板和字段区段等组件需要 Facet。

模式:


<flexiPageRegions>
   <itemInstances>
      <componentInstance>
         <componentName>flexipage:tabset2</componentName>
         <identifier>tabs_main_1</identifier>
         <componentInstanceProperties>
            <name>tabs</name>
            <value>tab1_content</value>
            <value>tab2_content</value>
         </componentInstanceProperties>
      </componentInstance>
   </itemInstances>
   <name>main</name>
   <type>Region</type>
</flexiPageRegions>

        
<flexiPageRegions>
<itemInstances></itemInstances>
<name>tab1_content</name>
<type>Facet</type>
</flexiPageRegions>

<flexiPageRegions>
<itemInstances></itemInstances>
<name>tab2_content</name>
<type>Facet</type>
</flexiPageRegions>

重要:Facet 区域与模板区域处于同一级别,是其兄弟节点,而非嵌套在其中。

特定组件提示

dynamicHighlights(RecordPage 标题区域)

**位置:**必须位于 header 区域。 显式字段(通过 CLI):使用最重要的字段显示记录摘要。单个主字段用于标识记录,例如名称。辅助字段(最多 12 个,建议 6 个)用于概述记录。

--primary-field Name
--secondary-fields Phone,Industry,AnnualRevenue

CLI 会自动生成带有字段引用的 Facet。

fieldSection

**用途:**按列显示字段。 **结构:**三级嵌套:

  1. 模板区域(Region 类型)
  2. 列 Facet(Facet 类型)
  3. 字段 Facet(Facet 类型) 在组件属性中引用:
<componentInstanceProperties>
   <name>columns</name>
   <value>Facet-{uuid}</value>
</componentInstanceProperties>
富文本组件

组件名称:flexipage:richText

用途:显示带格式的富文本内容,支持文本格式、标题、列表、表格、图片、链接、表单和多媒体元素。保留样式和布局。请转义默认文本中的所有特殊字符。

位置:可用于任何页面类型(Home、Record、App、Community 页面)的任何区域。

CLI 会直接生成该组件,不包含嵌套结构。

用户:“将富文本组件添加到 force-app/.../Account_Record_Page.flexipage-meta.xml”

结构:单层组件(无 Facet):

  1. 组件实例(flexipage:richText),包含直接属性

XML 结构示例:

<itemInstances>
   <componentInstance>
      <componentInstanceProperties>
         <name>decorate</name>
         <value>true</value>
      </componentInstanceProperties>
      <componentName>flexipage:richText</componentName>
      <identifier>flexipage_richText</identifier>
   </componentInstance>
</itemInstances>

标识符模式:flexipage_richText 或 flexipage_richText_{sequence}


必需的元数据结构

<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
   <flexiPageRegions>
      
   </flexiPageRegions>
   <masterLabel>Page Label</masterLabel>
   <template>
      <name>flexipage:recordHomeTemplateDesktop</name>
   </template>
   <type>RecordPage</type>
   <sobjectType>Object__c</sobjectType> 
</FlexiPage>

页面类型:

  • RecordPage——需要 <sobjectType>
  • AppPage——不需要 sobjectType
  • HomePage——不需要 sobjectType

验证清单

部署前:

  • [仅限新建页面] 使用 CLI 初始化——绝不要从头创建 FlexiPage XML
  • 所有标识符均唯一——文件中任何位置都不得有重复的 <identifier> 值
  • 所有区域/Facet 名称均唯一——<flexiPageRegions> 中不得有重复的 <name> 值
  • 合并同一 Facet 中的多个组件——使用一个包含多个 <itemInstances> 的区域,而不是多个名称相同的独立区域
  • 所有字段引用均使用 Record.{Field} 格式
  • 每个 fieldInstance 都有包含 uiBehavior 的 fieldInstanceProperties
  • 每个 fieldInstance 都使用独立的 <itemInstances> 封装
  • 模板区域使用 <type>Region</type>
  • 组件 Facet 使用 <type>Facet</type>
  • 手动编码包含 HTML/XML 的属性值
  • 区域中没有 <mode> 标签
  • 页面名称中没有 __c 后缀
  • 每个 Facet 恰好由一个组件属性引用

快速参考:CLI 命令

# RecordPage with fields
sf template generate flexipage \
  --name Account_Custom_Page \
  --template RecordPage \
  --sobject Account \
  --primary-field Name \
  --secondary-fields Phone,Industry,AnnualRevenue \
  --detail-fields Street,City,State,Name,Phone,Email

# AppPage
sf template generate flexipage \
  --name Sales_Dashboard \
  --template AppPage \
  --label "Sales Dashboard"

# HomePage
sf template generate flexipage \
  --name Custom_Home \
  --template HomePage \
  --description "Custom home for sales team"

所有模板均支持:

  • --output-dir(默认:当前目录)
  • --api-version(默认:最新版本)
  • --label(默认:页面名称)
  • --description

评论

支持 Markdown