2007年11月1日,星期四

母版页/页面布局部署为功能未更新

以来 将母版页和页面布局部署为功能 一直是该博客上评论次数最多的文章,而且一些张贴者似乎也遇到了同样的问题,我想写一篇简短的文章,其中提供一些我的经验信息。

因此,这是一个非标准的帖子,如果不影响您,请随时进行调整;-)

无论如何,我决定再做一些测试,看我是不是做错了什么,或者我做的事情是否与遇到问题的人有所不同。我的测试基本上是使用母版页和页面布局(通常与自定义内容类型相关联)建立一个发布站点,然后进行更新过程。这是我发现的:

  • 对文件(12文件夹外部)进行更新,然后XCOPYing这些文件以覆盖12 \ TEMPLATE \ 特征 \ MyFeature \目录中的文件,则成功更新了站点。 无需停用/激活功能。
  • 用一个 解决方案包 部署文件(使用功能时,这通常是我在服务器场环境中所做的事情)- 当我升级解决方案(stsadm -o upgradesolution)时,这再次正确更新了站点。这是可以预料的,因为在下面发生的事情与先前的测试完全相同。 (但是,我还注意到,即使解决方案升级完成后,目录有时也会消失,或者存在,但仍被另一个进程锁定,这意味着即使在Windows资源管理器中也无法访问文件-这有点恼人,但运行解决方案再次升级始终成功。)
  • 在导致对文件进行自定义(例如修改或什至只是用SPD签出)之后,通过功能/解决方案对文件进行的任何后续更新 出现在网站上(尽管可以在SPD中进行进一步的更新)。

简而言之,这就是我所期望的。假设尚未自定义文件,则任何更新文件系统上副本的内容都会导致对该站点的更新。如果它 具有 如果已经过自定义,则不会对文件系统进行更新(因为该文件现已添加到内容数据库中,并且不再使用文件系统版本)。如果您以前没有遇到过, 使用功能部署SharePoint文件时的注意事项-幻影/虚假主机 可能会有所帮助。

因此,我猜测如果覆盖Feature文件时母版页等没有更新,那是因为文件已经以某种方式进行了自定义。不幸的是,要发布文件并不容易-对于其他文件,SharePoint Designer在资源管理器视图中的文件旁边提供了一个方便的蓝点(如果已自定义文件),但是对于母版页/页面布局,这种情况不会发生。可以在下面的AllItems.aspx文件旁边看到蓝点(单击放大):



不幸的是,这也意味着恢复到文件系统上的文件也不是一件容易的事(我们不能像其他SharePoint文件一样,右键单击SPD中的文件并选择“重置为网站定义”)。因此,如果您确实想保留文件系统中引用的页面布局(例如,因为性能至关重要),但这会很麻烦,但是您最终处于这种状态。不过,可以使用API​​还原文件。我不需要自己执行此操作,但是要检查的属性是 SPFile.CustomizedPageStatus 如果返回 SPCustomizedPageStatus.Customized,然后 SPFile.RevertContentStream() 可以使用方法-这将导致SharePoint从今以后使用文件系统上的版本(尽管 请注意,您可能会丢失一些已进行的更新 after the file was 取消托管(自定义)-还原后,您需要将它们重新应用到文件系统文件。请记住,请勿为此使用SPD,否则您将回到开始的地方!)

到目前为止,(合理地)简单明了。

但是,一个海报(代尔彭特)有一个 关于使用Web部件更新页面布局的有趣问题。据我所知,将所有页面实例更新为具有Web部件 在Web部件区域 通过更新布局将是不可能的。这是因为如果使用Web部件区域,则Web部件与页面相关联 实例 而不是页面布局。确实,这可以成为体系结构的力量。它 可能会:

  • 从页面布局创建页面实例时,将默认Web部件添加到区域中。这可以通过使用“功能”部署页面布局并使用 AllUsersWebPart 标签。但是,这不会影响已经创建的页面。
  • 通过将Web部件直接添加到SPD中而不是区域中的页面标记中,将Web部件添加到所有页面中。当然,这意味着Web部件的设置只能由SPD中的页面设计者修改,而不能由站点用户修改。
  • 使用API​​遍历站点中的所有页面,以使用SPFile.GetLimitedWebPartManager()添加/修改Web部件。不用说,这是一种需要在生产中进行大量维护和计划的操作!

