Templated Razor Delegates - Simpler HTML blocks - c#

I am working on some template generation stuff with Razor, and I wish to accomplish the following syntax:
<div>
#(Html.Use<LinkItem>("Story1",
{
<span>Something cool</span>
#(item.Text)
}))
</div>
or, even better
<div>
#(Html.Use<LinkItem>("Story1",
<span>Something cool</span>
#(item.Text)
))
</div>
Using Templated Razor Delegates, I got this:
<div>
#(Html.Use<LinkItem>("Story1",
#<span>Something cool</span>
#<a href="#item.Href">
#item.Text
</a>
))
</div>
The problem is, I dont wanna have to add a # before each tag in the block, and a <text> tag doesent look too good either.
Is it possible to achieve what I am looking for? Or maybe there are other ways?

The closest you could get is with <text> nodes:
#(Html.Use<LinkItem>("Story1", #<text>
<span>Something cool</span>
#(item.Text)
</text>))
Personally I prefer using display templates:
#Html.DisplayFor(x => x.SomeCollectionProperty)
and then I define the corresponding display template which is automatically rendered for each element of the collection (~/Views/Shared/DisplayTemplates/SomeItem.cshtml)
#model SomeItem
<span>Something cool</span>
#Model.Text

Related

Render children pages in umbraco

I'm trying to make an FAQ page. The content structure is like this:
FAQ
-- Question 1
-- Question 2
-- Question 3
I can't seem to work out how to get the child templates to render though (I'm new to this).
FAQ Entries (Parent page)
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = null;
var faqContentId = (int)CurrentPage.faqContent;
}
<html>
#Html.Partial("head")
<body>
#Html.Partial("header")
<div class="content">
#{
foreach (var child in Umbraco.Content(1168).Children) {
// render children here
}
}
</div>
#Html.Partial("footer")
</body>
</html>
FAQ Entry (Child pages)
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
#Umbraco.Field("title")
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body">
#Umbraco.Field("answer")
</div>
</div>
</div>
Welcome my dear Umbraco Dev. Let me point you to a few directions:
If you only want the solution, skip to number 3.
1) Refrain from using #inherits Umbraco.Web.Mvc.UmbracoTemplatePage as it will soon be deprecated. Use #inherits Umbraco.Web.Mvc.UmbracoViewPage instead which will get you strongly typed stuff in your view and your code will look like #Model.GetPropertyValue("myValue")
Even better, create a custom model or try using Umbraco ModelsBuilder
which will get you cleaner code and stronger bindings with strongly typed models. But that's for another day.
2) I would recommend not grabbing nodes by id Umbraco.Content('id').Children like this. The reason is that if you for some reason delete the node and then create it again later on with the same name, the id will be different and your code will break the website.
Look at this page where people pointed me to the correct way of traversing umbraco Umbraco traversing
It talks about speed but it basically shows you also the correct way to traverse. you could also find the rest you need within Umbraco's documentation.
3)To the actual question: I'm assuming that the page you're on is the parent and you just want to grab the children. Then it's as easy as :
var collection = Model.Content.Children();
#foreach (var child in collection ) {
child.GetPropertyValue("yourValueAliasHere")
}
if you were using #inherits Umbraco.Web.Mvc.UmbracoViewPage you would have:
var collection = Model.Children();
#foreach (var child in Model.Children()) {
child.GetPropertyValue("yourValueAliasHere")
}
It should be something like #Html.Partial("FAQ Entry", child), where the 2nd parameter is the model (child object) that you want to pass into the partial view.

How to Include HTML inside If Statement

Why when I have certain HTML in my C# statements does Razor complain about invalid expressions and terms?
And how can I fix this?
For example; in my _layout.cshtml:
#if (Team.Id == ViewBag.TeamId)
{
</div>
<div class="row">
}
Razor actually tries to understand your HTML. Unfortunately it can't be highly intelligent and recognise dynamic code or code outside of the expression.
Since
</div>
<div>
is invalid HTML, it complains.
You can avoid this problem by using #:
This forces razor to bypass its "HTML recognition", and simply print whatever you're asking for.
E.g.
#if (Team.Id == ViewBag.TeamId)
{
#:</div>
#:<div class="row">
#:
}
You can also use #Html.Raw("YOUR HTML"); inside an if statement to add HTML code

