Getting Ultimate Picker to return Content Nodes instead of ID's
I have set up an ultimate picker property for one document type, so I can create relationships between different pages. Unfortunately this control only returns ID's, and I actually need the content.
The content does not appear in the XML at all, since it is in a completely different area of the site. This seems like a fairly trivial operation, any help would be appreciated. Thanks.
I wrote a small XsltExtension method to do this for me, makes for cleaner implementations as less calls are made to umbraco.library.GetXmlNodeById.
[code]
public static XPathNodeIterator GetNodesFromUltimatePicker(string NodeIds)
{
XPathNavigator xp = content.Instance.XmlContent.CreateNavigator();
// Setup the document to contain node data
XmlDocument doc = new XmlDocument();
// Emulate the umbraco ContentXml.
doc.LoadXml("");
if (!String.IsNullOrEmpty(NodeIds))
{
// Split all ids from the Ultimate Picker.
string[] nodeIds = NodeIds.Split(',');
// Let's get the node data from all our nodes.
for (int i = -1; ++i < nodeIds.Length; )
{
xp.MoveToId(nodeIds[i]);
if (xp.Select(".").Current is IHasXmlNode)
{
//Get the XmlNode from the XPathNodeIterator
XmlNode node = ((IHasXmlNode)xp.Select(".").Current).GetNode();
doc.DocumentElement.AppendChild(doc.ImportNode(node, false));
}
}
}
//Return our faked content tree.
return doc.CreateNavigator().Select(".");
}
[/code]
I rewrote the xslt helper method to support media items, and then I noticed I'd made some mistakes, so here's another version of the method. It filters all children from the nodes, but gets the data for each node.
[code]
public static XPathNodeIterator GetNodesFromUltimatePicker(string NodeIds)
{
// Setup our document to contain data.
XmlDocument doc = new XmlDocument();
doc.LoadXml("");
if (!String.IsNullOrEmpty(NodeIds))
{
// First attempt to find nodes in content tree.
XPathNavigator xp = content.Instance.XmlContent.CreateNavigator();
// Split all ids from the Ultimate Picker.
string[] nodeIds = NodeIds.Split(',');
// Let's get the node data from all our nodes.
XmlNode node;
for (int i = -1; ++i < nodeIds.Length; )
{
try
{
if (!String.IsNullOrEmpty(nodeIds[i]))
{
xp.MoveToId(nodeIds[i]);
if (xp.Select(".").Current is IHasXmlNode)
{
// Get the XmlNode from the XPathNodeIterator
node = ((IHasXmlNode)xp.Select(".").Current).GetNode();
// Import the node, and any children if specified.
// We only want the node and its data, not childnodes.
for (int j = -1; ++j < node.ChildNodes.Count; )
{
if (node.ChildNodes[j].Name == "node")
{
node.RemoveChild(node.ChildNodes[j]);
}
}
doc.DocumentElement.AppendChild(doc.ImportNode(node, true));
}
}
}
catch
{
// Node is most likely a Media node, and could not be found in the content cache.
// Let's find it in the media section instead.
int nodeId = 0;
Int32.TryParse(nodeIds[i], out nodeId);
if (nodeId > 0)
{
try
{
// Get the media item.
Media m = new Media(nodeId);
// Check to see that the types match.
if (m.nodeObjectType == Media._objectType)
{
node = m.ToXml(doc, true);
// Add the media node to our faked content tree.
for (int j = -1; ++j < node.ChildNodes.Count; )
{
if (node.ChildNodes[j].Name == "node")
{
node.RemoveChild(node.ChildNodes[j]);
}
}
doc.DocumentElement.AppendChild(node);
}
}
catch {}
}
}
}
}
// Return our faked content tree
// If we've found no nodes, it'll be emtpy.
return doc.CreateNavigator().Select(".");
}
[/code]
Might not be a perfect fit for everyone, but serves my purposes right now. I'm using it as a stand-in for Lefteris' Multiple Node Picker. To build a selective menu.
Getting Ultimate Picker to return Content Nodes instead of ID's
I have set up an ultimate picker property for one document type, so I can create relationships between different pages. Unfortunately this control only returns ID's, and I actually need the content.
The content does not appear in the XML at all, since it is in a completely different area of the site. This seems like a fairly trivial operation, any help would be appreciated. Thanks.
here is the general process of how i have used the ultimate picker... they key is splitting the list of IDs then using GetXmlNodeById
[code]
[/code]
hope this helps...
I wrote a small XsltExtension method to do this for me, makes for cleaner implementations as less calls are made to umbraco.library.GetXmlNodeById.
[code]
public static XPathNodeIterator GetNodesFromUltimatePicker(string NodeIds)
{
XPathNavigator xp = content.Instance.XmlContent.CreateNavigator();
// Setup the document to contain node data
XmlDocument doc = new XmlDocument();
// Emulate the umbraco ContentXml.
doc.LoadXml("");
if (!String.IsNullOrEmpty(NodeIds))
{
// Split all ids from the Ultimate Picker.
string[] nodeIds = NodeIds.Split(',');
// Let's get the node data from all our nodes.
for (int i = -1; ++i < nodeIds.Length; )
{
xp.MoveToId(nodeIds[i]);
if (xp.Select(".").Current is IHasXmlNode)
{
//Get the XmlNode from the XPathNodeIterator
XmlNode node = ((IHasXmlNode)xp.Select(".").Current).GetNode();
doc.DocumentElement.AppendChild(doc.ImportNode(node, false));
}
}
}
//Return our faked content tree.
return doc.CreateNavigator().Select(".");
}
[/code]
And the XSLT looks like this:
[code]
]>
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
xmlns:my.library="urn:my.library"
exclude-result-prefixes="msxml umbraco.library my.library">
[/code]
Note the double slashes in $SiteMenu//node in the for-each, it's because we return the
I rewrote the xslt helper method to support media items, and then I noticed I'd made some mistakes, so here's another version of the method. It filters all children from the nodes, but gets the data for each node.
[code]
public static XPathNodeIterator GetNodesFromUltimatePicker(string NodeIds)
{
// Setup our document to contain data.
XmlDocument doc = new XmlDocument();
doc.LoadXml("");
if (!String.IsNullOrEmpty(NodeIds))
{
// First attempt to find nodes in content tree.
XPathNavigator xp = content.Instance.XmlContent.CreateNavigator();
// Split all ids from the Ultimate Picker.
string[] nodeIds = NodeIds.Split(',');
// Let's get the node data from all our nodes.
XmlNode node;
for (int i = -1; ++i < nodeIds.Length; )
{
try
{
if (!String.IsNullOrEmpty(nodeIds[i]))
{
xp.MoveToId(nodeIds[i]);
if (xp.Select(".").Current is IHasXmlNode)
{
// Get the XmlNode from the XPathNodeIterator
node = ((IHasXmlNode)xp.Select(".").Current).GetNode();
// Import the node, and any children if specified.
// We only want the node and its data, not childnodes.
for (int j = -1; ++j < node.ChildNodes.Count; )
{
if (node.ChildNodes[j].Name == "node")
{
node.RemoveChild(node.ChildNodes[j]);
}
}
doc.DocumentElement.AppendChild(doc.ImportNode(node, true));
}
}
}
catch
{
// Node is most likely a Media node, and could not be found in the content cache.
// Let's find it in the media section instead.
int nodeId = 0;
Int32.TryParse(nodeIds[i], out nodeId);
if (nodeId > 0)
{
try
{
// Get the media item.
Media m = new Media(nodeId);
// Check to see that the types match.
if (m.nodeObjectType == Media._objectType)
{
node = m.ToXml(doc, true);
// Add the media node to our faked content tree.
for (int j = -1; ++j < node.ChildNodes.Count; )
{
if (node.ChildNodes[j].Name == "node")
{
node.RemoveChild(node.ChildNodes[j]);
}
}
doc.DocumentElement.AppendChild(node);
}
}
catch {}
}
}
}
}
// Return our faked content tree
// If we've found no nodes, it'll be emtpy.
return doc.CreateNavigator().Select(".");
}
[/code]
Might not be a perfect fit for everyone, but serves my purposes right now. I'm using it as a stand-in for Lefteris' Multiple Node Picker. To build a selective menu.
is working on a reply...