如前所述,由于这些问题,Web部件区域体系结构通常不是WCM网站开发等方案的最佳选择,因为在这里我们希望所做的更改能够应用于使用布局的所有页面。

希望这已经有用。与往常一样,如果您与此处详细介绍的经验有所不同,请发表评论,我一定很想听听。

[我也想对原始帖子的评论者(以及其他我一直反应迟钝的评论者)表示诚挚的歉意,因为我花了几周的时间才回来。与我的项目同时上线和搬家有关,希望现在可以恢复正常服务 ;-) ]

16条评论:

匿名 said...

很好的信息,尤其是有关Web部件区域的那部分。我亲身经历了那一幕,这很烦人。幸运的是,原始的Web应用程序完全炸毁了我,所以我不得不重新构建并解决了该问题! ;)

我注意到的一件事是,尽管页面确实会更新,但母版页库中的最后更新日期不会更新。奇。

我遇到了另一个与发布预览图像有关的问题。我将它们添加到我的自定义功能中:

<模块名称=“ PreviewImages”
Url =“ _ catalogs / masterpage / Preview Images”
Path =“ PreviewImages”
RootWebOnly =“ TRUE”>
<文件Url =“ tp_one_col.png”
名称=“ tp_one_col.png”
类型=“ GhostableInLibrary” />
</Module>

然后,我将PagePreviewImage属性添加到页面布局:

<文件Url =“ tp-onecolumn.aspx”
Type =“ GhostableInLibrary”
IgnoreIfAlreadyExists =“真”>
<属性名称=“ ContentType”
Value =“ $ Resources:cmscore,contenttype_pagelayout_name;” />
<属性名称=“标题”
Value =“交易后一栏” />
<属性名称=“ PublishingPreviewImage”
Value =“〜SiteCollection / _catalogs / masterpage / Preview Images / tp_one_col.png,〜SiteCollection / _catalogs / masterpage / Preview Images / tp_one_col.png”></Property>
<属性名称=“ PublishingAssociatedContentType”
Value =“;#Trading Post;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF390016611AA92AAE4F4BA3A28A1CC4C75A3A;#” />
</File>

部署解决方案似乎很好。我可以在网站集上激活该功能;但是,图像不会显示在“预览图像”文件夹中,并且页面布局继续使用默认的页面布局图像。如果我尝试手动将图像上传到“预览图像”文件夹,则会收到错误消息,指出该文件存在并且需要在更新之前检出,但我看不到任何地方。

有任何想法吗?

谢谢!

克里斯·奥'Brien说过...

嗨,科林,

是的,使用功能部件升级文件时,不会更新最后更新的信息。我认为这是因为磁盘上的文件被覆盖,但列表项没有被触及。

关于您的预览图像问题,我认为您对图像的模块声明有些错误。通过与我的比较,我认为要解决此问题,您应该:

-将模块的Url属性设置为“ _catalogs / masterpage”
-设置图像文件“预览图像/tp_one_col.png”的名称属性

我认为这与列表中文件夹的实现方式有关。其他一切看起来都不错。

让我知道是否可以解决。

干杯,

克里斯。

匿名 said...

你太聪明了!您成功完成了一篇文章,让我成功了一半!

我很高兴地说,这些图像现在显示在网站集中的“预览图像”文件夹中。但是,当我创建页面并选择一种自定义布局时,看不到它们。您认为这可能与我的属性声明有关,还是站点配置本身有问题?

再次感谢!

顺便说一句,如果你曾经在明尼阿波利斯市中心,让我给你买午餐!

克里斯·奥'Brien说过...

很乐意帮助老兄:-)

嗯,我以为应该可以。但是,请注意,在您的区域性文件夹下,“母版页画廊”结构下方还有一个PreviewImages文件夹(我假设“ zh-cn”)。其他预览图像存储在这里。

让我们尝试定位该文件夹。完成我上次建议的更改后,也可以尝试以下操作:

