2017年6月11日,星期日

Use an SPFx Application Customizer to add JavaScript (e.g. 头er) to every page in a site

[2017年9月更新了SPFx 1.2 RC0]

用于自定义Office 365中现代SharePoint网站和页面的新工具已经到来(在撰写本文时进行预览,2017年6月)。  These are known as “SharePoint Framework(SPFx)扩展”,并替换一些SharePoint开发人员长期用于提供关键方案的工具,例如:

  • 将JavaScript添加到站点/网站中的每个页面
  • 在每个页面中注入一些内容(例如,巨型菜单/全局导航或消息栏)
  • 集成弹出对话框
  • 将项目添加到SharePoint中的某些工具栏/菜单
  • 更改列表中特定字段的呈现/行为

换句话说,SPFx扩展提供了与CustomActions和JSLink等效的功能–以前的开发方法没有’不一定要翻译成现代网页。

在本文中,我想重点介绍上面列出的前两种情况(粗体)–在每个页面上引用一些JS,并运行一些代码以将某些内容放置在页面的页眉区域中。 Microsoft提供的文档在第二种情况下做得很好,但有时’有一点点视觉效果很好,所以我’将提供更多屏幕截图。一世’我还会谈谈你不这样做的情况’不一定要在页面上添加*内容*,但是您确实想添加*其他形式的脚本*以在每个页面上运行(例如,分析/其他)。

在向页面中注入内容方面,我们现在在现代页面中具有以下区域(注:这些是从SPFx 1.2起的名称):

  • 最佳
  • 底部
  • 对话框容器

N.B.我们可以期望将来有更多区域!这里’顶部(页眉)和底部(页脚)区域的外观如下:

SNAGHTML4eec1a

关键信息

微软目前表示,SPFx扩展将在2017年秋季/秋季达到“一般可用性”(即在所有租户中全面发布并适合生产使用)。在此之前,它们均处于预览状态。

还应注意,使新扩展成为可能的原因是Microsoft对租户的更新(仅在撰写本文时针对开发人员的租户,甚至不包括First Release),以及对开发人员用来入门的Yeoman Generator的更新-这是一个新的一组组件类型,可帮助您开始使用正确的默认代码。

SPFX 1.2的更改

  • 占位符名称的更改– “Top” and “Bottom” insteaad of “PageHeader” and “PageFooter”
  • 不推荐使用onRender()方法/在SPFx扩展中不再使用该方法

现代页面的先前限制

现代页面之所以令人沮丧,是因为:

  • 无法运行自定义脚本
    • 以前的方法(CustomAction + JSLink)添加的全局JS不在此处运行– only on “classic” pages
  • 相应缺乏页面扩展性
    • 无法将内容注入页面

什么’此处的更改是Microsoft提供了一个运行您的代码的钩子,并且还提供了 命名占位符 在现代页面上–您可以向其中添加内容的页面区域。只要您坚持这些区域并且不要’t arbitrarily “hack”通过更改其他DOM元素(例如使用jQuery或类似的元素)来显示该页面,则Microsoft有效地保证对Office 365的更新不会影响您的自定义设置。

您提供的脚本必须安装到应用程序目录并以这种方式部署,这意味着实际上存在批准步骤。这意味着,简单地编辑页面以添加脚本编辑器Web部件不再是简单的选择–脚本必须正常’d由管理员提供。当然对此有很多争论,但最终还是’Microsoft需要采取的措施,以促进更多的治理并保护Office 365作为一个稳定的平台。

Targeting placeholders such as the 最佳 and 底部 zones

在早期版本的SPFx中,某些页面仅具有“顶部”区域,但没有“底部”区域。那’现在已修复,并且如果页面类型(例如,现代页面,网站内容页面,文档库或列表页面等)上存在“顶部”区域,则“底部”区域也会出现:

SNAGHTML53485bb

我在上方显示了一个相对较窄的条形,但是’如果要使用CSS(此图像被缩小),则没有什么可以阻止您将顶部区域变大:

SNAGHTML2418631

但是,当然,这仅适用于现代页面–传统页面通常没有这些区域或不支持SPFx扩展:

SNAGHTML48946

I’稍后将讨论端到端的过程,但是直接看代码-对文档中建议的代码进行一些小的调整/简化,我的代码看起来像这样:

通过在扩展名中添加SCSS文件来实现CSS’s directory –我的名为AppCustomizer.module.scss,具有以下内容:

请记住,这已导入到您的定制程序的类中,例如:

import styles from './AppCustomizer.module.scss';

