Get children of node where 'tagged' using multi node tree picker
Hi,
I have the following site strucutre:
Home
Articles
Article 1
Article 2
Article 3
Article 4
Article 5
Category folder 1
Category folder 2
Category folder 3
Category folder 4
Category folder 5
Each of the articles can be tagged to belong to one or more of the category folders, using a multi node tree picker.
Now, on the website I need to create a category landing page which shows all articles 'tagged' as belonging to that category.
Could anyone point me in the right direction here, on how to achieve this with razor, as nothing I've tried has worked (there's a YSOD around every corner ;))?
My favorite approach for this type of thing (if your site isn't too large!) is the XPath operator. (Yes, you can do this in RAZOR, not just XSLT!)
For example:
var articleRoot = Library.NodeById(1234); // or however else you want to find this...
var categoryFolderNodeId = 333; // Current category. You could get this from current Node.Id or the querystring???
string query = String.Format(@".//article[categoryPicker/MultiNodePicker/nodeId = ""{0}""]", categoryFolderNodeId);
var articles = articleRoot.XPath(query);
Note the above is for version 4, with my MNTP storing values as XML. In Umbraco version 6 the XPath helper is renamed to Umbraco.ContentAtXPath but works pretty much the same. And if your MNTP stores values as CSV you'd have to change the Xpath query but the idea would be the same.
This looks like it'll do just the job but I'm having a little trouble with the implementation, presumably because this is in a partial view. I've tried this:
var articleRoot = Umbraco.TypedContent(1100);
var categoryFolderNodeId = 1058;
string query = String.Format(@".//article[categoryPicker/MultiNodePicker/nodeId = ""{0}""]", categoryFolderNodeId);
var articles = articleRoot.ContentAtXPath(query);
...and this:
var articleRoot = Umbraco.Content(1100);
var categoryFolderNodeId = 1058;
string query = String.Format(@".//article[categoryPicker/MultiNodePicker/nodeId = ""{0}""]", categoryFolderNodeId);
var articles = articleRoot.ContentAtXPath(query);
But both error (the first says "'Umbraco.Core.Models.IPublishedContent' does not contain a definition for 'ContentAtXPath' and no extension method 'ContentAtXPath' accepting a first argument of type 'Umbraco.Core.Models.IPublishedContent' could be found (are you missing a using directive or an assembly reference?)" (I'm referencing Umbraco.Core, Umbraco.Web and Umbraco.Core.Models), the second just says "Object reference not set to an instance of an object.").
Presumably it's because articleRoot isn't giving me the correct type of content to work with or something in the API has perhaps changed? I'm using Umbraco 6.1.6 by the way.
Do you have any idea how to get this working in the context of a partial?
Sounds like you are very close! I forgot to note also that ContentAtXPath in v6 was not just renamed from the v4 XPath, but is called a bit differently too now.
While XPath I believe was an extension method on a Node in v4, now in v6 ContextAtXPath is a member method on the UmbracoHelper class which you can call from the current umbraco context a.k.a. @Umbraco.
So for example you would change to var articles = Umbraco.ContentAtXPath(myPath); when moving from v4 to v6.
One last thing I just thought of now, I don't know if there is the same way to provide a "search context" to ContextAtXPath to indicate where your search should start although I may just not be seeing it right now. I don't think I've ran into this yet or noticed until now, but I suppose if your tree structure is very large, you might want to add more to your XPath expression to narrow down the search e.g., include more of the parent structure in the query. Best of luck to you!
Thanks. Having hard-coded some XPath in there to test this method works, so that's really handy to know - thank you! However, my MNTP just happens to store its values as CSV rather than XML (as CSV tends to be more easily processed with Razor) so rather than change this (and it looks like it could have been tricky to 'query' the CSV in the XPath) I thought I'd try another approach and go the all-razor route.
So here's what I've come up with, which seems to work, and doesn't involve mixing XPath/XML with Razor:
@{
// Get container id
var articleContainerId = 1100;
// Get category id (id of current page)
var categoryId = Model.Id.ToString();
// Get articles from container folder which are associated with current category
var articles = Umbraco.TypedContent(articleContainerId).Children.Where(x => x.GetPropertyValue<string>("category").Split(',').Contains(categoryId));
// Loop though nodes and output node name
foreach (var child in articles){
<p>@child.Name</p>
}
}
Get children of node where 'tagged' using multi node tree picker
Hi,
I have the following site strucutre:
Home
Each of the articles can be tagged to belong to one or more of the category folders, using a multi node tree picker.
Now, on the website I need to create a category landing page which shows all articles 'tagged' as belonging to that category.
Could anyone point me in the right direction here, on how to achieve this with razor, as nothing I've tried has worked (there's a YSOD around every corner ;))?
Many thanks folks.
My favorite approach for this type of thing (if your site isn't too large!) is the XPath operator. (Yes, you can do this in RAZOR, not just XSLT!)
For example:
Note the above is for version 4, with my MNTP storing values as XML. In Umbraco version 6 the
XPath
helper is renamed toUmbraco.ContentAtXPath
but works pretty much the same. And if your MNTP stores values as CSV you'd have to change the Xpath query but the idea would be the same.Good luck to you!
Thanks Funka. Good old XPath!
This looks like it'll do just the job but I'm having a little trouble with the implementation, presumably because this is in a partial view. I've tried this:
...and this:
But both error (the first says "'Umbraco.Core.Models.IPublishedContent' does not contain a definition for 'ContentAtXPath' and no extension method 'ContentAtXPath' accepting a first argument of type 'Umbraco.Core.Models.IPublishedContent' could be found (are you missing a using directive or an assembly reference?)" (I'm referencing Umbraco.Core, Umbraco.Web and Umbraco.Core.Models), the second just says "Object reference not set to an instance of an object.").
Presumably it's because articleRoot isn't giving me the correct type of content to work with or something in the API has perhaps changed? I'm using Umbraco 6.1.6 by the way.
Do you have any idea how to get this working in the context of a partial?
Thanks!
Sounds like you are very close! I forgot to note also that
ContentAtXPath
in v6 was not just renamed from the v4XPath
, but is called a bit differently too now.While
XPath
I believe was an extension method on a Node in v4, now in v6ContextAtXPath
is a member method on the UmbracoHelper class which you can call from the current umbraco context a.k.a.@Umbraco
.So for example you would change to
var articles = Umbraco.ContentAtXPath(myPath);
when moving from v4 to v6.One last thing I just thought of now, I don't know if there is the same way to provide a "search context" to ContextAtXPath to indicate where your search should start although I may just not be seeing it right now. I don't think I've ran into this yet or noticed until now, but I suppose if your tree structure is very large, you might want to add more to your XPath expression to narrow down the search e.g., include more of the parent structure in the query. Best of luck to you!
Thanks. Having hard-coded some XPath in there to test this method works, so that's really handy to know - thank you! However, my MNTP just happens to store its values as CSV rather than XML (as CSV tends to be more easily processed with Razor) so rather than change this (and it looks like it could have been tricky to 'query' the CSV in the XPath) I thought I'd try another approach and go the all-razor route.
So here's what I've come up with, which seems to work, and doesn't involve mixing XPath/XML with Razor:
is working on a reply...