Experience Cloud 开发人员指南

快速了解 Experience Builder 站点

Experience Builder 模板允许您创建品牌网站,让您的员工、 客户和合作伙伴可以建立联系。基于 Lightning 组件框架构建,Experience 构建器模板包括许多现成的功能和 Lightning 组件。但真正的 Lightning 组件框架的强大之处在于您可以开发自定义的 Lightning 组件 和功能,以满足您独特的业务需求,并彻底改变外观和感觉 您的网站。

从 Spring ’19(API 版本 45.0)开始,您可以使用两个 编程模型:Lightning Web 组件模型和原始 Aura 组件 型。Lightning Web 组件是使用 HTML 和现代构建的自定义 HTML 元素 JavaScript的。

提示

重命名为 Experience Cloud Spring ’21(API 版本 50.0)引入了一些新术语,了解起来可能很棘手 什么是什么。这是纲要。

Experience Builder 站点(以前称为 Lightning 社区)是您在 Experience Builder 中自定义的基于模板的站点。 随着 Lightning Web 运行时 (LWR) 的推出,我们为 even 添加了两个新术语 更清晰。

  • LWR 站点使用最新的基于 LWR 的模板构建,例如 构建您自己的 (LWR) 模板。LWR 站点只能与 Lightning Web 组件一起使用, 不是 Aura 组件。查看 LWR 网站获取体验 云。
  • Aura 网站是使用我们的原始模板构建的,例如客户 服务、合作伙伴中心和客户帐户门户,在 Aura 上运行。对于光环 站点、Lightning Web 组件和 Aura 组件可以在 页。

您可以将 Lightning Web 组件和 Aura 组件配置为拖放式 Experience Builder 的组件。管理员和最终用户不知道哪种编程模型 用于开发组件 – 对他们来说,它们只是 Lightning 组件。

无论你是开发人员、合作伙伴还是 ISV,本指南都介绍了如何创建自定义 Aura 网站和组件、主题布局组件和 Lightning Bolt 解决方案。

  • 开始之前 在开始
    开发自定义 Experience Builder 站点之前,请确保您熟悉如何在 Lightning 中进行开发。
  • 什么是 Salesforce Lightning?
    借助 Salesforce Lightning,您可以更轻松地为任何设备构建响应式应用程序,并包含 Lightning 组件框架和面向开发人员的有用工具。
  • 我应该使用哪个 Experience Builder 模板?
    根据您使用的 Experience Builder 模板,您可以使用两种编程模型构建 Experience Builder 站点:Lightning Web 组件模型和原始 Aura 组件模型。Build Your Own (LWR) 模板基于新的 Lightning Web 运行时 (LWR),只能与 Lightning Web 组件一起使用,而不能与 Aura 组件一起使用。其他模板基于 Aura 组件模型,可以同时使用 Lightning Web 组件和 Aura 组件。
  • Experience Cloud 开发人员发行说明 使用 Salesforce 发行说明
    了解 Experience Cloud 开发人员体验的最新更新和更改。

准备工作

在开始开发自定义 Experience Builder 站点之前,请确保您 熟悉在 Lightning 中开发。

您可以在 EnterprisePerformanceUnlimited 和 Developer Edition 或沙盒中创建 Experience Builder 站点和 Lightning 组件。

要成功使用本指南,需要:

  • 启用了数字体验的组织
  • 基于 Experience Builder 模板或 Lightning 的新站点或现有站点 螺栓解决方案
  • 熟悉使用 Experience Builder
  • 具有开发 Lightning 组件和使用 CSS 的经验

Lightning 开发资源

不熟悉 Lightning 开发?然后查看这些资源。

Lightning Aura 组件 开发者指南

所有 Aura 的首选指南。基本概念和方法 指南文档构成了本指南的基石。想想 Experience Cloud 开发人员指南作为开发系列的第 2 部分;它对你没有用,直到 您熟悉了第 1 部分。