-在预览图像的Module元素上,添加以下属性:IncludeFolders =“ ??-??”
-将页面布局上“ PublishingPreviewImage”的“ Value”属性更改为:

“〜SiteCollection / _catalogs / masterpage / zh-CN / Preview Images / tp_one_col.png,〜SiteCollection / _catalogs / masterpage / en-us / Preview Images / tp_one_col.png”

希望这会导致图像最终出现在该较低的文件夹中,并从那里正确引用。

让我发布。

克里斯。

匿名 said...

的SharePoint只是不喜欢放手...

我终于在测试网站集上工作了。我无法获取IncludeFolders =“ ??-??”可以做任何有用的事情,但是我可以通过将模块URL元素更改为“ _catalogs / masterpage / zh-cn”来使其工作。

但是,要使页面布局引用正确的图像,我必须从“母版页画廊”中删除布局,然后重新激活该功能。在我们的Intranet网站上,我无法删除任何布局,因为它们正在使用中。它不是布局页面本身,而是有关布局的元信息。我通过在所有布局中添加注释来进行测试,然后重新部署解决方案。现有页面的注释全部存在,但未在布局的属性中设置预览图像。

我无法更新属性,因为这会使布局重影,对不对?那么,为这些布局添加图像关联的最简单方法是什么?我可以直接在数据库中执行此操作,还是需要编写更新脚本?

谢谢!

克里斯·奥'Brien说过...

好的,如果您要尝试将预览图像添加到已配置的页面布局中,我完全可以相信该功能不会更新这些文件的ListItem(即元数据)。我本以为我上次提供的信息对于新的页面布局应该是不错的-由MS添加的“ PublishingLayouts”功能的快速检查确认了我使用的相同设置。 [注:我的印象是IncludeFolders =“ ??-??”将文件添加到 所有 子文件夹。]

就是否仅编辑ListItem会导致文件重影而言,恐怕我不确定100%。这是我一直想测试但尚未完成的事情。如果您有测试环境,请通过以下方式进行测试:

-编写代码以测试文件的SPFile.CustomizedPageStatus属性
-在测试文件上,检查该值不是SPCustomizedPageStatus.Customized
-编辑元数据
-检查值是否已更改

干杯,

克里斯。

瑞秋说过...

我创建了一个功能,该功能可以部署两个母版页和某些页面布局。母版页部署良好,没有问题,但是页面布局引起了问题。

当我部署功能时,页面布局(它们是新的布局)出现在sharepoint设计器中,但是当您添加新页面时,它们不会出现在我网站的母版页画廊中,也不会出现在页面布局列表中。

在进一步调查中,如果我从Sharepoint Designer签出新的版面设计页面感到高兴,但是当我尝试再次签入它时,出现错误“无法执行此操作。该文件不再签出或已被删除”

部署时绝对不会取消页面布局。

有任何想法吗?
谢谢!拉赫

克里斯·奥'Brien说过...

嗨雷切尔,

嗯,即使它们出现在SharePoint Designer中,在我看来还是有点像您的elements.xml文件可能不太正确。 XML看起来像我的吗 将母版页和页面布局部署为功能?

如果您将其张贴在这里,我很高兴看看。不过,您可能需要删除尖括号。

干杯,

克里斯。

匿名 said...

克里斯,你好

您拥有很棒的博客,并且撰写了很棒的文章。

我是这个有趣话题的发布者。 (deelpunt)。使用Web部件更新页面布局的问题仍然存在。

1.使用功能,并使用AllUsersWebPart标记的页面布局。但是,这不会影响已经创建的页面。

2.通过将Web部件直接添加到SPD中而不是区域中的页面标记中,将Web部件添加到所有页面。当然,这意味着Web部件的设置只能由SPD中的页面设计者修改,而不能由站点用户修改。
3.使用API​​遍历站点中的所有页面,以使用SPFile.GetLimitedWebPartManager()添加/修改Web部件。不用说,这是一种需要在生产中进行大量维护和计划的操作!
如前所述,由于这些问题

概要:

Web部件区域体系结构通常不是WCM网站开发等方案的最佳选择,因为在这里我们希望所做的更改能够应用于使用该布局的所有页面。


