XPath can unambiguously use $site/$parent (#14127)
* XPath can unambiguously use $site/$parent * add deprecation notices and obsolete methods * Update deprecation description text/instruction Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> * Small spelling fix on deprecation description * keep depr. getByQuery and handle legacy usage --------- Co-authored-by: Kalle Macklin <karlmacklin@users.noreply.github.co> Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -8,13 +8,23 @@ namespace Umbraco.Cms.Core.Xml;
|
||||
/// </summary>
|
||||
public class UmbracoXPathPathSyntaxParser
|
||||
{
|
||||
[Obsolete("This will be removed in Umbraco 13. Use ParseXPathQuery which accepts a parentId instead")]
|
||||
public static string ParseXPathQuery(
|
||||
string xpathExpression,
|
||||
int? nodeContextId,
|
||||
Func<int, IEnumerable<string>?> getPath,
|
||||
Func<int, bool> publishedContentExists) => ParseXPathQuery(xpathExpression, nodeContextId, null, getPath, publishedContentExists);
|
||||
|
||||
/// <summary>
|
||||
/// Parses custom umbraco xpath expression
|
||||
/// </summary>
|
||||
/// <param name="xpathExpression">The Xpath expression</param>
|
||||
/// <param name="nodeContextId">
|
||||
/// The current node id context of executing the query - null if there is no current node, in which case
|
||||
/// some of the parameters like $current, $parent, $site will be disabled
|
||||
/// The current node id context of executing the query - null if there is no current node.
|
||||
/// </param>
|
||||
/// <param name="parentId">
|
||||
/// The parent node id of the current node id context of executing the query. With this we can determine the
|
||||
/// $parent and $site parameters even if the current node is not yet published.
|
||||
/// </param>
|
||||
/// <param name="getPath">The callback to create the nodeId path, given a node Id</param>
|
||||
/// <param name="publishedContentExists">The callback to return whether a published node exists based on Id</param>
|
||||
@@ -22,6 +32,7 @@ public class UmbracoXPathPathSyntaxParser
|
||||
public static string ParseXPathQuery(
|
||||
string xpathExpression,
|
||||
int? nodeContextId,
|
||||
int? parentId,
|
||||
Func<int, IEnumerable<string>?> getPath,
|
||||
Func<int, bool> publishedContentExists)
|
||||
{
|
||||
@@ -84,19 +95,27 @@ public class UmbracoXPathPathSyntaxParser
|
||||
// parseable items:
|
||||
var vars = new Dictionary<string, Func<string, string>>();
|
||||
|
||||
// These parameters must have a node id context
|
||||
if (nodeContextId.HasValue)
|
||||
if (parentId.HasValue)
|
||||
{
|
||||
vars.Add("$parent", q =>
|
||||
{
|
||||
var path = getPath(parentId.Value)?.ToArray();
|
||||
var closestPublishedAncestorId = getClosestPublishedAncestor(path);
|
||||
return q.Replace("$parent", string.Format(rootXpath, closestPublishedAncestorId));
|
||||
});
|
||||
|
||||
vars.Add("$site", q =>
|
||||
{
|
||||
var closestPublishedAncestorId = getClosestPublishedAncestor(getPath(parentId.Value));
|
||||
return q.Replace(
|
||||
"$site",
|
||||
string.Format(rootXpath, closestPublishedAncestorId) + "/ancestor-or-self::*[@level = 1]");
|
||||
});
|
||||
}
|
||||
else if (nodeContextId.HasValue)
|
||||
{
|
||||
vars.Add("$current", q =>
|
||||
{
|
||||
var closestPublishedAncestorId = getClosestPublishedAncestor(getPath(nodeContextId.Value));
|
||||
return q.Replace("$current", string.Format(rootXpath, closestPublishedAncestorId));
|
||||
});
|
||||
|
||||
vars.Add("$parent", q =>
|
||||
{
|
||||
// remove the first item in the array if its the current node
|
||||
// this happens when current is published, but we are looking for its parent specifically
|
||||
var path = getPath(nodeContextId.Value)?.ToArray();
|
||||
if (path?[0] == nodeContextId.ToString())
|
||||
{
|
||||
@@ -116,6 +135,16 @@ public class UmbracoXPathPathSyntaxParser
|
||||
});
|
||||
}
|
||||
|
||||
// These parameters must have a node id context
|
||||
if (nodeContextId.HasValue)
|
||||
{
|
||||
vars.Add("$current", q =>
|
||||
{
|
||||
var closestPublishedAncestorId = getClosestPublishedAncestor(getPath(nodeContextId.Value));
|
||||
return q.Replace("$current", string.Format(rootXpath, closestPublishedAncestorId));
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: This used to just replace $root with string.Empty BUT, that would never work
|
||||
// the root is always "/root . Need to confirm with Per why this was string.Empty before!
|
||||
vars.Add("$root", q => q.Replace("$root", "/root"));
|
||||
|
||||
Reference in New Issue
Block a user