Lightning Web 组件 开发者指南

了解如何开发 Lightning Web 组件,即使用 HTML 构建的自定义 HTML 元素 和现代 JavaScript。

LWR 体验站点 云开发人员指南

使用“构建自己的网站”(LWR) 开发加载速度快且可扩展的站点 Experience Cloud 的模板。此模板基于最新的 Lightning Web 运行时 (LWR) 和 Lightning Web 组件 (LWC) 编程模型。

Aura 组件基础知识 (Trailhead Module)

使用 Aura 组件构建具有可重用 UI 组件的新式 Web 应用程序。学习核心 Lightning 组件概念并构建可运行的简单费用跟踪器应用程序 在独立应用程序、Salesforce 移动应用程序或 Lightning Experience 中。

构建 Lightning Web 组件 (Trailhead Trail)

使用 JavaScript 和 HTML 开发可重用的 Lightning Web 组件。

快速入门:Aura 组件 (Trailhead Project)

创建第一个组件,用于呈现组织中的联系人列表。

构建自定义主题布局 Experience Builder Sites 的组件(Trailhead 项目)

使用主题布局组件自定义 Experience Builder 站点。

闪电组件 性能最佳实践(博客文章)

了解影响组件性能的 Lightning 特性,并获得 优化组件的最佳实践。

Experience Cloud 资源

不熟悉 Experience Cloud?然后查看这些资源。

设置和管理体验 Cloud Sites(帮助)

使用模板创建品牌网站,直接与您的客户互动,以及 合作伙伴在线。

通过经验扩大您的影响力 云 (Trailhead Trail)

了解开始使用 Salesforce Experience Cloud 所需的工具。

体验云 概述(帮助)

及时了解其他 Experience Cloud 资源。

什么是 Salesforce Lightning?

借助 Salesforce Lightning,您可以更轻松地为任何设备构建响应式应用程序, 并包含 Lightning 组件框架和为开发人员提供的有用工具。闪电网络包括这些技术。

  • Lightning 组件可加速开发和应用性能。开发定制 其他开发人员和管理员可用作可重用构建基块的组件 自定义 Experience Builder 站点、Salesforce 移动应用程序和 Lightning 经验。
  • Lightning 应用程序生成器使管理员能够直观地构建 Lightning 页面,无需代码, 使用现成的和定制的 Lightning 组件。制作您的 Lightning 组件 在 Lightning 应用程序生成器中可用,因此管理员可以构建自定义用户界面 没有代码。
  • Experience Builder 使管理员能够使用模板直观地构建站点,并且 组件。使您的 Lightning 组件在 Experience Builder 中可用,以便 管理员无需代码即可构建网站页面。

一些使用 Lightning 框架构建的 Salesforce 产品包括:

  • Experience Builder 模板
  • 闪电 解决 方案
  • 闪电体验
  • Salesforce 移动应用程序

注意

您无需启用 Lightning Experience 即可使用 Experience Builder 模板 或开发 Lightning 组件。Experience Builder 站点使用相同的底层技术 作为 Lightning Experience,但它们彼此独立。

我应该使用哪个 Experience Builder 模板?

根据您使用的 Experience Builder 模板,您可以构建 Experience 使用两种编程模型构建站点:Lightning Web 组件模型和原始模型 Aura 组件模型。Build Your Own (LWR) 模板基于新的 Lightning Web 运行时 (LWR),只能与 Lightning Web 组件一起使用,而不能与 Aura 组件一起使用。其他 模板基于 Aura 组件模型,可以使用 Lightning Web 组件和 光环组件。

建立你自己的

提供每个Experience Builder站点所需的基本页面:主页、创建记录、 错误、记录明细、记录列表、相关记录列表、搜索、检查密码、忘记 密码、登录名、登录错误和注册。根据需要添加更多页面和组件 您正在构建的体验。要优化网站的外观,请自定义您的品牌 和主题。

