如何为 sitecore 分支模板添加新的自定义标准值令牌?

How can I add a new custom standard value token for sitecore branch templates?

Sitecore 在创建分支模板时附带了几个标准的自定义值标记(即 $name 用于新项目的名称,$parentid 用于父项目的 ID)。

有没有办法添加新的变量?

具体来说,我想要一个允许我在添加时访问项目路径的变量?

这个 ADD CUSTOM STANDARD VALUES TOKENS IN THE SITECORE ASP.NET CMS 有一个 sitecore 博客 post,但是老实说,这是错误的。我不确定为什么 sitecore 坚持在这些 post 中一直生产“ 未经测试的原型 ”。该博客中的人字面意思是 您可以根据以下 未经测试的原型实施解决方案 o_O


出于某种原因,sitecore 正在跳过各种环节来反编译源代码,然后重新创建它(给一个人一把锤子,也许一切看起来都像钉子?)。如果默认行为发生变化,这会使您的代码非常脆弱,而且完全没有必要。

您可以在几行代码中添加一个新变量:

public class NewVariablesReplacer : MasterVariablesReplacer
{
    public override string Replace(string text, Item targetItem)
    {
        //still need to assert these here
        Sitecore.Diagnostics.Assert.ArgumentNotNull(text, "text");
        Sitecore.Diagnostics.Assert.ArgumentNotNull(targetItem, "targetItem");
        string tempTxt = text;


        if (text.Contains("$path"))
        {
            Sitecore.Diagnostics.Assert.ArgumentNotNull(targetItem.Paths, "targetItem.Paths");
            Sitecore.Diagnostics.Assert.ArgumentNotNull(targetItem.Paths.FullPath, "targetItem.Paths.FullPath");
            tempTxt = text.Replace("$path", targetItem.Paths.FullPath);
        }
        
        //Do what you would normally do.
        return base.Replace(tempTxt, targetItem);
    }
}

这无需反编译即可工作,因为它通过调用 base.Replace(text, targetItem);.

保留了基本功能

然后您需要像博客 post 中那样更改 xml 中的默认行为:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <settings>
      <setting name="MasterVariablesReplacer">
        <patch:attribute name="value">Sitecore.Sharedsource.Data.NewVariablesReplacer ,Sitecore.Sharedsource</patch:attribute>
      </setting>
    </settings>
  </sitecore>
</configuration>

开箱即用,我们可以使用这些变量:

$name: The item name
$id: The item ID
$parentid: The item ID of the parent item
$parentname: The item name of the parent item
$date: The system date
$time: The system time
$now: The combination of system date and time

令牌是以“$”符号开头的变量。在内容树中创建内容项时,调用的管道是:

<expandInitialFieldValue help="Processors should derive from Sitecore.Pipelines.ExpandInitialFieldValue.ExpandInitialFieldValueProcessor">
  <processor type="Sitecore.Pipelines.ExpandInitialFieldValue.SkipStandardValueItems, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.ExpandInitialFieldValue.CheckSharedField, Sitecore.Kernel" />
  <processor type="Sitecore.Pipelines.ExpandInitialFieldValue.ReplaceVariables, Sitecore.Kernel" /></expandInitialFieldValue>

完成所有工作的管道是:

public override void Process(ExpandInitialFieldValueArgs args)
{
  Assert.ArgumentNotNull((object) args, "args");
  MasterVariablesReplacer variablesReplacer = Factory.GetMasterVariablesReplacer();
  string text = args.SourceField.Value;
  if (variablesReplacer == null)
    args.Result = text;
  else
    args.Result = variablesReplacer.Replace(text, args.TargetItem);
 }

在 ReplaceVariables 处理器中,您会看到调用另一个 class 来完成所有工作。此 class 在 web.config.

部分定义
<setting name="MasterVariablesReplacer" value="Sitecore.Data.MasterVariablesReplacer,Sitecore.Kernel.dll" />

反编译这个class,你会看到执行顺序是Replace > ReplaceValues > ReplaceWithDefault,其中Replace是一个虚方法,而其他的不是。对我们来说幸运的是,这意味着我们可以使用我们自己的自定义子 class 轻松覆盖组合逻辑。

<!--<setting name="MasterVariablesReplacer" value="Sitecore.Data.MasterVariablesReplacer,Sitecore.Kernel.dll" />-->
<setting name="MasterVariablesReplacer" value="Client.SitecoreUtil.SettingsOverrides.MasterVariablesReplacer,Client.Sitecore" />

在我们的自定义 class 中,我们必须使用相同或相似的代码覆盖 Replace 方法。然后我们需要两个本地私有版本的 ReplaceValues 和 ReplaceWithDefault。我们可以对 ReplaceWithDefault 使用相同或相似的代码,但 ReplaceValues 方法是您定义自定义标记并告诉 Sitecore 如何处理它的地方。例如,假设您想用字符串“hello”替换自定义“$test”标记,这将是生成的代码。

private string ReplaceValues(string text, Func<string> defaultName, Func<string> defaultId, Func<string> defaultParentName, Func<string> defaultParentId)
{
        if (text.Length == 0 || text.IndexOf('$') < 0)
            return text;
        ReplacerContext context = this.GetContext();
        if (context != null)
        {
            foreach (KeyValuePair<string, string> keyValuePair in (SafeDictionary<string, string>)context.Values)
                text = text.Replace(keyValuePair.Key, keyValuePair.Value);
        }
        text = this.ReplaceWithDefault(text, "$name", defaultName, context);
        text = this.ReplaceWithDefault(text, "$id", defaultId, context);
        text = this.ReplaceWithDefault(text, "$parentid", defaultParentId, context);
        text = this.ReplaceWithDefault(text, "$parentname", defaultParentName, context);
        text = this.ReplaceWithDefault(text, "$date", (Func<string>)(() => DateUtil.IsoNowDate), context);
        text = this.ReplaceWithDefault(text, "$time", (Func<string>)(() => DateUtil.IsoNowTime), context);
        text = this.ReplaceWithDefault(text, "$now", (Func<string>)(() => DateUtil.IsoNow), context);

        text = this.ReplaceWithDefault(text, "$test", (Func<string>)(() => "hello"), context);

        return text;
}

这就是为 Sitecore 标准值定义自定义标记变量的全部内容。所有工作都在 ReplaceValues 方法中完成。