umbraco 7: get property value

I am using umbraco 7 ASP.NET C# MVC 4.
Im trying to use the new umbraco, so far its been ok, but i need to get a property of one of my pages i set up.
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var homePage = CurrentPage.AncestorsOrSelf(1).First();
var menuItems = homePage.Children.Where("isMenu == true");
}
<!-- Nav -->
<div class="row">
<div class="col-md-12 top-menu-container">
<ul>
#* If the Url of the current page is "/" then we want to add the class "current_page_item" *#
#* Otherwise, we set the class to null, that way it will not even be added to the <li> element *#
<li>
<div onclick="location.href='/';" class="col-md-2 metro-container" style="background-color:##Model.Content.GetPropertyValue("navigationColor")" >
<img class="menu-img" src="../../media/1001/home.png" alt="" />
Home
</div>
</li>
#foreach (var item in menuItems)
{
#* If the Id of the item is the same as the Id of the current page then we want to add the class "current_page_item" *#
#* Otherwise, we set the class to null, that way it will not even be added to the <li> element *#
<li>
<div onclick="location.href='#item.Url';" class="col-md-2 metro-container" style="background-color:##item.Content.GetPropertyValue("navigationColor")" >
<img class="menu-img" src="../../media/1001/home.png" alt="" />
#item.Name
</div>
</li>
}
</ul>
</div>
</div>
So the first "li" outside the loop i simply get the models content Getproperty method which surely enough gets me any property i tell it too.
However the loop i have although goes through the current pages children, i cant seem to get a specific property.
Makes it worse is intellicense Isn't working as its all runtime.
The line in question is
<div onclick="location.href='#item.Url';" class="col-md-2 metro-container" style="background-color:##item.Content.GetPropertyValue("navigationColor")" >
I need to get the color that was set on the page from the navigationColor control.
What am i doing wrong here?
Big derp on my side.
The item var in the foreach loop already has property's contained in the item.
all you need to do is
item.NameofYourPropertyAlias
and that should do it.
The following code works for me:
item[index].GetProperty("name").Value
Makes it worse is intellicense Isn't working as its all runtime.
The problem is that you're using dynamic model instead of the strongly typed kind.
Instead of using CurrentPage you can use Model.Content.
So instead of:
var homePage = CurrentPage.AncestorsOrSelf(1).First();
Use:
var homePage = Model.Content.AncestorOfSelf(1);
Intellisense will then work after you type a stop after homePage.
I would also strongly recommend inputting using Umbraco.web with the rest of your using statements at the top of the template. This should further improve intellisense, and allow you to see methods such as .GetPropertyValue<T>(string alias).
You should then be able to use item.GetPropertyValue<string>("navigationColor").
item.NameofYourPropertyAlias
this is the proper use of item while looping

Add Css class to div from controller C#

What would be the best way to add/remove a css class to a div from the controller?
I have a div in a razor view like so (simplified)
<div id="divToToggle" class="hidden">
//content
</div>
In my controller, depending if there is content or not, I want to add or review that class="hidden".
if (model.name.HasAValue())
{
model.company = Method();
//Toggle div to visible here.
}
I have thought about making a new property in the model and setting that value and then in the razor view doing like class="#Model.CssName" However, I have numerous tabs to deal with and don't want to clutter the model up with another set of css properties. What would be the most efficient way to do this?
In view you can do:
<div id="divToToggle" class=#(model.name.HasAValue()?"hidden":"visible")>
//content
</div>
You can also add class, if you have array of class and you want to append in foreach loop
<div class="panel #arrayClass[count1] panel-stat">
</div>
If you have class returning from model
<div class="panel #model.class panel-stat">
<div>
Or you can also use if condition or ternary operator as per your requirement you can do what you want to achieve.

use viewdata to perform inline styles

Im populating viewdata with a bunch of css style properties.
<span style="font-size:50pt; font-family:"<%= ViewData["font"]%>";"><%= ViewData["UserCopy"]%> </span>
i want to be able to do something similar to the above. i.e use the style put into viewdata and use them on inline styles.
how can i do this?
thansk
You have too many double quotes. Try this:
<span style="font-size:50pt; font-family:<%= ViewData["font"]%>;">
<%= Html.Encode((string)ViewData["UserCopy"]) %>
</span>

Categories

Resources