构建自己的 (LWR)

由新的 Lightning Web 运行时 (LWR) 平台提供支持,这个可自定义的模板 提供无与伦比的页面性能,提高开发人员的工作效率。快速构建 像素完美的页面,并开发 Lightning Web 组件和主题,以匹配您独特的 品牌。

适合熟悉开发的开发人员、咨询合作伙伴和 ISV 自定义 Lightning Web 组件,并使用 Salesforce DX、用户界面 API 和 顶点。

查看 LWR 站点获取体验 云指南。

客户账户门户

一个私密且安全的地方,供客户访问和更新其帐户信息。 通过让客户在 门户。客户可以查看和支付发票、更新其帐户信息以及搜索 您的知识库,用于回答他们最常见问题。

顾客服务

功能强大、响应迅速的自助服务模板,具有多个预构建的主题选项。这 Customer Service 模板允许用户将问题发布到社区、搜索和查看 文章、协作,并通过创建案例联系支持代理。支持知识, Chatter 问题和案例。

合作伙伴中心

专为渠道销售工作流程设计的灵活、响应迅速的模板。招募、建设、 并发展您的合作伙伴网络,以品牌化的方式共同推动渠道销售和营销 在线空间。轻松配置销售线索分销、交易注册和营销 活动。在中央空间中共享培训材料和销售材料,并使用 用于跟踪管道的报表。

帮助中心

一个公开您创建的文章的公共访问自助服务社区 可从知识库获取。您可以减轻客户支持团队的负担,并且 您的用户会因为找到自己的解决方案而感到满意。

Experience Cloud 开发人员发行说明

使用 Salesforce 发行说明了解 Experience Cloud 开发人员体验。

有关新功能和更改的功能,请参阅 Salesforce 发行说明的 Experience Cloud 部分。您还可以查找 Experience Cloud 在“新建和更改的项目”中 Salesforce 发行说明中的开发人员。

开发 Experience Builder 站点:基础知识

了解开发者控制台开发工具,以及如何创建基本的拖放操作 光环组件,以及在此过程中要考虑的提示。

  • 使用开发者控制台 开发者控制台
    提供了用于开发 Aura 组件和应用程序的工具。
  • 为 Experience Builder 配置拖放式 Aura 组件 在Experience Builder
    中使用自定义Aura组件之前,需要执行一些配置步骤。
  • 在Experience Builder
    中公开组件属性 您可以使用设计资源来控制在Experience Builder中公开哪些属性。设计资源与组件位于同一文件夹中。它描述了 Aura 组件的设计时行为,即可视化工具在页面或应用中显示组件所需的信息。
  • 为 Experience Builder
    配置 Aura 组件的提示和注意事项 在为 Aura 站点创建 Aura 组件和组件捆绑包时,请牢记这些准则。
  • 支持的 Aura 组件、接口和事件 基于 Aura 的 Experience Builder 站点并非支持所有 Aura 组件、接口和事件
    。有些仅适用于 Salesforce 移动应用程序或 Lightning Experience。在自定义您的网站之前,请查看可用的内容。
  • 个性化目标开发人员和组名称
    在使用 Connect REST API 或元数据 API 个性化 Experience Builder 站点时,确定体验变体目标的开发人员名称和组名称。
  • 遵守用户的个人信息可见性设置 具有门户和站点的组织提供特定设置
    ,以向其他用户隐藏用户的个人身份信息和联系信息。这些设置不会在 Apex 中强制执行,即使使用 Apex 安全功能(如子句或方法)也是如此。要对来宾或外部经过身份验证的用户隐藏特定字段,请遵循下面概述的示例代码。WITH SECURITY_ENFORCEDstripInaccessible

使用开发者控制台

开发者控制台提供了用于开发 Aura 组件和 应用。

