How to loop through properties in a tab and display them using Razor? - umbraco

I have a Document Type, that has a tab with some properties.
The properties are Upload types, and Simple Editor types.
(Users are supposed to upload images with some image text).
I have not grouped the "Upload" and "Simple Editor" properties, so how do i do this?
Next question,
I want to loop through each group (there should be 3 currently) and display them on my website.
The markup should look like the following:
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
..
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
...
I would like to use Razor for this. Thanks in advance!

For the first part, using the Razor model, you can't. The content object that you get on the front end only contains the properties, the tabs are not included, as they're only really for organising things in the back office.
You CAN get that information using the Umbraco API, but it's pretty database intensive and could potentially be quite slow if you have a lot of properties/tabs.
You'd be better grouping them yourself in your Razor Macro.

for the second part, you can acces the properties of a page via #Model.property. For example:
<div>
<div>#Model.simpleProperty</div>
</div>

Related

How do I conditionally parse formatting with Thymeleaf?

Is there an alternate way I can get this to process with Thymeleaf? Thymeleaf doesn't like the open tag, but I want to only render it for ROLE_A.
<span sec:authorize="hasRole('ROLE_A')">
<div class="col-xs-10">
</span>
bunch of text not specific to ROLE_A
<span sec:authorize="hasRole('ROLE_A')">
custom text specific to ROLE_A
</div>
</span>
I tried using
<sec:authorize="hasRole('ROLE_A')">
and
<div sec:authorize="hasRole('ROLE_A')">.
The former also doesn't run due to the same open tag issue and the latter is mixing up the closed div tags.
I have numerous blocks like this, so duplicating sections for different roles is not a great solution.
Not in the style you want. You need to close those elements.
My advice is then consider using fragments and load them as required with the needed data/
That way you reuse existing code thus making it cleaner and smaller.
For more examples and way you can do the above check out the Thymeleaf page http://www.thymeleaf.org/doc/springsecurity.html.

Displaying HTML and Images in MultiSelectList ASP.NET MVC Razor