So, the key elements 这里are:

  • ApplicationBaseCustomizer
  • 使用 this.context.placeholderProvider.tryCreateContent() 引用合适的占位符的方法及其’的内容-它使您可以操作DOM元素的事实(例如,设置innerHTML)

部署选项–全球或逐站点

    在什么方面 同事 您在网站上的定制程序,可以通过两种方式在生产环境中执行此操作:

    • 逐站点 –通过这种方法,您可以在应用程序包装中添加一些声明性XML,然后确保将应用程序从“应用程序目录”安装到扩展应在其中运行的每个站点。具体来说,您的定制程序有一个包含清单文件的清单文件’的ID([MyCustomizer] .manifest.json),并在此之上添加一个带有CustomAction元素的elements.xml文件(就像过去一样!)。这有一个新的"’ClientSideComponentId”属性,并且必须指向您的定制工具的ID。
    • 全局/脚本 –在这种方法中,您将 skipFeatureDeployment 归因于“true” in youre package-solution.json 文件,然后使用CSOM或REST根据需要以编程方式将CustomAction添加到每个网站(例如,通过迭代或包含在某些配置代码中)。看到 //dev.office.com/sharepoint/docs/spfx/tenant-scoped-deployment 更多细节。使用这种方法时,管理员可以选择在安装到应用程序目录中时使SPFx Web部件/扩展名全局可用:

      SNAGHTMLf7281c2

      SPFx Web部件将显示在每个站点中,但是正如我所说,对于SPFx扩展,您还需要使用CustomAction / ClientSideComponentId来照顾到您所需的每个站点/网站的程序化关联/注册。 看我的帖子 管理跨SharePoint网站的租户范围的SPFx扩展 一些PowerShell / C#代码可以做到这一点。

    但是在包装生产之前’是一种模式,您可以在担心打包之前开发/测试定制程序。通过运行一个“gulp serve”在本地并向现代页面添加一些querystring参数,以便从本地主机加载清单– it’s a bit like the “local SPFx workbench”等效,但适用于SPFx扩展程序/定制程序。

    但是我不’t need placeholders –我只想在每个页面上引用一些JavaScript!

    在这种情况下,代码会更简单。如果您有一个外部JS文件,想以一种快速而肮脏的方式进行引用,可以通过将脚本标签动态添加到<head>页面的元素。我的测试表明,在onInit方法中执行此操作似乎很安全,但是onRender方法也可以– in any case, it’只是这样的老式方法:

    但是考虑一下!

    • 如果JS托管在另一个域上,则可能需要在该域上启用CORS(取决于您的JS在做什么)
    • 如果您要引用模块脚本,则可以通过将其作为外部模块中的外部模块来引用,从而以一种更简洁的方式进行操作"externals"config.json文件的部分(请参阅 将外部库添加到SharePoint客户端Web部件 了解更多)。我已经测试过,这种方法确实可以与Application Customizer一起使用
    • 您也可以选择捆绑脚本(如果有必要的话),并确保在定制程序的onRender方法中引用了该脚本。那也应该工作。

    处理

    无论您要定位页面占位符还是仅在每个页面上引用脚本,此过程实际上都是相同的:

    如果需要,更新SPFx Yeoman Generator

    您可能需要做的第一步是更新SPFx Yeoman Generator–假设您已经安装了所有位,则可以通过键入“yo”在命令行上,然后执行更新过程:

    SNAGHTML38f4e932

    选择“更新您的发电机” option and select “@ microsoft / sharepoint”:

    SNAGHTML38f64e11

    SNAGHTML38f7128a

    创建应用程序定制程序扩展

    [注:一世’m本质上是复制/遍历 主要“建立您的第一个扩展” documentation 这里–您也应该参考。]

    一旦您’准备好实际创建您的应用定制程序,可以通过运行该生成器来完成:

    SNAGHTML3902e5e2

    为您的解决方案命名,并确保选择“Extension” option:

    SNAGHTML1dbcd6b

    在这种情况下,我们’重新使用应用程序定制程序(而不是ListView命令集定制程序[CustomAction /工具栏替换]或字段定制器[JSLink /字段替换]):

    SNAGHTML1d772eb

    为您的定制器提供一个名称,然后提供一个描述:

    SNAGHTML212d82d

    然后,生成器将忙于使用适当的文件创建您的应用程序,然后您’ll see:

    SNAGHTML2114dd4

    现在,您的应用程序已创建,您 ’将获得样板代码(在更高版本的SPFx中看起来可能与此稍有不同):

    SNAGHTML2152c30

    It’s a good idea to test running this in debug mode before making any code changes, so do this by running a 喝一口 with the “nobrowser” switch:

    SNAGHTML216506c

    下一步是浏览到新页面,但在URL中添加了一些querystring参数,以便加载定制程序的* local *清单。首先,打开浏览器到现代页面–文档库是一个不错的选择:

    SNAGHTML21b7c46

    然后在记事本或类似工具中,构建所需的querystring参数。这种基本格式是:

    ?loadSPFX=true&
    debugManifestsFile=//localhost:4321/temp/manifests.js&
    customActions={"badba93c-7f98-4a68-b5ed-c87ea51a3145":{"location":"ClientSideExtension.ApplicationCustomizer","properties":{"testMessage":"Hello as property!"}}}
      

    但是你’我需要用您的定制工具中的ID替换ID’s manifest file:

    SNAGHTML224e8a1

    SNAGHTML226aa94

    如果将其粘贴到浏览器窗口中文档库的URL的末尾并按Enter,您将看到与调试模式有关的警告消息:

    SNAGHTML228610e

    点击“Load debug scripts”按钮,然后您的代码应执行,您应该看到结果–在样板代码的情况下,’s an alert box:

    SNAGHTML22a488b

    成功!您’现在,可以在调试模式下运行Application Customizer。

    生产包装(逐站点/声明性方法)

    为此,我建议您按照文档中的步骤操作(从 将扩展部署到SharePoint) –但以下是主要步骤的摘要。最终,它围绕:

    1. 生成您的应用程序,并将捆绑的JS文件部署到CDN之类的地方(就像SPFx Web部件一样)
    2. 将一些打包文件添加到您的应用程序,以便在将应用程序添加到网站时调用自定义程序(有点像功能激活)–实际上,它是功能激活;))
    3. 将应用程序包部署到应用程序目录,然后将其添加到站点

    在过程方面,关键步骤为:

    • 创建SharePoint / Assets文件夹并添加一个elements.xml文件:

      SNAGHTML3954c9a1
    • 将内容添加到elements.xml– set the “ClientSideComponentId”到您的定制工具的标识符,即在[MyCustomizer] .manifest.json文件中找到的标识符 (请记住,如果您打算使用skipFeatureDeployment = 真正并通过脚本进行全局部署,则可以跳过此步骤):

      <?xml version="1.0" encoding="utf-8"?>
      <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
          <CustomAction
              Title="COB Global JS"
              Location="ClientSideExtension.ApplicationCustomizer"
              ClientSideComponentId="5dba1a34-6bbe-42ef-be72-94e01b527ce2">
          </CustomAction>
      </Elements>
            

    • 编辑config \ package-solution.json文件– add a “Features”节点以引用您的elements.xml文件。它需要类似于以下内容:

        "features": [{
            "title": "COB AppCustomizer - global JS",
            "description": "Adds 一些 JavaScript to every page in the site",
            "id": "456da147-ced2-3036-b564-8dad5c1c2e34",
            "version": "1.0.0.0",
            "assets": {        
              "elementManifests": [
                "elements.xml"
              ]
            }
          }]
    •       
    • 请注意与JS捆绑包的CDN托管相关的其他一些步骤(例如,更新‘cdnBasePath’ property in the ‘write-manifests.json’文件),然后分别使用“ gulp bundle --ship”和“ gulp package-solution --ship”来捆绑和打包您的应用。
    • As I say, 头 to 文档 实际执行此操作的全部步骤。

      然后将应用上传到应用目录:

      SNAGHTML2dc2e6a

      请注意,此时,管理员需要信任该应用程序,并将看到远程文件的托管位置-在我的情况下,我使用了Office 365公用CDN:

      SNAGHTML9a5ac5

      然后,您应该看到您的定制程序生效,并且如果您继续查看,’会看到一个网络范围的功能(默认情况下),它将您的定制程序绑定到该站点:

      SNAGHTML2cbe9ae

    其他事项 

    • 财产袋– as shown in the “建立您的第一个扩展” page, there’可以与定制程序一起使用的各种属性包。在生产模式下,属性是在elements.xml文件的CustomAction元素中指定的。在我的示例中,我选择使用直接在代码中指定的值,但是此属性包提供了 一些 分离级别(但仍会烧入您的包装中)

    定制愉快!

    张贴者 Chris O'Brien 23:07  

    3条评论:

    矮羽毛说过...

    这是太棒了!!!现在,我可以嵌入megamenu了,这使我们停止使用现代页面。

    2017年8月4日12:26
    巴努钦塔说过...

    这篇文章很棒,有非常详细的解释。非常感谢克里斯。

    谢谢& Regards,
    巴努

    2018年1月4日12:12
    戴夫说过...

    谢谢克里斯。这是一篇非常有帮助的文章。

    2018年5月10日在10:26

    发表评论