开发人员控制台使您能够执行这些功能。

  • 使用菜单栏 (1) 创建或打开这些 Lightning 资源。
    • 应用
    • 元件
    • 接口
    • 事件
    • 令 牌
  • 使用工作区 (2) 处理 Lightning 资源。
  • 使用侧边栏 (3) 创建或打开客户端资源,这些资源是 特定组件捆绑包。
    • 控制器
    • 助手
    • 风格
    • 文档
    • 渲染
    • 设计
    • SVG

为 Experience Builder 配置拖放式 Aura 组件

在Experience Builder中使用自定义Aura组件之前,有几个 要执行的配置步骤。

1. 将界面添加到你的 元件

显示为 拖放组件 在Experience Builder中,组件必须实现接口。forceCommunity:availableForAllPageTypes

创建 Aura 组件后,该组件将显示在 Components 中 组织中所有 Aura 站点的面板。

下面是一个简单的“Hello World”组件的示例代码。组件必须 命名为 componentName.cmp

注意

要使 资源,例如组件,可在您自己的组织外部使用,请用 标记它。例如,如果您希望组件在已安装的软件包中可用,请使用 由 Experience Builder 用户提供 在另一个 组织。access=”global”access=”global”

<aura:component implements="forceCommunity:availableForAllPageTypes" access="global">
    <aura:attribute name="greeting" type="String" default="Hello" access="global" />
    <aura:attribute name="subject" type="String" default="World" access="global" />

    <div>{!v.greeting}, {!v.subject}!</div>
</aura:component>

警告

当您将自定义组件添加到 site,它们可以绕过您为来宾用户设置的对象级和字段级安全性 (FLS) 轮廓。Lightning 组件在引用对象或检索对象时不会自动强制执行 CRUD 和 FLS 从 Apex 控制器。这意味着框架继续显示记录和 用户没有 CRUD 权限和 FLS 可见性的字段。您必须手动操作 在 Apex 控制器中强制执行 CRUD 和 FLS。

2. 将设计资源添加到组件包中

设计资源控制公开的组件属性 在 Experience Builder 中。这 设计资源与 .cmp 资源位于同一文件夹中,并且 描述 Aura 组件的设计时行为 – 可视化工具所需的信息 以在页面或应用程序中显示组件。

例如,设置属性的默认值,或创建 Aura 组件属性 可供管理员在 Experience Builder 中编辑,您的 组件包需要设计资源。下面是与“Hello World”组件捆绑在一起的设计资源。一个 设计资源必须命名为 componentName.design

<design:component label="Hello World">
    <design:attribute name="greeting" label="Greeting" />
    <design:attribute name="subject" label="Subject" description="Name of the person you want to greet" />
</design:component>

自选。将 SVG 资源添加到组件包

要为组件定义自定义图标,请将 SVG 资源添加到组件包中。 该图标显示在 Experience Builder 组件中的组件旁边 面板。

如果不包含 SVG 资源,系统将使用默认图标 (默认组件图标)。

下面是一个简单的红色圆圈 SVG 资源,用于“Hello World”组件。An SVG 资源必须命名为 componentName.svg

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 
<svg xmlns="http://www.w3.org/2000/svg"
     width="400" height="400">
  <circle cx="100" cy="100" r="50" stroke="black"
    stroke-width="5" fill="red" />
</svg>

自选。将 CSS 资源添加到组件包

要设计你的 自定义组件,将 CSS 资源添加到组件包中。

这是 CSS 的 简单的类,以配合“Hello World”组件。CSS 资源必须命名为 componentName.css

.THIS .greeting {
    color: #ffe4e1;
    font-size: 20px;
}

创建类后,将其应用于组件。

<aura:component implements="forceCommunity:availableForAllPageTypes" access="global">
    <aura:attribute name="greeting" type="String" default="Hello" access="global" />
    <aura:attribute name="subject" type="String" default="World" access="global" />

    <div class="greeting">{!v.greeting}, {!v.subject}!</div>
</aura:component>

在Experience Builder中公开组件属性