I need to show a drop down list with ability to select multiple items. I am able to bind this with a Dictionary object and it works fine with plain text values. However, i need to include img tags as well in the values.
This is basically a list of people along with their public profile picture. However, the list shows the html tags instead of showing the actual image.
Here is the razor code in my view:
#Html.ListBox("MyFriends", new MultiSelectList(Model.Connections.Distinct(), "key", "value"), new { #class = "list-item"})
The output is shown as:
<img src="http://localhost/api/person/1211/dp" title="avatar" /> John Smith
<img src="http://localhost/api/person/1212/dp" title="avatar" /> Person Two
<img src="http://localhost/api/person/1213/dp" title="avatar" /> Person 3
<img src="http://localhost/api/person/1214/dp" title="avatar" /> Rick Rude
But i want to actually show display picture followed by the name. Any solution?
The problem you are facing is not strictly connected with Razor or even with ASP.NET MVC.
It is connected with the fact that DOM prohibits you from placnig an tag directly inside tag (so it's an HTML-related constraint).
There is a possibility to use CSS styling to add images to your select list:
How to add a images in select list
This will though most probably not solve your problem because the styles are added statically, whereas your list is dynamic.
All in all I think you should consider using some alternative for Html.Listbox like for example jQuery Combobox.

Referring to current HTML-Element in Razor?

In Razor (MVC 4) can I do something like the following (pseudo)code?
<div id="One" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
<div id="Two" #if(THIS_ID_IS("One")) {WRITE_SOMETHING_HERE} ></div>
My intention is, that in DIV "One" an additional attribute will be written, but not in DIV "Two"
So, the THIS_ID_IS(string id) should determine, if the Razor-Parse is INSIDE the given DIV with id="xyz"
Is this possible?
You can use single line if statement to overcome this situation
<div id="One" #(THIS_ID_IS("One") ? "write something" : "") ></div>
Since ids are unique values. All divs will have diffrent ids.
So I dont think there is any need for Conditional Check in razor.
You can Directly add the extra attributes to your Div as follows
<div id="One" attribute-name="Value"></div>
In situations like this I tend to write a helper method to output the markup. This way you a not constrained by the 'rules' of razor. I did a similar thing to output jQuery slider html inside a div.
It also depends on your target audience, I rarely produce the actual views as our designer does most of that. I don't like handing over stuff to the 'creatives' that requires them to write/understand the logic.
It may not be the ideal solution or maybe even overkill in your situation but may be worth a look.
http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs
As much as I would like it to be possible. It looks like it's not the case.
Based on these two articles :
Simple
In depth
It would seem that the Razor engine combines a code and a markup parser.
The main parser decides to use one or the other.
So the parsers are not aware of one another.
Simply put, in your example, <div id="One"></div> and #if(THIS_ID_IS("One")) would be parsed in different scopes and then just concatenated together.

How to hide a content placeholder if it has no children without client code (MVC)

I have a ContentPlaceholder inside of a MasterPageView. All of my other pages come from the same master and I have one page that needs about 70% of the behavior in this master. There is a navigation panel in the master that is spitting out un-necessary html even if left blank by the page. Looks like this:
<div class="span3">
<div class="side_navigation">
<ul>
<asp:ContentPlaceHolder ID="SideNavigation" runat="server" />
</ul>
</div>
</div><%-- /master sub-navigation --%>
I simply want to hide ALL of this markup whenever my placeholder (SideNavigation) has 0 children. I don't want to use javascript. I'd rather do this work on the server and deliver it to the client with less responsibility and markup. I've already tried doing "this.SideNavigation.Controls.Count" but it always ends up being 0. If there was a way I could tie into a loaded event and then test this logic that would be great. I am ok with making a code-behind file for my master, but it would be nice to be able to accomplish my goal in the .master file only.
Let me know what you think.
I would probably recommend using a different master page for the page without the navigation. You can have nested master pages so you don't necessarily need to duplicate code to do this.
However if you do wish to keep it like this, I would personally use a bit of javascript (with jquery) as follows
$(function(){
if($('.span3 .side_navigation ul li').length() == 0){
$('.span3').hide();
}
});
obviously i'd give span3 an ID to make it not hide every span3 but you hopefully get the idea.

Designer-friendly views in Asp.Net MVC

I'm enjoying Asp.Net MVC and am looking to use it in an upcoming project. Part of the project, however, is an emphasis on being able to expose the project Views to designers for things like theming and so on. One problem I'm anticipating is that Asp.Net MVC views are rather developer-centric. I really don't want to have to educate designers on the intracies of <% vs. <%= let alone something like <% foreach ...
Take a typical MVC menu structure, for example.
<div id="menu">
<ul>
<li><%= Html.ActionLink("Home", "Index", "Main")%></li>
<li><%= Html.ActionLink("About", "About", "Main")%></li>
<li><% Html.RenderPartial("LogOnUserControl"); %></li>
</ul>
</div>
I'd much rather be able to tell designers to go with something like
<div id="menu">
<ul>
<li>{ActionLink "Home", "Index", "Main"}</li>
<li>{ActionLink "About", "About", "Main"}</li>
<li>{Partial "LogOnUserControl"}</li>
</ul>
</div>
Or
<div id="menu">
<ul>
<li><my:ActionLink text="Home" action="Index" controller="Main" /></li>
<li><my:ActionLink text="About" action="About" controller="Main" /></li>
<li><my:Partial name="LogOnUserControl" /></li>
</ul>
</div>
Yes, that last looks suspiciously like a raft of UserControls. Personally, I'm not a fan of actually using UserControls to do this if only because the rendering of those controls happens after pretty much everything else (as I understand it) and I'd prefer something that fits more in line with the MVC lifecycle. All I really need is a set of placeholders and a way to replace them with the relevant rendering.
So where's the best place to do so and what kind of trade-offs am I looking at here. I can imagine a couple of angles to come at this:
A custom ViewPage class where I can override something relevant. ViewPage.RenderView or ViewPage.FrameworkInitialize, maybe, but how you get at the text from there I don't know.
Create a custom TextWriter and override ViewPage.CreateHtmlTextWriter that I can then intercept the text output for replacing stuff. This is pretty late in the cycle, though, and will mess with other custom filtering if I'm not careful.
Create my own IView and ViewEngine classes. I didn't get far down this path before wondering if I was headed to a very bad place.
Custom UserControls that can mimic the functionality needed.
Opinions? Other options? Is my own ViewEngine my best option? My own ViewPage? Or are UserControl objects going to be adequate (please say no)?
Take a look at Spark. It's syntax is similar to your example.
As Charles Conway said, Spark is definitely way to go. Look at example. First, you create partial view in _ActionLink.spark with code:
<viewdata text="String" action="String" controller="String">
${ Html.ActionLink(controller, action, text) }
Then you use it like that in other views:
<ActionLink text="Home" action="Index" controller="Main" />
You just have to prepare partial views for your designers and then they an create view in prefered style. Isn't it easy?
EDIT:
Sorry, that was wrong. <ActionLink text="Home" action="Index" controller="Main" /> will not work, because Home, Index and Main are treates as variables. It may not be that easy to do it as you wish.
I have a similar requirement for a current project, except my 'designers' are more or less end users (people that know their way around html, but it's not their job) which leads to some additional challenges. My implementation is probably too specific for your needs but I'll quickly explain it lest it be useful to anyone else.
I wanted to totally avoid any kind of code in the views for the pages they would be designing so I decided to go with a templating system that does something similar to your point #2, but not at runtime. I am also using spark, although it's not for the benefit of the users as they won't be touching anything that looks like code.
Basically the users create a full html-only template that has placeholder tags for user controls and partial views. The users then upload the template through an interface that parses it and turns it into a spark view.
eg.
For a picture gallery, <gallery /> is parsed into something like !{Html.Gallery(Model)} or <use file="Gallery"/>. For a description field, <desc name="Kitchen" /> is parsed into !{Html.Description(Model, x => x.Descriptions.Kitchen)}. It also checks that "Kitchen" is in fact a property for the object/page that is being templated, or that the Model being passed in for a gallery actually contains a collection of images to avoid runtime errors.
Further properties can be specified in the tag to pass additional parameters to the parsed controls. If the control specified requires Javascript, then it is also included in the view. If there are any problems parsing, output is return specifying which placeholder is invalid and why.
While answered and accepted, I don't see the example of this: why don't you just use:
<li><a href='<%= Url.Action("Home", "Index")%>'>Main</a></li>
Similar in Spark. I prefer this to Html.ActionLink, Html.BeginForm, etc, whenever possible (almost always except for form controls where it's easier to have automatic name encoding with Html helpers).
And your designers do see the link.

Resources