Loop through a category entity, then its contents in separate loops

Jun 3, 2015 at 2:57 PM
I have a template set up kind of like this....
@using ToSic.Eav.DataSources
@{ 
    int rowCounter = 0;
    var mid = Dnn.Module.ModuleID.ToString();
    var allItems = CreateSource<EntityTypeFilter>();
    allItems.TypeName = "e_ReportCategories";    
    }

<ul>
@foreach (var dict in allItems.List) {
        var Content = AsDynamic(dict.Value);
        var Pubs = ((ToSic.Eav.IEntity)AsEntity(Content))
            .Relationships.AllParents
            .Where(c => c.Type.Name == "Publications");
    <li>
    <a href="#" class="filter" data-filter="@Content.DataFilter">@Content.CategoryName</a>
    </li>
  }
</ul>

<div>
@if(Pubs.Any()){
<ul>
foreach(var p in Pubs.OrderByDescending(e => AsDynamic(e).DateCreated)) {
var pub = AsDynamic(p);
<div class="@Content.DataFilter">
<li>@pub.Name</li>
}
</ul>
}
</div>
This doesn't work because the Pubs variable can't be accessed outside of that first foreach loop. (At least, that's my guess.) Is there way to declare Pubs somewhere else where both foreach loops can use it? I will need the Content variable for both as well.

The end result would look like this: http://www.rcu.msstate.edu/Research/Publications.aspx
I want to loop through categories, then through all the publications for the selected category.
Jun 22, 2015 at 8:30 PM
Any ideas on this?
Thanks
Coordinator
Jun 23, 2015 at 6:05 AM
From your example it's not clear what you want.

Within the for-each pubs is always the current pubs of the current Content-item.

Now outside of the loop, what do you want it to be? There is no current Contetn-item. Do you want it to the be the Publications of the first Content-item? or of all of them? what are you trying to do?

Thanks,
Daniel
Jun 23, 2015 at 1:29 PM
The end result will look like this:
http://www.rcu.msstate.edu/Research/Publications.aspx

The first loop loops through an entity field of categories.

The second loop loops through the publications within the chosen category.

This is the FULL template code:
@using ToSic.Eav.DataSources
@{ 
    int rowCounter = 0;
    var mid = Dnn.Module.ModuleID.ToString();
    var allItems = CreateSource<EntityTypeFilter>();
    allItems.TypeName = "e_ReportCategories";    
    }

<div class="portfolio-filters">
<div class="row">
<div class="col-md-12">
<ul class="filters">
    <li>
    <a href="#" class="filter" data-filter="all">All</a>
    </li>
@foreach (var dict in allItems.List) {
        var Content = AsDynamic(dict.Value);
        var Pubs = ((ToSic.Eav.IEntity)AsEntity(Content))
            .Relationships.AllParents
            .Where(c => c.Type.Name == "Publications");
    <li>
    <a href="#" class="filter" data-filter="@Content.DataFilter">@Html.Raw(Content.Name)</a>
    </li>
  }
</ul>
</div>
</div>
</div>


@if(Pubs.Any()){

<div class="row portfolio-items">
    <div id="grid">

@foreach(var p in Pubs.OrderBy(c => AsDynamic(c).DateCreated)) {
   var pub = AsDynamic(p);
    <div style="display: inline-block; opacity: 1; height: 520px;" class="@Content.DataFilter mix item col-md-3 mix_all">


<h4 style="line-height: 1.2 !important;">@pub.Name</h4>

<a href="@pub.issuu" target="_blank"><img src="@pub.Thumbnail" class="item-image" alt="@pub.Name cover" />  </a>    

<div class="item-meta-container">
        
<p style="font-size: .9em; font-style: italic;">
@pub.Author
</p>

        
<a href="@pub.issuu" class="rox_short_button small sunset" target="_blank"><em class="micon-book-4"></em> Read online</a>
<br />
<a href="@pub.File">Download PDF</a>


</div>
</div>
}

</div>
</div>
}
Does that make sense?
Coordinator
Jun 23, 2015 at 3:28 PM
Ok - I think I figured out what your problem is

You're currently defining the variable Pubs within the @foreach. But you're not using it within the for-each :).

Take that out. Something like
@using ToSic.Eav.DataSources
@{ 
    int rowCounter = 0;
    var mid = Dnn.Module.ModuleID.ToString();
    var allItems = CreateSource<EntityTypeFilter>();
    allItems.TypeName = "e_ReportCategories";    

        var Pubs = ((ToSic.Eav.IEntity)AsEntity(Content))
            .Relationships.AllParents
            .Where(c => c.Type.Name == "Publications");
    }

<div class="portfolio-filters">
<div class="row">
<div class="col-md-12">
<ul class="filters">
    <li>
    <a href="#" class="filter" data-filter="all">All</a>
    </li>
@foreach (var dict in allItems.List) {
        var Content = AsDynamic(dict.Value);
    <li>
    <a href="#" class="filter" data-filter="@Content.DataFilter">@Html.Raw(Content.Name)</a>
    </li>
  }
</ul>
</div>
</div>
</div>

