Umbraco Razor newbie syntax issue - razor

I have the following code block that nearly works. It completes the outer #foreach cycle and starts each sub #foreach cycle. It puts out the first image in each pair but then outputs
"} if(countItem==1) (" which can be read in the browser.
Any advice would be appreciated
Craig
Code:-
#inherits umbraco.MacroEngines.DynamicNodeContext
#{
int level = 2;
var subjects = #Model.AncestorOrSelf(level).Children.Where("nodeTypeAlias == \"SideGallerySectionHeading\"");
int countItem = 1;
if (subjects != null) {
<div class="highslide-gallery">
#foreach(var subjectName in subjects){
<h3>#subjectName.Name</h3>
foreach(dynamic image in subjectName.Children) {
if(countItem==1){<div class="picrowdiv">}
<div class="picdiv">
<a href="#image.Media("itemLarge","umbracoFile")" class="highslide" onclick="return hs.expand(this)">
<img src="#image.Media("itemThumbnail","umbracoFile")" width="100" height="100" alt="test"></a>
<div class="highslide-caption">
#image.bodyText
</div>
<p>#image.caption</p>
</div>
if(countItem==1){</div>}
countItem++;
if(countItem>2){countItem=1;}
}
}
</div>
}
}

You may try to rewrite the line
if(countItem==1){</div>}
into
#if(countItem==1){
</div>
}

Razor is quite picky about closing your html tags so you may have to refactor to make this work. I like ternary operators for stuff like this
try
#(countItem==1 ? "</div>")
#countItem++;
#(countItem>2 ? countItem=1)
you can also do else with a :
so
#(countItem==1 ? "</div>" : "")

Related

if else statement is not being treated as code inside #foreach - 2sxc v11 DNN 9.8