您可以使用设计资源来控制在体验中显示哪些属性 建筑工人。设计资源与组件位于同一文件夹中。它描述了 Aura 组件的设计时行为 – 可视化工具显示 组件。

要使 Aura 组件属性可供管理员在 Experience Builder 中编辑,请在设计中为该属性添加一个节点 资源。当您将属性标记为必需时,该属性会自动显示在Experience Builder中,除非它 为其分配了默认值。design:attribute

您必须使用 default 指定必需的属性 在设计的组件定义中未标记为必需的值和属性 资源,使它们对用户显示。设计资源仅支持 、 或 类型的属性。intstringboolean

对于拖放组件,公开 属性将显示在组件的属性面板中。

对于主题布局组件,当主题布局 在“设置”|”主题面积。

为 Experience Builder 配置 Aura 组件的提示和注意事项

在为 光环网站。

组件

  • 使用设计文件元素中的属性为组件指定一个友好名称,例如 .label<design:component label=”foo”>
  • 将组件设计为填充 100% 的区域宽度(包括边距) 它们显示在。
  • 确保组件在声明性中提供适当的占位符行为 工具(如果需要交互)。
  • 切勿让组件显示空白框。想想其他网站是如何工作的。例如 Facebook 在源项从服务器返回之前显示源的轮廓, 这提高了用户对 UI 响应能力的感知。
  • 如果组件依赖于触发的事件,请为其指定之前显示的默认状态 事件触发。
  • 使用标准设计标记设置组件样式,使其与 Salesforce设计系统。
  • 请记住,Lightning Locker 是针对创建的所有 Aura 组件强制执行的 在 Summer ’17(API 版本 40.0)及更高版本中,当组织中启用了 Lightning Locker 时,并且 网站。在组织级别,如果 Lightning Web Security 尚未使用 Lightning Locker,则 Lightning Locker 正在使用 已启用。请参阅开发安全站点:CSP、LWS 和 Lightning Locker。
  • 对于自定义组件,当您在体验中使新属性可供编辑时 构建器,在进行网站翻译时,请牢记以下注意事项: 如果组件正在使用中 在Experience Builder的页面上,从页面中删除组件并将其替换为 更新后的版本。否则,当您导出网站内容进行翻译时, 对于导出文件中的该组件实例,将省略您添加的属性。如果 该组件包含已翻译的内容,请先将网站内容导出到 保留现有翻译。然后将组件替换为更新的 版本。

属性

  • 使用设计文件来控制向Experience Builder公开哪些属性。
  • 使您的属性易于使用,便于管理员理解。不要暴露 SOQL 查询、JSON 对象或 Apex 类名。
  • 为必需属性提供默认值,以避免用户体验不佳。当 具有必需属性且没有默认值的组件将添加到体验中 生成器,它看起来无效。
  • 使用基本支持的类型 (, , ) 公开的属性。stringintegerboolean
  • 为元素中的整数属性指定最小值和最大值,以控制接受值的范围。<design:attribute>
  • 请注意,字符串属性可以为数据源提供一组预定义的 值,允许属性将其配置公开为选择列表。
  • 为属性提供具有友好显示名称的标签。
  • 包括描述以解释预期数据并提供指南,例如 数据格式或预期的值范围。描述文本在 属性面板。
  • 若要删除实现接口的组件的设计属性,请首先 在删除 design 属性之前,从组件中删除接口。然后 重新实现接口。如果在网站页面中引用了该组件,则必须删除 该组件,然后才能更改它。forceCommunity:availableForAllPageTypes

支持的 Aura 组件、接口和事件

并非所有 Aura 组件、接口和事件都支持基于 Aura 的体验 建设者网站。有些仅适用于 Salesforce 移动应用程序或 Lightning Experience。 在自定义您的网站之前,请查看可用的内容。

Aura 组件、接口和事件记录在组件库中。每 组件、接口和事件指示它支持哪种体验。