@if(Pubs.Any()){

<div class="row portfolio-items">
    <div id="grid">

@foreach(var p in Pubs.OrderBy(c => AsDynamic(c).DateCreated)) {
   var pub = AsDynamic(p);
    <div style="display: inline-block; opacity: 1; height: 520px;" class="@Content.DataFilter mix item col-md-3 mix_all">


<h4 style="line-height: 1.2 !important;">@pub.Name</h4>

<a href="@pub.issuu" target="_blank"><img src="@pub.Thumbnail" class="item-image" alt="@pub.Name cover" />  </a>    

<div class="item-meta-container">
        
<p style="font-size: .9em; font-style: italic;">
@pub.Author
</p>

        
<a href="@pub.issuu" class="rox_short_button small sunset" target="_blank"><em class="micon-book-4"></em> Read online</a>
<br />
<a href="@pub.File">Download PDF</a>


</div>
</div>
}

</div>
</div>
}
Coordinator
Jun 23, 2015 at 3:30 PM
BTW you can also simplyf this:
@foreach (var dict in allItems.List) {
        var Content = AsDynamic(dict.Value);
    <li>
    <a href="#" class="filter" data-filter="@Content.DataFilter">@Html.Raw(Content.Name)</a>
    </li>
into this

@foreach (var Content in AsDynamic(allItems.List)) {
    <li>
    <a href="#" class="filter" data-filter="@Content.DataFilter">@Html.Raw(Content.Name)</a>
    </li>
Jun 24, 2015 at 8:49 PM
This was helpful, except I had to rename the Content variable because it kept saying that name was already in use. It's now "categories".

Problem is now, I need "categories" to be a global variable too, as the div containing the publications has to have a class that refers to its category.
I tried moving the categories variable definition to the top like you did with Pubs, but it's still not working. Probably just some syntax I don't have quite right.
@using ToSic.Eav.DataSources
@{ 
    int rowCounter = 0;
    var mid = Dnn.Module.ModuleID.ToString();
    var allItems = CreateSource<EntityTypeFilter>();
    allItems.TypeName = "e_ReportCategories";    

        var Pubs = ((ToSic.Eav.IEntity)AsEntity(Content))
            .Relationships.AllParents
            .Where(c => c.Type.Name == "Publications");
            
        var dict = allItems.List;    
        var categories = AsDynamic(dict.Value);
    }

<div class="portfolio-filters">
<div class="row">
<div class="col-md-12">
<ul class="filters">
    <li>
    <a href="#" class="filter" data-filter="all">All</a>
    </li>
    
@foreach (var c in categories) {
        var cat = AsDynamic(c);
    <li>
    <a href="#" class="filter" data-filter="@cat.DataFilter">@Html.Raw(cat.Name)</a>
    </li>
  }
</ul>
</div>
</div>
</div>

@if(Pubs.Any()){
 
<div class="row portfolio-items">
    <div id="grid">

@foreach(var p in Pubs.OrderBy(c => AsDynamic(c).DateCreated)) {
   var pub = AsDynamic(p);

    <div style="display: inline-block; opacity: 1; height: 520px;" class="@cat.DataFilter mix item col-md-3 mix_all">
    
    @Content.Toolbar

    <h4 style="line-height: 1.2 !important;">@pub.Name</h4>

    <a href="@pub.issuu" target="_blank"><img src="@pub.Thumbnail" class="item-image" alt="@pub.Name cover" /></a>  

<div class="item-meta-container">
        
    <p style="font-size: .9em; font-style: italic;">
        @if(pub.Author != "") {
        @pub.Author
        }
        else {
        <span>Research & Curriculum Unit</span>
        }
    </p>

    <a href="@pub.issuu" class="rox_short_button small sunset" target="_blank"><em class="micon-book-4"></em> Read online</a>
    <br />
    <a href="@pub.File">Download PDF</a>

</div><!-- end item-meta-container -->
</div><!-- end datafilter div -->
} <!-- end foreach -->


</div><!-- end grid -->
</div><!-- end PF items -->
} <!--end if Pubs Any-->
Coordinator
Jun 25, 2015 at 9:09 AM
dict is already the list. It doesn't have a value. try
var categories = AsDynamic(dict);
Jun 25, 2015 at 1:32 PM
Thanks much.
Now how can I use the DataFilter field (from the categories variable) here inside the Pubs loop? I need it to properly display publications from the correct categories.
@foreach(var p in Pubs) {
   var pub = AsDynamic(p);   

    <div style="display: inline-block; opacity: 1; height: 520px;" class="@categories.DataFilter mix item col-md-3 mix_all">
    
The above does not work.


On my original build of this, (this page: http://www.rcu.msstate.edu/Research/Publications.aspx) I had success with using separate Presentation for the DataFilter. I just really don't like how you had to type it in instead of choosing from a list, and when you typed it in, it would add another entry to that content type. So that DataFilter content type contains 20-something entries for 3 different categories. Seems sloppy. Maybe I set that up wrong?
Coordinator
Jun 25, 2015 at 2:00 PM
@amandathomas - it would probably be much more efficient if we could support you directly and get things done with remote-viewing etc. Why don't you check out our support conditions? http://2sxc.org/en/Contact