I'm currently learning 2sxc and am building a directory app as my initial project.
I'm trying to use the following code in a list view to change the way an item is displayed based on the Boolean "UpgradedListing"
#foreach(var listing in AsList(Data)) {
<div #Edit.TagToolbar(listing)>
if(listing.UpgradedListing == 'true'){
<strong>#listing.ListingName</strong<br/>
<a href='mailto:#listing.Email'>#listing.Email</a>
<hr/>
} else {
#listing.ListingName<br/>
<a href='mailto:#listing.Email'>#listing.Email</a>
<hr/>
}
</div>
}
the resulting output looks like this:
if(listing.UpgradedListing == 'true'){ Techmedics Ltd office#techmedics.co.nz
} else { Techmedics Ltd
office#techmedics.co.nz
}
if(listing.UpgradedListing == 'true'){ Solutions Online NZ Ltd enquiries#solutions-online.co.nz
} else { Solutions Online NZ Ltd
enquiries#solutions-online.co.nz
}
in other words the if else isn't being seen as code.
Can any one explain why this is?
You just need an # symbol in front of the first if, so
#if(listing.UpgradedListing == 'true'){
Also you've got a typo, your closing strong tag is missing its right >
And 'true' is not the same as true (boolean). 2sxc will know and return a boolean for .UpgradedListing (if you have it set AS a boolean field... if you have it as a string, then you need == "true"
and you can also move the stuff that doesn't change outside the if/else to make it more readable...
#foreach (var listing in AsList(Data))
{
// here you can still write C# without an #
// because it's still in code-mode
var x = 7; // this still works here
<div #Edit.TagToolbar(listing)>
<!-- here Razor switches to HTML because we had a Tag around it -->
<!-- so we need to really introduce the code-mode again -->
#if (listing.UpgradedListing)
{
<strong>#listing.ListingName</strong><br />
}
else
{
#listing.ListingName<br />
}
<a href='mailto:#listing.Email'>#listing.Email</a>
<hr />
</div>
}

How to give multiple conditions in *ngIf statement in angular 6?

My navigation bar,
<div *ngIf = ("path == '/login'" && "path == '/home'") class="tabs-header-nav">
<a routerLink="/login" class="nav-link active">login</a>
<a routerLink="/bb" class="nav-link">home</a>
<a routerLink="/" class="nav-link">CC</a>
</div>
<div *ngIf = ("path == '/aa'" || "path == '/bb'") class="tabs-header-nav">
<a routerLink="/aa" class="nav-link active">aa</a>
<a routerLink="/bb" class="nav-link">bb</a>
<a routerLink="/" class="nav-link">CC</a>
</div>
Likewise I have 5 to 6 navigation bar in my html. Now I need to display a particular navigation bar for particular page. Single if condition ( *ngIf = "path === '/aa'" ) seems to be working, where if I give multiple conditions it is not working. Could you please help me on this?
You should go for ngSwitch that takes multiple values
<div [ngSwitch]="path">
<div *ngSwitchCase="'/login'">...</div>
<div *ngSwitchCase="'/home'">...</div>
</div>
I have created a Stackblitz demo here
I think you are doing mistake in *ngIf quotations
If you have data that may in every time be different, mostly you use of If. but if is not ok in every where. It is better that you use of switch-case in your code like:
public string TestSwitchCase(string value)
{
switch (value)
{
case "John":
return null;
case "Jack":
return "Jack";
default:
break;
}
return null;
}
Now in angular, there is best way to do this in HTML code. this is ngSwitch and use like:
<container-element [ngSwitch]="switch_expression">
<some-element *ngSwitchCase="match_expression_1">...</some-element>
<some-element *ngSwitchCase="match_expression_2">...</some-element>
<some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
<ng-container *ngSwitchCase="match_expression_3">
<!-- use a ng-container to group multiple root nodes -->
<inner-element></inner-element>
<inner-other-element></inner-other-element>
</ng-container>
<some-element *ngSwitchDefault>...</some-element>
</container-element>
For more information See: This
GoodLuck.
[SOLUTION] : Simply use "&&" operator to add multiple conditions in *ngIf -
//TypeScript File - demo.ts
//Declaration
flag: any;
temp_array = [];
//Assignment
this.flag = true;
this.temp_array = [1,2];
<!--HTML File - demo.html-->
<div *ngIf="flag && temp_array.length>0">
Both *ngIf conditions passes
</div>

Model to Partial in Umbraco

I have the following snippet on my About Us page (shortened for clarity):
#foreach(var employee in CurrentPage.Employee) {
<img class="img-fluid" src="#Umbraco.Media(Convert.ToString(employee.Photo)).umbracoFile" alt="" />
<h2>#employee.Name</h2>
<h3>#employee.Title</h3>
<span>#employee.Bio</span>
}
The body of the foreach is actually bigger, I specificaly chose to leave the image in the snippet to show the usage of #Umbraco.Media
So I want to extract it to a Partial.
Here is the Code of the Partial:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.Employee>
#using ContentModels = Umbraco.Web.PublishedContentModels;
#using Umbraco.Web;
<img class="img-fluid" src="#Umbraco.Media(Convert.ToString(Model.Content.Photo)).umbracoFile" alt="" />
<h2>#Model.Content.Name</h2>
<h3>#Model.Content.Title</h3>
#Model.Content.Bio
The page then becomes this:
#foreach(var employee in CurrentPage.Employee) {
#Html.Partial("Employee", new global::Umbraco.Web.Models.RenderModel(employee, Model.CurrentCulture))
}
Problem is that I'm getting
Cannot bind source content type Umbraco.Web.Models.DynamicPublishedContent to model content type Umbraco.Web.PublishedContentModels.Employee.
I think my problem comes from the fact that I loop through my Employees with CurrentPage.Employee rather than going through something like Model.Children.
Anyway, is there a way to get the Model out of the DynamicPublishedContent ?
I found out what my problem was.
Actually and as a rule of thumb, you should not use CurrentPage
I changed the code in the About Us page to this:
#foreach(var employee in Model.Content.Children("Employee")) {
#Html.Partial("Employee", employee)
}
Then my partial view needs to start like this:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.Employee>
#using ContentModels = Umbraco.Web.PublishedContentModels;
And then I can use #Model.Name or any other DocumentType property on the Employee.
That's it!

