Presentation loop with content loop?

Apr 27, 2015 at 9:03 PM
I'm writing a Razor template that looks somewhat like this (I removed a lot of HTML that I don't think is important):
@foreach(var e in Presentation) {
var Presentation = e.Presentation;
<a href="#@Presentation.Department">@Presentation.Department</a>

<div id="@Presentation.Department">

@foreach(var e in List) {
var Content = e.Content;
<h3>@Content.Name</h3>
<p>@Content.OtherInfo</p>
}

</div>

}
I am getting this error:
System.Web.HttpCompileException (0x80004005): d:\Web\DNN7\Portals\0\2sxc\Content_RCUstaffRazor.cshtml(2): error CS0136: A local variable named 'Presentation' cannot be declared in this scope because it would give a different meaning to 'Presentation', which is already used in a 'parent or current' scope to denote something else at System.Web.Compilation.AssemblyBuilder.Compile()
I have also tried arranging it other ways, but get a missing } error.

I want my end result to be a Staff Listing page like this: http://www.rcu.msstate.edu/rcu-staff.aspx but I'd like the different departments to dynamically load. (In this page, the departments are static, and each department has a separate 2xc content module with lists of people... I'd like to have all people in the same module with their departments defined in a field, so it can be changed easily when people change departments.)
Apr 27, 2015 at 9:47 PM
Hi Amanda

the reason you are getting this error is that you redefine presentation as this is already used by 2sxc

your error would get resolved by
var myPresentation = e.Presentation;
and then you would also use this throughout your code
<div id="@myPresentation.Department">
checking out the url why don't you just create a department content type and an employee content type

then you can just loop though your department and foreach department loop throught the employees of that department

Armand 2DNN
your friendly non official 2sxc support :)
Apr 28, 2015 at 12:53 PM
Thanks.

Why doesn't Content need a new variable?

I have another razor template with another content type that uses the variables Content and Presentation, and that one works. Just trying to understand. Thanks!
Apr 28, 2015 at 1:05 PM
In all templates you can set Content/Presentation if it's the first time they were used.

If you start with foreach(var x in Presentation) then Presentation was already used, from then on you can't set it yourself to anything else.
Apr 28, 2015 at 1:26 PM
I am still having issues even when renaming the Presentation variable.

Can someone look at my template settings and verify they're correct? I have never been able to understand the difference between Content/Presentation and ListContent/ListPresentation.

http://grab.by/GP5K
Apr 28, 2015 at 1:39 PM
Edited Apr 28, 2015 at 1:40 PM
Hi

I leave it to Daniel to do all the exact explanation :)

but with your setup you should just use 2 content types and set one as content type for the other

presentation is just for presentation , i use it to give like a special class or something to an element

here is my setup for a recent team listing ( team is content item used as an entity in employee )

Image

and you should code it like this http://2sxc.org/learn-razor/Relationships see the course list by category example, that's the same as your employees by department

Armand 2DNN
your friendly non official 2sxc support :)
Apr 28, 2015 at 3:13 PM
In short: if you don't know what Presentation is for, you probably don't need it :)

We use it to set output/design parameters which have nothing to do with the content. For example, it could contain google-map configuration (which has nothing to do with the address being displayed) or heading-types on a simple template.

But you can always put all your fields in the content-item and avoid presentation - the only drawback is that you will always have the same presentation settings for this piece of information, even if at one place you would need google-maps configurations, in another vCard-configurations etc. for the same address.
Apr 28, 2015 at 8:45 PM
OK, I'm trying to set up the loop based on the template for Course List by Category at the bottom of the page here: http://2sxc.org/learn-razor/Relationships

I'm still not sure what I'm doing. It's hard to tell what certain things in the example code refer to, e.g. I'm not sure whether "courses" refers to a content type, field name, or variable in some places. Video didn't clarify it very well either.