个性化目标开发人员和组名称

在以下情况下确定体验变体目标的开发人员名称和组名称 使用 Connect REST API 或元数据 API 对 Experience Builder 站点进行个性化设置。

对于 Connect Rest API 的 Target Input 请求正文或 Audience 元数据类型的 PersonalizationTargetInfo 子类型,您必须指定:

  • 属性中的目标组名称groupName
  • 属性中的目标开发人员名称targetValue

若要确定这些名称,必须从 站点的 ExperienceBundle 文件夹。

确定这些值的方式会有所不同,具体取决于您是否定位到网页 变体、品牌集、组件 可见性或组件属性。

页面变体

要确定页面变体的组名称和开发人员名称,请打开相关的 路由文件和相应的视图文件。例如,打开 routes 文件夹中的 Home.json 文件和 views 文件夹中的 Home.json 文件。组名称Format: ,其中 是路由 JSON 文件的属性。route.idroute.idid

例: 63d9b8fe-99fc-4f54-b784-5034e09a6670开发商名称格式: ,其中:route.label_view.label_Page

  • route.label是路由 JSON 文件的属性。label
  • view.label是视图 JSON 文件的属性。label

例: Home_Gold_Home_Page

品牌集

若要确定品牌集的组名称和开发人员名称,请打开相关的 品牌设置文件和相应的主题文件。例如,在客户服务网站中, 打开 themes 文件夹中的 customerService.json 文件和 brandingSets 文件夹中的 customerService.json 文件。组名称格式: ,其中 是 主题 JSON 文件。theme.id$#$Brandingtheme.idid

例: 70ebee67-0fca-421e-ac32-12879ee55936$#$Branding开发商名称格式: ,其中:theme.developerName_brandingSet.label_Branding

  • theme.developerName是主题 JSON 文件的属性。developerName
  • brandingSet.label是品牌集 JSON 文件的属性。label

例: service_Customer_Service_Branding

组件可见性

确定组名和 开发人员名称 对于组件可见性,请打开包含该组件的视图文件。为 例如,打开 views 文件夹中的 Home.json 文件。组名称格式: ,其中:view.id$#$component.id

  • view.id是属性 的视图 JSON 文件。id
  • component.id是视图 JSON 文件中组件的属性。id

例: f8c9b721-0a1d-45bb-954f-3277a0501892$#$823cb1c0-697f-4b33-8fa4-a925aef98cf7开发商名称格式: ,其中:view.label_componentName_Component

  • view.label是视图 JSON 文件的属性。label
  • componentName是体验中组件的名称 生成器(不在 JSON 文件中)。

例: Home_Headline_Component

注意

如果 必要时,您可以向开发人员名称添加一个数值以使其唯一。为 例。Home_Page_Rich_Content_Editor_Component1

组件属性

对于组件属性,组和开发人员名称会有所不同,具体取决于 组件位于视图正文中,或者位于主题布局的页眉或页脚中。

视图主体中的组件

若要确定视图正文中组件的组和开发人员名称,请打开视图 包含组件的文件。例如,打开 Home.json 文件 在“视图”文件夹中。组名称格式: ,其中:view.id$#$component.id

  • view.id是属性 的视图 JSON 文件。id
  • component.id是视图 JSON 文件中组件的属性。id

例: f8c9b721-0a1d-45bb-954f-3277a0501892$#$823cb1c0-697f-4b33-8fa4-a925aef98cf7开发商名称格式: ,其中:view.label_componentName_Component_Properties

  • view.label是视图 JSON 文件的属性。label
  • componentName是体验中组件的名称 生成器(不在 JSON 文件中)。

例: Home_Headline_Component_Properties

注意

如有必要,您可以向开发人员名称添加一个数值,使其唯一。为 例。Home_Page_Rich_Content_Editor_Component1

页眉或页脚中的组件

