Been some time since I was working with the filtering bit but I think you have two options.
One is to index the content in the contentareas http://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-Find/8/Integration/EPiServer-75/Indexing-content-in-a-content-area/
Or you could add the logic to the page during indexing and setting a bool property that you then filter on.
Hope that gives you some new angles to solving the issue.
/Petter
Okay, thanks, I´ll try that. But I think the FilterBuilder code needs to change some how since the field in the created filter was called GetContent.Name.ProductAreas.Items.Select$$string and there will still not be any property with that name even if I index the content in the ContentArea, right?
//Petra
Yes right you are.
So going down option one and adding the content in the contentarea to the index should give a a json response that looks something like
{
...
"MainContentArea": {
"ReferencedPermanentLinkIds": [
"bla bla bla"
],
"Contents": [
{
....
"MasterLanguage.Name$$string": "sv",
"ContentTypeName$$string": "YourSuperDuperBlock",
"Status": 4,
...
}
...
}
and in that case the filter would be
filterBuilder = filterBuilder.And(x => x.MainContentArea.Contents.Select(c => c.ContentTypeName).Match(productArea));
/Petter
Okay, thanks, the indexing of the items in the content area worked fine, but the Linq query didn´t work. Contents is marked as deprecated and the Select part didn´t work, I got an error saying "The type arguments for method 'Enumerable.Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly." and I couldn´t get it to compile without changing it to:
filterBuilder = filterBuilder.And(x => x.ProductAreas.Items.Select(c => c.GetContent().ContentTypeName()).Match(productArea));
This led me to getting a field name on the filter called GetContent.ContentTypeName.ProductAreas.Items.Select$$string instead of the previous which was GetContent.Name.ProductAreas.Items.Select$$string.
Starting to think that what I want to do isn´t possible...
//Petra
Right well that's a shame.
Guess we have to do it on indexing then instead.
Just add a prop to your pagetype that runs through the items and checks if you got a productArea or not. Then you should be able to use that prop in your querying.
/Petter
I haven´t tried that yet, but I still won´t get the names of the page types in the content area, just a true or false if there are items in the content area or not, right? I need to filter on the name of the page type in the content area.
//Petra
Well was thinking something like this.
public bool HasSystemTagPageWithRightName { get { var result = false; if (ProductAreas != null && ProductAreas.Items.Any()) { foreach (var item in ProductAreas.Items) { var blockContent = item.GetContent() as SystemTagPage; if (blockContent != null && !string.IsNullOrEmpty(blockContent.Name)) { result = true; } } } return result; } }
Then in your filter you would just modify the builder to look at the bool
I suspect we are thinking of different things, with this solution it´s required that the product area to use in the filter is always the same and it´s not. I don´t know what product area to filter on until the end user chooses that in a select list, so one time it might be x and the next time y. So I can´t really have a property on the page type that does the matching.
//Petra
Right so I missunderstood what you where after.
But if you modify the code abow to just add the names of the SystemTagPage as a list of strings and then filter on that?
public List<string> SystemTagPages { get { var result = new List<string>(); if (ProductAreas != null && ProductAreas.Items.Any()) { foreach (var item in ProductAreas.Items) { var blockContent = item.GetContent() as SystemTagPage; if (blockContent != null && !string.IsNullOrEmpty(blockContent.Name)) { result = result.Add(blockContent.Name) } } } return result; } }
Hmm, that would probably be a solution. Why didn´t I think of that :) Performance wise I won´t actually get rid of the iteration that I now do on the result after the Find question is finished since it´ll be in the property of the page type instead, but at least I´ll get rid of the ugly post-query Linq-filter which was my goal so, win!
I´ll try it out! Thanks Petter! (will mark as solution once verified :))
Hi,
I have a Find query where I search for a specific page type and I want to filter that query on items in the page's ContentArea. I´ll try to explain:
There is a page type called PartnerPage and on that page there is a ContentArea property called ProductAreas where editors can drag and drop pages of page type SystemTagPage. I need to filter on the SystemTagPage's Name property against a product area (string) which is selected from a list in the view.
This is the Find query:
And the filter (the filterBuilder variable in the query) is created like this:
I can´t get the filter to work, when debugging I see that the Field of the filter is called "GetContent.Name.ProductAreas.Items.Select$$string" and I guess that´s why I don´t get any hits, there is no property with that name. But I´m not sure how the filter should be written to accomplish this, any ideas? Might not even be possible since a ContentArea and its items are a bit different from "normal" properties.
My solution right now is to skip the filter for product area and do a Linq query on the finished result from Find instead but that doesn´t feel like a good solution, like this:
Any ideas and information is welcome! Thanks!
BR, Petra