C# 如何编写转换以支持多种不同的页面类型?

C# 如何编写转换以支持多种不同的页面类型?,c#,kentico,C#,Kentico,我有一个“promo”小部件,它包装了内置的通用页面查看器web部件。编辑可以将促销小部件添加到他们的页面,以便链接到站点中的任何其他页面。他们添加的促销小部件将显示链接页面的名称和该页面的摘要图像 小部件被配置为显示路径字段,以便编辑器可以选择他们正在升级的页面,并且将TransformationName字段的默认值设置为“CMS.MenuItem.Promo”。TransformationName字段标记为不可编辑 我真的希望编辑器能够将他们的promo小部件指向站点中的任何页面,而不必担心

我有一个“promo”小部件,它包装了内置的通用页面查看器web部件。编辑可以将促销小部件添加到他们的页面,以便链接到站点中的任何其他页面。他们添加的促销小部件将显示链接页面的名称和该页面的摘要图像

小部件被配置为显示路径字段,以便编辑器可以选择他们正在升级的页面,并且将TransformationName字段的默认值设置为“CMS.MenuItem.Promo”。
TransformationName
字段标记为不可编辑

我真的希望编辑器能够将他们的promo小部件指向站点中的任何页面,而不必担心他们指向的节点类型,因此我希望使CMS.MenuItem.promo转换支持任何页面类型

我的想法是添加自定义转换方法,如:

namespace CMS.Controls
{
    public partial class CMSTransformation
    {
        public string GetTeaser()
        {
            TreeNode node = this.get_the_current_node_somehow...();
            Page page = new PageFactory().GetPage(node);
            return page.GetTeaserRelativeURL();
        }
然后,我可以在转换中包含以下内容,编辑器不需要关心节点的类型:

<img src="<%# GetTeaser() %>" />
e、 g.CMS_MenuItem只是:

public class CMS_MenuItem : Page
{
    public const string TeaserField = "MenuItemTeaserImage";
    private readonly TreeNode node;
    public CMS_MenuItem(TreeNode node)
    {
        this.node = node;
    }
    public override string GetTeaserRelativeURL()
    {
        var guid = node.GetValue<Guid>(TeaserField, Guid.Empty);
        return AttachmentURLProvider.GetAttachmentUrl(guid, node.NodeAlias);
    }
公共类CMS\u菜单项:第页
{
public const string tasterfield=“menuitemtasterrimage”;
私有只读树节点;
公共CMS_菜单项(树节点)
{
this.node=节点;
}
公共重写字符串GetTeserRelativeUrl()
{
var guid=node.GetValue(striserfield,guid.Empty);
返回AttachmentURLProvider.GetAttachmentUrl(guid,node.NodeAlias);
}
是否可以在转换方法中获取
TreeNode
对象?如果可以,我可以使用现有代码获取摘要图像,而不考虑节点的类型

如果在转换方法中无法获取
TreeNode
,那么无论当前页面类型如何,获取字段的最干净方法是什么


我知道
GetNotEmpty()
GetColumnName()
转换方法,但每次我尝试获取字段时都要传递一个包含12个列名的列表,这似乎很难看。

我认为对每种页面类型进行特定转换会更容易。您可以使用相同的代码进行转换,例如Promo,并对每种页面类型进行此转换。在您的小部件/web部件将通过宏初始化属性。宏将只获取显示的页面类型代码名。给定属性的默认值可能类似于:

{%my\u macro\u to\u get\u page\u type\u code\u name%}.promo


我想您也可以通过标准K#语言获取代码名,但我个人还没有这样做。另一种方法是使用自定义表单控件,它可以根据您的喜好进行初始化。

我认为对每个页面类型进行特定转换会更容易。您可以使用相同的代码进行转换,例如。Promo并对每种页面类型进行此转换。在小部件/web部件的设置中,您可以通过宏初始化属性。宏只需获取显示的页面类型代码名。给定属性的默认值可能类似于:

{%my\u macro\u to\u get\u page\u type\u code\u name%}.promo


我想您也可以通过标准K#语言获取代码名,但我个人还没有这样做。另一种方法是使用自定义表单控件,它可以根据您的喜好进行初始化。

感谢Boris的回答,这听起来应该可以工作,但似乎TransformationName中没有调用我的宏字段。我已在CustomMacros.cs中添加了一个Utils.PageType()。我已将Visual Studio调试器附加到该站点,并在宏上设置了一个断点。如果我在页面上包含“{%Utils.PageType()%}”,则会命中该断点,但如果我呈现一个包含转换名称“{%Utils.PageType()%}.Promo”的小部件然后断点没有命中。所以看起来TransformationName字段中的宏没有被调用?我还尝试将TransformationName设置为“{%classname%}.Promo”当我将Universal Page Viewer指向某个事件时,不会调用现有的CMS.Event.Promo转换。如果我没有记错,则必须将宏设置为给定字段的默认值,并且编辑器无法编辑该字段。否则,如果在编辑器可访问的字段上解决宏,这将是一个安全缺陷。I'我已经用一个内置宏快速测试了这一点,它似乎解决得很好:嗨,Boris。我可以确认没有调用宏,因为编辑器可以编辑该字段-但现在这已经解决了,我仍然无法获取中继器正在转换的项的页面类型。“{%classname%}”在自定义宏“context.RelatedObject”中,只给出保存转发器的页面的页面类型是带有转发器的页面的PageTemplateInstance对象,而不是转换的项。DocumentContext.CurrentDocument显然是包含转发器的文档。是否可以获取重复项的页面类型?感谢Boris的回答,听起来应该可以工作,但似乎没有调用我的宏TransformationName字段。我已在CustomMacros.cs中添加了一个Utils.PageType()。我已将Visual Studio调试器附加到站点,并在宏上设置了一个断点。如果我在页面上包含“{%Utils.PageType()%}”,则会命中该断点,但如果我呈现了一个包含转换名称“{%Utils.PageType()%}.Promo”的小部件然后断点没有命中。所以看起来TransformationName字段中的宏没有被调用?我还尝试将TransformationName设置为“{%classname%}.Promo”当我将Universal Page Viewer指向某个事件时,不会调用现有的CMS.Event.Promo转换。如果我没有记错,则必须将宏设置为给定字段的默认值,并且edi无法编辑该字段
public class CMS_MenuItem : Page
{
    public const string TeaserField = "MenuItemTeaserImage";
    private readonly TreeNode node;
    public CMS_MenuItem(TreeNode node)
    {
        this.node = node;
    }
    public override string GetTeaserRelativeURL()
    {
        var guid = node.GetValue<Guid>(TeaserField, Guid.Empty);
        return AttachmentURLProvider.GetAttachmentUrl(guid, node.NodeAlias);
    }