Problems with getting an image to show in a paged list

I have the following code, and it displays the listed text and the pagination at the bottom all fine. But when I try to get the images from the child page into the list it errors for me. Any ideas why?
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = "SiteLayout.cshtml";
}
<div role="main" id="main">
<div id="blogPageFeatures">
<!-- loop through all of the child pages (blog posts) and grab data to output as a summary -->
#{
var pageSize =3;
var page =1;int.TryParse(Request.QueryString["page"],out page);
var items =Model.Content.Children().Where(x => x.IsDocumentType("BlogArticle")).OrderByDescending(x => x.CreateDate);
var totalPages =(int)Math.Ceiling((double)items.Count()/(double)pageSize);
if(page > totalPages)
{
page = totalPages;
}
else if(page <1)
{
page =1;
}
}
#foreach(var item in items.Skip((page -1)* pageSize).Take(pageSize))
{
<a href="#item.Url">
<!-- The next image line is where it errors -->
<img src="#Umbraco.Media(item.Children.blogArticleImage).Url">
<h2>#item.Name</h2>
<p class="blogTileDate">#item.CreateDate.ToString("dd/MM/yy")</p>
</a>
}
<div class="clearfix"></div>
<!-- Pagination START -->
#if(totalPages >1)
{
<div class="pagination">
<ul>
#if(page >1)
{
<li>Prev</li>
}
#for(int p =1; p < totalPages +1; p++)
{
var active =(p == page)?" class=\"active\"":string.Empty;
<li#(Html.Raw(active))>
#p
</li>
}
#if(page <totalPages)
{
<li>Next</li>
}
</ul>
</div>
}
<!-- Pagination END -->
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
</div>
You are getting Model.Content.Children, which is a strongly typed collection of IPublishedContent objects. You are then calling item.Children.blogArticlImage, which is not going to work, as you're trying to get the a property on the children of the item, not a property of the item itself. You're also trying to use dynamic syntax, which won't work on the strongly typed objects. Try changing your image code to:
<img src="#Umbraco.TypedMedia(item.GetPropertyValue<int>("blogArticleImage")).Url">
That should do te trick, one thing to note is that if an item doesn't have an image set, or the image that has been selected has been deleted, it'll throw an error. A more robust approach would be something like this:
var imageSrc = "ADD DEFAULT IMAGE PATH HERE";
var media = Umbraco.TypedMedia(item.GetPropertyValue<int>("blogArticleImage"));
if (media != null && !string.IsNullOrEmpty(media.Url))
{
imageSrc = media.Url;
}
<mig src="#imageSrc">

razor count items

How can i do this in razor:
when there is one item, i only want this item to be displayed. (item in fotoGallerij)
when there are more items, i want all of them (like the code bellow, working)
How can i make this if (i think) structure in razor (c# / umbraco)?
#inherits umbraco.MacroEngines.DynamicNodeContext
<ul class="image-gallery">
#foreach (var item in #Model.fotoGallerij)
{
<li>
<a class="gallery grouped" href="/ImageGen.ashx?height=500&constrain=true&crop=resize&image=#item.Image.umbracoFile" title="">
<img src="/ImageGen.ashx?width=71&height=73&crop=resize&image=#item.Image.umbracoFile" alt=""/></a>
</li>
}
</ul>
<script>
$("a.gallery").colorbox({rel:'grouped'});
</script>
Thanks for helping!
Razor is in effect C#, so anything you can do with C#, you can do with Razor. Something like this should work:
#inherits umbraco.MacroEngines.DynamicNodeContext
#if (Model.fotoGallerij.Count() == 1)
{
// Display only the one here...
}
else if (Model.fotoGallerij.Count() > 1)
{
// Loop through the list of items here...
}