扩展 RenderField.GetFieldValue 处理器 - 并非所有与页面关联的项目都被处理
Extending the RenderField.GetFieldValue processor - not all items associated with the page are processed
我有一个富文本字段,其中包含用于 HTML 中嵌入图像的某些标记({{alt}}
和 {{title}}
)。我扩展了 Sitecore.Pipelines.RenderField.GetFieldValue
处理器,以便在前端呈现页面时,处理器会将这些标记替换为媒体项中的 alt 和 title 字段值。不幸的是,我的自定义处理器只处理一组特定的项目(特别是 WFFM 字段),它不处理我的 Body
具有标记的字段,即使我知道我正在浏览的页面正在呈现该字段(代码 运行 在布局上是 @Html.Sitecore().Field("Body")
这意味着它应该由管道处理,对吗?)
我也尝试了 GetTextFieldValue
和 GetMemoFieldValue
处理器,但处理的是相同的项目。寻找一些关于具体应由该管道处理哪些字段的指导。
这是我的 Process() 函数:
public void Process(RenderFieldArgs args)
{
Assert.ArgumentNotNull(args, "args");
Assert.ArgumentNotNull(args.Item, "args.Item");
Assert.ArgumentNotNull(args.GetField(), "args.GetField()");
if (args.Item.Database == Database.GetDatabase("web"))
{
if (args.GetField().Value.Contains("{{alt}}"))
{
args.GetField().Value = ReplaceAltToken(args.GetField().Value);
}
if (args.GetField().Value.Contains("{{title}}"))
{
args.GetField().Value = ReplaceTitleToken(args.GetField().Value);
}
if (args.GetField().Name == "Body")
{
// Since we're rendering the body field differently we need to expand dynamic links
args.Item.Editing.BeginEdit();
args.GetField().Value = Sitecore.Links.LinkManager.ExpandDynamicLinks(args.GetField().Value);
args.Item.Editing.EndEdit();
}
}
}
我的配置包含文件:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<renderField>
<processor
type="[Redacted].Processor.RenderField.GetFieldValueExtended, [Redacted].Processor"
patch:after="processor[@type='Sitecore.Pipelines.RenderField.GetFieldValue, Sitecore.Kernel']" />
</renderField>
</pipelines>
</sitecore>
解决这个问题有多个步骤。取消选中所有效果图上的 Cacheable
是重要的第一步。我遇到的其余问题很可能是我的解决方案特有的(设计不佳,很快就会重构)。
我的本地站点没有最新的文件。当我更新文件时,我仍然 运行 进入 Attempt to retrieve context object of type 'Sitecore.Mvc.Presentation.PageContext' from empty stack
错误,我可以通过在模型的简单 GetBody() 函数中调用 Sitecore.Web.UI.WebControls.FieldRenderer.Render(item, "Body")
而不是 Html.Sitecore().Field("Body")
。然后在视图中我简单地输入 @Html.Raw(Model.Body)
.
我认为 .Field()
助手没有工作,因为与请求的字段关联的项目是未知的,所以另一个解决方法是使用 Html.Sitecore().Field("Body", item)
直接在参数中指定项目。
我有一个富文本字段,其中包含用于 HTML 中嵌入图像的某些标记({{alt}}
和 {{title}}
)。我扩展了 Sitecore.Pipelines.RenderField.GetFieldValue
处理器,以便在前端呈现页面时,处理器会将这些标记替换为媒体项中的 alt 和 title 字段值。不幸的是,我的自定义处理器只处理一组特定的项目(特别是 WFFM 字段),它不处理我的 Body
具有标记的字段,即使我知道我正在浏览的页面正在呈现该字段(代码 运行 在布局上是 @Html.Sitecore().Field("Body")
这意味着它应该由管道处理,对吗?)
我也尝试了 GetTextFieldValue
和 GetMemoFieldValue
处理器,但处理的是相同的项目。寻找一些关于具体应由该管道处理哪些字段的指导。
这是我的 Process() 函数:
public void Process(RenderFieldArgs args)
{
Assert.ArgumentNotNull(args, "args");
Assert.ArgumentNotNull(args.Item, "args.Item");
Assert.ArgumentNotNull(args.GetField(), "args.GetField()");
if (args.Item.Database == Database.GetDatabase("web"))
{
if (args.GetField().Value.Contains("{{alt}}"))
{
args.GetField().Value = ReplaceAltToken(args.GetField().Value);
}
if (args.GetField().Value.Contains("{{title}}"))
{
args.GetField().Value = ReplaceTitleToken(args.GetField().Value);
}
if (args.GetField().Name == "Body")
{
// Since we're rendering the body field differently we need to expand dynamic links
args.Item.Editing.BeginEdit();
args.GetField().Value = Sitecore.Links.LinkManager.ExpandDynamicLinks(args.GetField().Value);
args.Item.Editing.EndEdit();
}
}
}
我的配置包含文件:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<renderField>
<processor
type="[Redacted].Processor.RenderField.GetFieldValueExtended, [Redacted].Processor"
patch:after="processor[@type='Sitecore.Pipelines.RenderField.GetFieldValue, Sitecore.Kernel']" />
</renderField>
</pipelines>
</sitecore>
解决这个问题有多个步骤。取消选中所有效果图上的 Cacheable
是重要的第一步。我遇到的其余问题很可能是我的解决方案特有的(设计不佳,很快就会重构)。
我的本地站点没有最新的文件。当我更新文件时,我仍然 运行 进入 Attempt to retrieve context object of type 'Sitecore.Mvc.Presentation.PageContext' from empty stack
错误,我可以通过在模型的简单 GetBody() 函数中调用 Sitecore.Web.UI.WebControls.FieldRenderer.Render(item, "Body")
而不是 Html.Sitecore().Field("Body")
。然后在视图中我简单地输入 @Html.Raw(Model.Body)
.
我认为 .Field()
助手没有工作,因为与请求的字段关联的项目是未知的,所以另一个解决方法是使用 Html.Sitecore().Field("Body", item)
直接在参数中指定项目。