相关文章推荐
沉稳的围巾  ·  博客导航 - lindexi ·  4 周前    · 
耍酷的炒饭  ·  Gitea和Nginx配置·  1 年前    · 
深情的鸵鸟  ·  javascript - ...·  2 年前    · 

现代网站在很大程度上依赖于由复杂的JavaScript和CSS代码驱动的客户端处理。 组织和优化此代码的服务可能是一个复杂的问题。

为了帮助解决此问题,AEM提供了​ 客户端库文件夹 ,可让您将客户端代码存储在存储库中,将其按类别整理,并定义何时以及如何向客户端提供每种类别的代码。 然后,客户端库系统负责在最终网页中产生正确的链接,以加载正确的代码。

AEM中客户端库的工作原理 how-client-side-libraries-work-in-aem

在页面的HTML中包含客户端库(即,JS或CSS文件)的标准方法是,在该页面的JSP中包含 <script> <link> 标记,并包含相关文件的路径。 例如,

<script type="text/javascript" src="/etc/clientlibs/granite/jquery/source/1.8.1/jquery-1.8.1.js"></script> </head>

虽然此方法在AEM中有效,但当页面及其组成组件变得复杂时,它可能会导致问题。 在这种情况下,最终HTML输出中可能会包含同一JS库的多个副本。 为避免这种情况并允许对客户端库进行逻辑组织,AEM使用​ 客户端库文件夹

客户端库文件夹是 cq:ClientLibraryFolder 类型的存储库节点。 CND表示法 中的定义为

[cq:ClientLibraryFolder] > sling:Folder
  - dependencies (string) multiple
  - categories (string) multiple
  - embed (string) multiple
  - channels (string) multiple
        

默认情况下,cq:ClientLibraryFolder节点可以放置在存储库的/apps/libs/etc子树中的任意位置(这些默认值和其他设置可通过系统控制台的​ Adobe Granite HTML库管理器 ​面板进行控制)。

每个cq:ClientLibraryFolder都填充了一组JS和/或CSS文件以及几个支持文件(见下文)。 cq:ClientLibraryFolder的属性配置如下:

categories:标识此cq:ClientLibraryFolder内的JS和/或CSS文件集所属的类别。 categories属性是多值属性,它允许库文件夹成为多个类别的一部分(请参阅下面的内容,了解其用处)。

dependencies:这是此库文件夹所依赖的其他客户端库类别的列表。 例如,在给定两个cq:ClientLibraryFolder节点FG的情况下,如果F中的某个文件需要G中的另一个文件才能正常工作,则Gcategories中至少有一个应属于Fdependencies中。

embed:用于嵌入来自其他库的代码。 如果节点F嵌入节点G和H,则生成的HTML将是来自节点G和H的内容集。

allowProxy:如果客户端库位于/apps下,则此属性允许通过代理servlet访问它。 请参阅下面的查找客户端库文件夹并使用代理客户端库Servlet

引用客户端库 referencing-client-side-libraries

由于HTL是开发AEM站点的首选技术,因此应使用HTL在AEM中包含客户端库。 但是,也可以使用JSP执行此操作。

使用HTL using-htl

在HTL中,通过AEM提供的帮助程序模板来加载客户端库,该模板可通过data-sly-use访问。 此文件中有三个可用的模板,可以通过data-sly-call来调用它们:

每个帮助程序模板都需要一个 categories 选项来引用所需的客户端库。该选项可以是字符串值的数组,也可以是包含逗号分隔值列表的字符串。

有关详细信息和使用示例,请参阅文档HTML模板语言快速入门

使用JSP using-jsp

ui:includeClientLib标记添加到您的JSP代码中,以便在生成的HTML页面中添加指向客户端库的链接。 要引用库,请使用ui:includeClientLib节点的categories属性的值。

<%@taglib prefix="ui" uri="https://www.adobe.com/taglibs/granite/ui/1.0" %>
<ui:includeClientLib categories="<%= categories %>" />
        

创建客户端库文件夹 creating-client-library-folders