备注:我现在使用的选项1是为了更好的部署。但是更新仍然需要通过代码以编程方式添加Webpart来完成。这在部署方案中很困难。

但是,将发布控件和Web部件结合使用的主要原因是可以使用OOB列表视图Web部件和过滤Web部件。一些内容通过列表进行管理。而且过滤可以轻松完成。

因此,这涉及到第二个主题:

我无法使用页面布局中的webpartconnection来工作。

我有一个严重的问题,无法使Webpart连接在pagelayout中工作。

我正在使用两个webpart区域进行页面布局。第一个Webpart区域包含一个DataForm Webpart。第二个包含一个Sharepoint LisFilter Web部件。

我使用DataForm Webpart从SiteCollection中的另一个Web查看List-content。我为DataForm Webpart设置了ConsumerID。然后,我使用列表过滤器Webpart来过滤DataForm。现在,我想在页面布局中设置Webpart连接。因此,从pagelayout创建页面时,过滤会自动发生。内容编辑器仅需要设置过滤器值。

我在页面布局中使用以下代码段来设置webpartconnection:

WebPartPages:SPProxyWebPartManager runat =“服务器” id =“ ProxyWebPartManager”
SPWebPartConnections
WebPartPages:SPWebPartConnection
ID =“ g_0ECAEED5273C475AA0126B9F0395ADB8”
ConsumerConnectionPointID =“ UniqueIDForConsumer”
ConsumerID =“ DataForm1”
ProviderConnectionPointID =“ UniqueIDForRegionConnection”
ProviderID =“ SharepointListFilter1”
WebPartPages:TransformableFilterValuesToFilterValuesTransformer
MappedConsumerParameterName =“主题”
WebPartPages:SPWebPartConnection
SPWebPartConnections
WebPartPages:SPProxyWebPartManager


但是问题是webpartconnection设置不正确。过滤器Web部件仍显示:该过滤器Web部件未连接。我认为ConsumerConnectionPointID和ProviderConnectionPointID有问题。因为我使用了开箱即用的Web部件,所以我不知道[ConnectionProvider]和[ConnectionConsumer]属性是否设置正确。在这些属性中,您可以定义ConsumerConnectionPointID或ProviderConnectionPointID。

[ConnectionConsumer(“ filter”,“ UniqueIDForConsumer”,AllowsMultipleConnections = true)]

要么

[ConnectionProvider(“ Subject”,“ UniqueIDForRegionConnection”,AllowsMultipleConnections = true)]

因为我没有编写自己的Web部件,因此未设置这些属性。

因为您是WCM的权威,所以希望您能为我解决这些问题。许多客户要求使用页面布局,我们必须将发布控件与Webpart结合使用。这会导致很多棘手的情况。

概要:

1必须有可能时,在Webpart区域中的组合发布控件和WebParts可能存在或???还有另一种情况吗? (编写用户控件等)。

2.页面布局:可以完成设置Web部件的连接,还是必须编写用于将Web部件彼此连接的自定义代码。

感谢任何答案。欢迎所有帮助

贝特里克·卡斯滕
凯捷顾问
bertrick.karsten@capgemini.com

克里斯·奥'Brien说过...

嗨Bertrick,

很抱歉没有尽快回应。恐怕我对页面布局中的已连接Web部件没有做任何事情,因此不确定我能提供多少帮助。我以为只要有Web部件管理器,一切都应该可以正常工作。

如果您愿意选择其他方法,则可以选择放弃ListViewWebParts以便使用自定义控件。这些将根据用户输入的参数发出CAML查询。您将不会获得ListViewWebPart提供的完整的“使用列表”体验,但是如果您只想以特定格式列出项目,则可以。如果您需要每个项目(而不是列表工具栏)上的下拉上下文菜单,则可以查看 Codeplex上增强的内容查询Web部件 -您应该能够以编程方式设置QueryOverride属性,以便采用用户输入的参数。

如果您想坚持使用Web部件,那么我绝对会建议您尝试使用代码尝试进行连接。

希望有一定用处。

干杯,

克里斯。

匿名 said...

你好克里斯。
Tnx的启发性文章。尽管我有一些有关重影/不重影辩论的信息。

