由于 Sitecore 7 需要 VS 2012,而且我们公司不会很快升级,我不得不为此寻找 Sitecore 6 解决方案。
根据这篇文章和这篇文章,我想出了这个解决方案。
public class SCWTreeList : TreeList
{
protected override void OnLoad(EventArgs e)
{
if (!String.IsNullOrEmpty(Source))
this.Source = SourceQuery.Resolve(SContext.ContentDatabase.Items[ItemID], Source);
base.OnLoad(e);
}
}
这将创建一个自定义控件TreeList
并将其 Source 字段传递给一个类来处理它。该类需要做的就是将源字段中的所有内容解析为站点核心查询路径,然后可以将其重新分配给源字段。然后,这将继续由 Sitecore 自己的查询引擎处理。
因此,对于我们的多站点解决方案,它启用了如下路径:
{A588F1CE-3BB7-46FA-AFF1-3918E8925E09}/$sitename
要解决这样的路径:
/sitecore/medialibrary/Product Images/Site2
然后,我们的控件将仅显示正确站点的项目。
这是处理解析 GUID 和令牌的方法:
public static string Resolve(Item item, string query)
{
// Resolve tokens
if (query.Contains("$"))
{
MatchCollection matches = Regex.Matches(query, "\\$[a-z]+");
foreach (Match match in matches)
query = query.Replace(match.Value, ResolveToken(item, match.Value));
}
// Resolve GUIDs.
MatchCollection guidMatches = Regex.Matches(query, "^{[a-zA-Z0-9-]+}");
foreach (Match match in guidMatches)
{
Guid guid = Guid.Parse(match.Value);
Item queryItem = SContext.ContentDatabase.GetItem(new ID(guid));
if (item != null)
query = query.Replace(match.Value, queryItem.Paths.FullPath);
}
return query;
}
下面的令牌处理,如您所见,它要求使用$siteref
令牌的任何项目都在Site Folder
我们创建的项目内。这允许我们使用包含我们所有多站点内容文件夹必须遵循的名称的字段 - Site Reference
。只要遵守该命名约定,它就允许我们引用媒体库中的文件夹或 Sitecore 中的任何其他共享内容。
static string ResolveToken(Item root, string token)
{
switch (token)
{
case "$siteref":
string sRef = string.Empty;
Item siteFolder = root.Axes.GetAncestors().First(x => x.TemplateID.Guid == TemplateKeys.CMS.SiteFolder);
if (siteFolder != null)
sRef = siteFolder.Fields["Site Reference"].Value;
return sRef;
}
throw new Exception("Token '" + token + "' is not recognised. Please disable wishful thinking and try again.");
}
到目前为止,这适用于 TreeLists、DropTrees 和 DropLists。让它与 DropLinks 一起工作会很好,但这种方法似乎不起作用。
这感觉就像是在摸索表面,我相信你可以用这种方法做更多的事情。