创建一个cq:ClientLibraryFolder节点以定义JavaScript和层叠样式表库并将它们提供给HTML页面。 使用节点的categories属性标识它所属的库类别。

该节点包含一个或多个在运行时合并到单个JS和/或CSS文件中的源文件。 生成的文件的名称是具有.js.css文件扩展名的节点名称。 例如,名为cq.jquery的库节点会生成名为cq.jquery.jscq.jquery.css的文件。

客户端库文件夹包含以下项目:

有关特定于小组件的客户端库要求的信息,请参阅使用和扩展小组件

Web客户端必须具有访问cq:ClientLibraryFolder节点的权限。 您还可以从存储库的安全区域公开库(请参阅下面的嵌入其他库的代码)。

覆盖/lib中的库 overriding-libraries-in-lib

位于/apps下方的客户端库文件夹优先于/libs中类似的同名文件夹。 例如,/apps/cq/ui/widgets优先于/libs/cq/ui/widgets。 当这些库属于同一类别时,将使用/apps以下的库。

查找客户端库文件夹并使用代理客户端库Servlet locating-a-client-library-folder-and-using-the-proxy-client-libraries-servlet

在以前的版本中,客户端库文件夹位于存储库中的/etc/clientlibs下方。 这仍受支持,但建议客户端库现在位于/apps下。 这是为了在其他脚本附近找到客户端库,这些脚本通常位于/apps/libs下方。

客户端库文件夹下的静态资源必须位于名为​ resources ​的文件夹中。 如果文件夹​ 资源 ​下没有静态资源(如图像),则无法在发布实例上引用该资源。 示例如下: https://localhost:4503/etc.clientlibs/geometrixx/components/clientlibs/resources/example.gif

为了能够访问/apps下的客户端库,使用了代理servlet。 仍在客户端库文件夹上强制执行ACL,但如果allowProxy属性设置为true,则servlet允许通过/etc.clientlibs/读取内容。

如果静态资源位于客户端库文件夹下的资源下,则只能通过代理访问。

Adobe建议查找/apps下的客户端库,并使用代理servlet使其可用。 但是,请记住,最佳做法仍然要求公共站点从不包含直接通过/apps/libs路径提供的任何内容。

创建客户端库文件夹 create-a-client-library-folder

打开文件并键入以下文本以标识源文件路径的根:

#base=*[root]*

将* [root]*替换为包含源文件的文件夹相对于TXT文件的路径。 例如,当源文件与TXT文件位于同一文件夹时,请使用以下文本:

#base=.

以下代码将根设置为cq:ClientLibraryFolder节点下名为mobile的文件夹:

#base=mobile

#base=[root]下面的行中,键入源文件相对于根的路径。 将每个文件名放在单独的一行中。

单击​ 全部保存

链接到依赖项 linking-to-dependencies

当客户端库文件夹中的代码引用其他库时,将其他库标识为依赖项。 在JSP中,引用客户端库文件夹的ui:includeClientLib标记会导致HTML代码包含指向生成的库文件和依赖项的链接。

依赖项必须是另一个cq:ClientLibraryFolder。 要识别依赖关系,请使用以下属性向您的cq:ClientLibraryFolder节点添加属性:

嵌入来自其他库的代码 embedding-code-from-other-libraries

您可以将来自客户端库的代码嵌入到另一个客户端库中。 在运行时,生成的嵌入库的JS和CSS文件包含嵌入库的代码。

嵌入代码可用于提供对存储在存储库安全区域中的库的访问权限。

特定于应用程序的客户端库文件夹 app-specific-client-library-folders

最佳做法是将应用程序文件夹中所有与应用程序相关的文件保留在/apps以下。 拒绝网站访客访问/apps文件夹也是最佳实践。 为满足这两个最佳实践,请在/apps下创建一个客户端库文件夹,并使其可通过查找客户端库文件夹和使用代理客户端库Servlet中所述的代理servlet访问。

使用类别属性可标识要嵌入的客户端库文件夹。 要嵌入库,请使用以下属性将属性添加到嵌入cq:ClientLibraryFolder节点:

