在 Orchard 中是否可以在渲染之前动态更改 HTML 形状?

Is it possible in Orchard to dynamically change HTML in a shape right before rendering?

这是 Content.ThumbnailSummary.cshtml 的标记,我使用自定义 DisplayType 将 ContentItems 呈现为可点击的缩略图,其内容绝对位于它们之上。

@using Orchard.Utility.Extensions;
@{
    var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
}
<a class="content-item @contentTypeClassName thumbnail-summary">
    @Display(Model.Header)
    <div class="thumbnail-summary-inner">
        @Display(Model.Content)
    </div>
    @Display(Model.Footer)
</a>

问题是,大多数部分和字段开箱即用地呈现为链接或包含链接的段落,并且嵌套的 <a> 标签在大多数浏览器中搞得一团糟 DOM 呈现非常糟糕。 ThumbnailSummary 应该从不 包含任何链接。

我可以为每个字段和部分创建替代项,或者我可以默认删除放置中的所有内容,只在需要时为特定情况添加规则。但这会非常乏味并且会破坏放置的很多好处,所以我希望我可以以某种方式去除或替换代码中的所有 <a> 标签,仅用于具有此 DisplayType 的形状。

我一直在寻找这个方向,但我不确定它是否可行:

public class Shapes : IShapeTableProvider
{
    public void Discover(ShapeTableBuilder builder)
    {
        builder.Describe("Content")
            .OnDisplaying(displaying =>
            {
                if (displaying.ShapeMetadata.DisplayType == "ThumbnailSummary")
                {             
                    // Do something here???
                }
            });
    }
}

你几乎是对的,而不是提供者添加一个继承自 Orchard.DisplayManagement.Implementation.ShapeDisplayEvents 的 class 或自己实现 IShapeDisplayEvents

我自己这样做是为了从管理区域中删除无法通过功能或权限禁用的某些功能。

代码应该如下所示

public class MyShapeDisplayEvents : Orchard.DisplayManagement.Implementation.ShapeDisplayEvents
{
  public override void Displayed(Orchard.DisplayManagement.Implementation.ShapeDisplayedContext context)
  {
    if (context.Shape is Orchard.DisplayManagement.Shapes.Shape)
    {
      Orchard.DisplayManagement.Shapes.Shape lShape = (Orchard.DisplayManagement.Shapes.Shape)context.Shape;

      if (lShape.Metadata.Type == "Layout")
      { 
        string lChildContent = context.ChildContent.ToHtmlString();

        // do something with the content like removing tags

        context.ChildContent = new System.Web.HtmlString(lChildContent);
      }

      ...