This blog post explains how you can add tokens for Sitecore to expand when users create new items with the Sitecore ASP.NET web Content Management System (CMS).
When a user creates an item based on a data template, if the standard value for any field in that data template contains any of the following tokens, Sitecore expands those tokens as explained in this list to populate the field value in the new item:
When a user creates an item using a branch template, Sitecore performs this standard values token substitution on the field values of that new item. If fields in the descendants of a branch template definition item contain values that override the standard values for those fields, Sitecore performs token substitution on those overriding values. Wherever the $name token appears in the name(s) of the item(s) created from a branch template, Sitecore also replaces the $name token with the name entered by the user before invoking the branch template.
When Sitecore performs such token expansion, the resulting fields no longer contain their standard value, but a concrete value after applying such expansion. Items created from branch templates that contain values in fields also override standard values for those fields, whether or not those values contain any of these tokens.
You can implement a solution based on the following untested prototype that adds a custom token for expansion:
namespace
Sitecore.Sharedsource.Data
{
using
System;
System.Collections.Generic;
SC = Sitecore;
public
class
MasterVariablesReplacer : SC.Data.MasterVariablesReplacer
override
string
Replace(
text, SC.Data.Items.Item targetItem)
SC.Diagnostics.Assert.ArgumentNotNull(text,
"text"
);
SC.Diagnostics.Assert.ArgumentNotNull(targetItem,
"targetItem"
result =
this
.ReplaceValues(
text,
() => targetItem.Name,
() => targetItem.ID.ToString(),
() => SC.Data.Items.ItemUtil.GetParentName(targetItem),
() => targetItem.ParentID.ToString());
return
result;
}
private
ReplaceValues(
Func<
> defaultName,
> defaultId,
> defaultParentName,
> defaultParentId)
if
((text.Length != 0) && (text.IndexOf(
'$'
) >= 0))
SC.Text.ReplacerContext context =
.GetContext();
(context !=
null
)
foreach
(KeyValuePair<
,
> pair
in
context.Values)
text = text.Replace(pair.Key, pair.Value);
text =
.ReplaceWithDefault(text,
"$name"
, defaultName, context);
"$id"
, defaultId, context);
"$parentid"
, defaultParentId, context);
"$parentname"
, defaultParentName, context);
"$date"
, () => SC.DateUtil.IsoNowDate, context);
"$time"
, () => SC.DateUtil.IsoNowTime, context);
"$now"
, () => SC.DateUtil.IsoNow, context);
"$user"
, () => SC.Context.User.LocalName, context);
text;
ReplaceWithDefault(
variable,
> defaultValue,
SC.Text.ReplacerContext context)
((context !=
) && context.Values.ContainsKey(variable))
(text.IndexOf(variable, StringComparison.InvariantCulture) < 0)
text.Replace(variable, defaultValue());
This class duplicates much of the code in the default Sitecore.Data.MasterVariableReplacer class (mainly because existing methods are private or non-virtual), but adds the $user token expansion. Use a tool such as .NET reflector to disassemble the source code for your version and then make the corresponding change to that. With this customization in place, Sitecore replaces the token $name with the name of the context user (the user that created the item) wherever that token appears in standard values for the data template or field values for the branch template used to create the item.
You can use a Web.config include file such as the following (Sitecore.Sharedsource.MasterVariableReplacer.config in my case) to enable this customization:
<
configuration
xmlns:patch
=
"https://www.sitecore.com/xmlconfig/"
>
sitecore
settings
setting
name
"MasterVariablesReplacer"
patch:attribute
"value"
>Sitecore.Sharedsource.Data.MasterVariablesReplacer,Sitecore.Sharedsource</
</
Unfortunately, replacing tokens in the names of items in branch template definitions appears to require more work (this logic may be obfuscated in Sitecore.Nexus.dll); this solution applies only to field values.
sitecorejunkie.com/.../
www.sitecore.net/.../All-About-Standard-Values-in-the-Sitecore-ASPNET-CMS.aspx
Logic to specify replacer class may change in Sitecore 7? www.sitecore.net/.../Sitecore-7-Pipeline-Updates.aspx
This seems far too complicated. Why do you need to "disassemble the source code"? Your inheriting from the base class. Just call the base method: base.Replace(text, targetItem);
stackoverflow.com/.../how-can-i-add-a-new-custom-standard-value-token-for-sitecore-branch-templates
@Liam: I think you mean something like: public override string Replace(string text, SC.Data.Items.Item targetItem) { return this.ReplaceWithDefault(base.Replace(text, targetItem), "$user", () => SC.Context.User.LocalName, context); } One reason could be that methods other than Replace() can call the ReplaceValues() method, which would skip this replacement.
ReplaceWithDefault is just a glorified Contains() method. I don't really get what your trying to say here? What other methods, this does one job? It sounds like you may be attempting to prematurely optimise your code. Also why are you passing Func into all the methods. This is just inefficient. Your adding a whole layer of un-neccassy processing to access a string. If the functions did something it'd make sense, but they don't they just return a string?! So why not just pass in a string. A lot of this code doesn't really make any sense TBH. Also this is very fragile. If sitecore changed the implementation (for whatever reason) of what $parentname. You'd have to duplicate this work in your code. But you wouldn't know it'd changed....
@Liam: I don't intend it as an optimization; I would prefer to maintain the more simple code, which I think would work in all known cases. I would like to override ReplaceValues(), but would not be able to call base.ReplaceValues() because it is private. If I only override Replace() and something calls ReplaceField(), it will not perform my replacement. I could add my logic in a new method and override both the Replace() and ReplaceField() methods to call their base methods that call ReplaceValues() and then call my method, but what if Sitecore adds another method that calls ReplaceValues()? Through my years of working with Sitecore, which uses a lot of dynamic type loading, I have learned to be cautious of things like this (and also, remember to check for code in constructors!).