<script type="text/javascript" src="/etc/clientlibs/granite/jquery.js"></script>
<script type="text/javascript" src="/etc/clientlibs/granite/utils.js"></script>
<script type="text/javascript" src="/etc/clientlibs/granite/jquery/granite.js"></script>
<script type="text/javascript" src="/etc/clientlibs/foundation/jquery.js"></script>
<script type="text/javascript" src="/etc/clientlibs/foundation/shared.js"></script>
<script type="text/javascript" src="/etc/clientlibs/foundation/personalization/kernel.js"></script>
        

在这种情况下,有必要将所有所需的客户端库代码合并到单个文件中,以便减少页面加载上的来回请求数量。 为此,您可以使用cq:ClientLibraryFolder节点的嵌入属性,将所需的库embed到特定于应用程序的客户端库中。

AEM中包含以下客户端库类别。 您应该仅嵌入运行特定站点所需的那些项目。 但是,您应该保持此处列出的顺序

  • personalization.core.kernel
  • personalization.clientcontext.kernel
  • personalization.stores.kernel
  • personalization.kernel
  • personalization.clientcontext
  • personalization.stores
  • cq.collab.comments
  • cq.collab.feedlink
  • cq.collab.ratings
  • cq.collab.toggle
  • cq.collab.forum
  • cq.cleditor
  • padding: 0; margin: 0; background: url(../../../apps/myapp/clientlib/styles/images/bg-full.jpg) no-repeat center top; width: 100%;

    将库用于特定移动组 using-a-library-for-specific-mobile-groups

    使用客户端库文件夹的channels属性来标识使用该库的移动组。 当针对不同的设备功能设计相同类别的库时,channels属性非常有用。

    要将客户端库文件夹与设备组关联,请将具有以下属性的属性添加到您的cq:ClientLibraryFolder节点:

    使用预处理器 using-preprocessors

    AEM允许可插拔的预处理器,并随附对CSS和JavaScript的YUI Compressor和JavaScript的Google Closure Compiler (GCC)的支持,并将YUI设置为AEM的默认预处理器。

    可插拔预处理器允许灵活使用,包括:

    config:= mode ":" processorName options*;
    mode:= "default" | "min";
    processorName := "none" | <name>;
    options := ";" option;
    option := name "=" value;
                  
    failOnWarning (defaults to "false")
    languageIn (defaults to "ECMASCRIPT5")
    languageOut (defaults to "ECMASCRIPT5")
    compilationLevel (defaults to "simple") (can be "whitespace", "simple", "advanced")
            

    AEM提供了几种用于调试和测试客户端库文件夹的工具。

    请参阅嵌入的文件 see-embedded-files

    要跟踪嵌入代码的来源,或确保嵌入的客户端库产生预期的结果,您可以查看运行时嵌入的文件的名称。 要查看文件名,请将debugClientLibs=true参数附加到网页的URL。 生成的库包含@import语句,而不是嵌入的代码。

    在上一个嵌入来自其他库的代码部分的示例中,/etc/client/libraries/myclientlibs/publicmain客户端库文件夹嵌入了/apps/myapp/clientlib客户端库文件夹。 将参数附加到网页会在网页的源代码中生成以下链接:

    <link rel="stylesheet" href="/etc/clientlibs/mycientlibs/publicmain.css">
            

    发现客户端库 discover-client-libraries

    /libs/cq/granite/components/dumplibs/dumplibs组件生成系统上所有客户端库文件夹的信息页面。 /libs/granite/ui/content/dumplibs节点将组件作为资源类型。 要打开该页面,请使用以下URL(根据需要更改主机和端口):

    https://<host>:<port>/libs/granite/ui/content/dumplibs.test.html

    该信息包括库路径和类型(CSS或JS)以及库属性的值(如类别和依赖项)。 页面上的后续表将显示每个类别和渠道中的库。

    查看生成的输出 see-generated-output

    dumplibs组件包括一个测试选择器,该选择器显示为ui:includeClientLib标记生成的源代码。 该页面包含用于不同js、css和主题属性组合的代码。