确定 主题布局,打开包含组件的主题文件。例如,在 Customer 中 服务站点,在主题中打开 customerService.json 文件 文件夹。组名称格式: ,其中:themeLayout.id$#$component.id

  • themeLayout.id是包含组件的布局的属性。id
  • component.id是布局中组件的属性。id

例: 06ce2db9-2c79-4ccc-9ca8-94c7b50efb6b$#$c55d1908-fe6b-47e8-b41e-70ad05aeb490组件属性组名称开发商名称格式: ,其中:themeLayout.label_componentName_Component_Properties

  • themeLayout.label是包含组件的布局的属性。label
  • componentName是体验中组件的名称 生成器(不在 JSON 文件中)。

例: Default_Navigation_Menu_Component_Properties组件属性开发人员名称

遵守用户的个人信息可见性设置

具有门户和站点的组织提供特定设置来隐藏用户的个人信息 来自其他用户的身份信息和联系信息。这些设置不会在 Apex 中强制执行, 即使具有 Apex 安全功能,例如子句或方法。对来宾或外部隐藏特定字段 经过身份验证的用户,请遵循下面概述的示例代码。

WITH SECURITY_ENFORCEDstripInaccessible

若要在 User 对象中隐藏用户的个人信息,请执行以下操作:

public User[] fetchUserDetail(Set userIds) { 
    // Query all the fields of user which we are expected in user record to show that on UI or to 
    // perform some business logic. 
    User[] userRecords = [SELECT id, username, communitynickname, firstname, lastname, title 
    FROM User WHERE id IN :userIds]; 
 
    for (User userRecord : userRecords) { 
        // User is not fetching his own record and is not standard user. 
        if(userRecord.id != UserInfo.getUserId() && !Auth.CommunitiesUtil.isInternalUser()) { 
            // clear-out all PII fields form user record which we have queried above. 
            userRecord.username = ''; 
            userRecord.title = ''; 
        } 
    } 
    return userRecords;
}

遵守用户在社区中的联系信息可见性设置,或者 门户,我们检查与特定字段关联的首选项并显示或隐藏数据 因此。对于用户在 Experience Cloud 中的联系人可见性设置 网站:

public User[] fetchUserRecordRespectingFLVPreferences(Set<Id> userIds) {

    //Fetch users records along with fields specific user preferences.
    User[] userRecords = [SELECT email, UserPreferencesShowEmailToExternalUsers, UserPreferencesShowEmailToGuestUsers FROM User WHERE id IN :userIds];

    // If context user is internal user then return result without any restriction.
    if (Auth.CommunitiesUtil.isInternalUser()) {
        return userRecords;
    }

    // If user is guest user then return result as per the user's UserPreference for the fields related to the Guest user visibility.
    if (Auth.CommunitiesUtil.isGuestUser()){
        return fetchUserRecordForGuestUser(userRecords);
    }

    // Return result as per the user's UserPreference for the fields related to the External user visibility 
    return fetchUserRecordForExternalUser(userRecords);

}

// Apply Field level visibilty logic by checking user's UserPreferences for the fields related to the External user visibility.
public User[] fetchUserRecordForExternalUser(User[] userRecords) {

    for(User userRecord : userRecords) {

        //Clear field of user record when context user fetching other user's record and Field Level Visibility for that field is set to Restricted.
        if(userRecord.id != UserInfo.getUserId() && !userRecord.UserPreferencesShowEmailToExternalUsers)
        {
            userRecord.email = '';
        }

    }   

    return userRecords;         
}

// Apply Field level visibilty logic by checking user's UserPreferences for the fields related to the Guest user visibility.
public User[] fetchUserRecordForGuestUser(User[] userRecords) {

    for(User userRecord : userRecords) {

        //Clear field of user record when context user fetching other user's record and user preference for that field is NOT set to public.
        if(!userRecord.UserPreferencesShowEmailToGuestUsers)
        {
            userRecord.email = '';
        }

    }   

    return userRecords;       

}