这一切都与出版网站有关。
一点历史。
在教共享点开发时-尽管我做了很多事情,但我还是让班级进行了一些实验。我们实现了一个微秒计数器,以查看幻影页面和非幻影页面之间的实际区别。
服务器是不同的-我可以得到的东西-包括几个虚拟mashines。
为了取消托管页面,我们使用了SharePoint Designer。我们使自己成为2个工作组站点(wss 3.0),并取消托管默认页面之一,除了在sharePoint Designer中打开和保存文件外,什么也不做。然后我们开始点击页面并记录所有可衡量的响应时间。
这表明ud表示,未托管的页面的执行速度比twing重影页面的执行速度慢16到34倍。
这很容易使我得出这样的结论:如果页面很重要(例如Intranet上的默认页面),则无主机托管将是一个严重的错误。
这就是即时教学。

后来我开始在发布站点(moss 2007)上运行一些测试,并且:SPCustomizedPageStatus返回所有发布页面的Customizen(未托管)。由于上面的实验,我感到发抖:-)
对我来说,取消托管意味着-不会被.NET缓存兑现-再次意味着它会像旧的asp一样逐行加载intrepet。是从顶部搞定这个架构,还是真的没有那么重要(这将是一个问题)。
这个问题的另一部分。
如果版面页面没有被托管,您将不会看到版面页面本身的更改-如您在本文中提到的。可以得出这样的结论,即编辑GHOSTED布局页面会立即改变从该布局创建的所有页面。但是可悲的是,如果用户通过插入Web部件以任何方式更改了页面,或者页面将与布局页面断开连接,在这种情况下,重影/无主机托管的问题对于这个确切的发布页面来说完全是不愉快的。

有什么办法可以改善发布页面的性能?

如果连接到发布页面的页面布局被重影或取消托管,它是否仍会影响性能?

使用某种硬件缓存或适当的输出提示会有所帮助,但会给个性化设置带来很多麻烦,例如即使您是汉娜,也欢迎彼得

克里斯·奥'Brien说过...

每,

首先,对您的延迟表示歉意-您的评论暂时漏掉了。

您提出了一些有趣的观点-我绝对同意非定制页面的性能要优于定制页面,尽管老实说,我不确定您引用的性能统计信息。在发布页面布局方面,再次进行非自定义(即通过功能部件部署)的效果会更好,因此,如果页面加载时间至关重要,则应对此予以考虑。我建议在您的环境中进行性能测试是确定是否绝对必要的一个好主意-通常在添加完所有自定义代码后,我不确定自定义/未自定义是否会像您想象的那样重要。

最后一点,关于将输出缓存与个性化结合起来,关键是使用 缓存后替换 在从缓存中获取主页内容后添加个性化内容(例如“ Welcome Hannah”)。

HTH,

克里斯。

未知说过...

您能否告诉我如何使用Sharepoint网站中的新功能升级已生成的Visual Studio解决方案(使用Sharepoint解决方案生成器)。

1)在为更新的功能创建新解决方案时,我需要删除任何文件吗?
2)运行sysadm upgrade命令后&我尝试打开网站,它给我未找到的错误?你能帮忙吗?

克里斯·奥'Brien说过...

巴维克

害怕我对Solution Generator并没有做很多事情,但是我希望升级可能不会像您想的那么简单-一般来说,SolGen会为您提供站点定义,您可以从中创建新站点,但可以修改站点已经创建的文件不能通过修改定义来完成。您应该通过添加新功能/使用浏览器用户界面/使用对象模型/ STSADM等来进行更改。

HTH,

克里斯。

兰迪花束 said...

克里斯,您再次发表了一篇有趣而有益的文章。在测试过程中,我发现了一些可以增强您的陈述的内容,因此我想发表评论,以便每个人都可以从测试工作中受益。

您提到仅通过SPD检出文件将自定义文件。我通过UI进入“母版页库”并进行了一些测试。签出文件不会自定义页面(就像在SPD中一样),但是签入后页面确实已被自定义。放弃签出还可以确保文件没有被自定义。由于这与您报告SPD工作的方式不同,我想我会指出这一点。

克里斯·奥'Brien说过...

兰迪

感谢您提供有用的说明。

谢谢,

克里斯。