This is my template:
@foreach(var e in List) {
    var Content = e.Content;
    // Here's the short version for the list of person depts
    var Staff = ((ToSic.Eav.IEntity)AsEntity(Content))    // cast to use power-API
            .Relationships.AllParents    // all parents, no matter what type
            .Where(c => c.Type.Name == "Person");    // now only the courses

@Html.Raw(Content.Toolbar)
<h3>@Content.Department</h3>
if(Staff.Any()){
foreach(var staffmember in Staff) {
var c = AsDynamic(staffmember);
    <h4>@c.Name</h4>
<p>@c.Position</p>
}
}
}
This is the closest I have gotten. It's not throwing an error, but it just puts out a list of these:
 <h3>System.Collections.Generic.List`1[ToSic.SexyContent.DynamicEntity]</h3>
^ Those should be the departments. No people are being listed at all.

My content type for staff members is named Person.
The content type for departments is PersonDepartments.
Apr 28, 2015 at 10:10 PM
Hi

I made you a very quick sample app as its midnight here already :)

the idea here is you have a n app and in there you have teams and persons and you can link a person to a team

what the tempalte does is take all teams in the db ( so not all teams from the module ) display it and show the persons associated

donwnload it here

Armand 2DNN
your friendly non official 2sxc support :)
Apr 29, 2015 at 12:58 PM
So you're saying this needs to be an app instead of just a content module?
Thanks for your help.
Apr 29, 2015 at 1:15 PM
App or Content is almost identical in functionality - nokiko is just giving you an app because it's easy to package and distribute which makes samples easier to share.
Apr 29, 2015 at 1:48 PM
I see.

Whenever I put this template in, I don't get an error, but everything is just blank.
Apr 29, 2015 at 2:06 PM
Department seems to be a list of related content-items. If you only need the first one, try this
<h3>@Content.Department[0].EntityTitle</h3>
Instead of entitytitle you could also write any other field that describes a Department
Apr 29, 2015 at 2:17 PM
amanda

I see now i set the team as content type and did not make it a no content type tempalte

just go to edit and add one item and you shoudl see everythign
Apr 29, 2015 at 2:48 PM
Tried that, still blank. :(
Apr 29, 2015 at 3:06 PM
realy strange

I just tried on a clean 734 install, imported and selected the app and it shows this ( all my test content )

Image

just to be clear you did went to app manangement and imported the app using the import app button and got a message that team tempalte installed uscesfully?
Apr 29, 2015 at 3:57 PM
I got it now. I had copied & pasted the template into my own module instead of importing this app. Sorry I'm so clueless.

Looks fine, but I'm getting an error when I try to add a new item.

From the Event Viewer:
Message:Value cannot be null. Parameter name: source
Apr 29, 2015 at 4:05 PM
mm strange

what happens if you just go to admin sampleteam, then to the content tab and from there click on the show items link on either team or person and add a new item though there
Apr 29, 2015 at 4:13 PM
It just shows the three original items.
Apr 30, 2015 at 10:24 AM
@Amanda

This is correct these were in the original app

I made you a qucick screencast how to edit

http://screencast.com/t/uDeK4NSGRVIv

If you have never used this setup the idea is that you dont ahve content attached to a module but it uses all content

so i have a content item for all teams

and i have a content item for all the people

And when i want to adit it i just go the admin for that app and add the content I need. you can also reause this content lets say you wnat to have a page with just a fe items you can just create a new tempalte. give it the person content type and when adding a new item choose to add excisting item and you can select any of the persons you added through the admin

All clear now?

Armand 2DNN
your friendly non official 2sxc support :)
Apr 30, 2015 at 1:44 PM
Yes, thanks. I would like to be able to use the buttons in the template's toolbar to add new people, since that's much less complicated, but this will work for now. I will try to rework this with my own template and keep you posted.
Apr 30, 2015 at 7:03 PM
I want to create a separate template to edit so I can keep your example one as a backup. I created a new template in the app's admin, but now when I click "Change Template/Layout" in the module edit menu, nothing happens.

I tried changing the page's skin to the default Cavalier, in case something in my skin was causing problem, but that did not help.
Apr 30, 2015 at 10:04 PM
Changing templates seems to be an issue with 6.6.5/6 or similar. We didn't follow up on it yet because we're just about to release 7.0 next Monday and it changes much how this is handled...
May 4, 2015 at 2:01 PM
I've just about got it where I want it. Just one question. In this line:
@foreach(var person in Persons.OrderBy(c => AsDynamic(c).name)) {
What does c mean?

I want to reorder the list, so the manager will appear first (I have a manager boolean field), then everyone else in the list alphabetically by the last name field.
May 4, 2015 at 2:58 PM
The real answer is actually a bit complex involving anonymous functions. So what actually happens is that Order-By waits for a return-value from the function inside its (...) brackets. The return-value is the Name. But to get the name, a the AsDynamic needs to know what item it's currently working for - and that's the c-variable which the Order-by gives in. Here's a bit of pseudo-code tryng to explain it.
function DoThisForEachItem_GetSortAttribute(entity) {
  return entity.Name
}

foreach(var person in Persons.OrderBy(DoThisForEachItem_GetSortAttribute(EachItemAutomaticallyGivenByTheOrderBy)) {
...
}
that's more or less what happens - just with an inline anonymous function and a Lambda expression (the =>)

:)