Conditional link in Razor - asp.net-mvc

I have some tabs, and I want to say "if they are currently on the page that this tab refers to, make this a span. Otherwise, make this a link." In pseudo-razor, that would look like this:
#if(CurrentlyOnThisPage) {
<span>
} else {
<a>
}
Tab Content
#if(CurrentlyOnThisPage){
</span>
} else {
</a>
}
Razor (correctly) notes that I'm not closing my beginning tags, and so has trouble parsing this syntax. If the tab content was small, I could use Html.ActionLink, but I've got a few lines of stuff and I'd like to keep the benefits of the HTML editor rather than putting it all into a string. Is there any way to do this?

You can write the tags as literal text to prevent Razor from parsing them:
#:<span>

How about something like this?
#{
var linkOrSpan= CurrentlyOnThisPage ? "span" : "a";
}
<#linkOrSpan><text>Tab Content</text></#linkOrSpan>
No errors about closing tags with this.
Looks a bit cleaner too ihmo.
HTH

Or just write it out explicitly:
#if(CurrentlyOnThisPage)
{
<span>tabcontent</span>
} else {
<a>tabcontent</a>
}

Related

Spaces being turned into in angular

I'm using ng_repeat to display text from an object. On the rails backend I call strip_tags(text) to remove html. When looking at the output it looks fine. Even when looking at the object in 'view source' it looks fine.
It only looks weird when you look at the text that is actually rendered from the ng_repeat - after a certain point (200 words in the example below) every space is replaced by an
This is causing the text to overflow the div. Any suggestions for dealing with this?
Edit: Some of the code (simplified)
JS:
$scope.init = function(id){
$scope.episodes = gon.episodes
Haml:
.episode-edit{ng_repeat:"episode in episodes"}
%p {{episode.sanitized_summary}}
You should try ng-bind-html. Your snippet would look like
<p ng-bind-html="YourObject"></p>
You can use it in ng-repeat as well.
If you want to secure the data first then include $sce service in your controller. Your snippet would be like
var ExampleCtrl = function($scope, $sce) {
$scope.YourObject = $sce.trustAsHtml($scope.YourObject); // that's it
}
Sorry, turns out it had nothing to do with angular, more to do with Ruby.
Ruby's whitespace regex doesn't capture unicode non-breaking space.
Instead of str.gsub(/\s/m, ' ') you have to use str.gsub(/[[:space:]]/m, ' ')

CSS class on generated div element for EPiServer blocks

I have a ContentArea with a number of floating blocks. EPiServer automatically wraps each block in a div-element, which is necessary for the edit mode to function properly. So what is initially one div becomes three nested divs: content area, child element wrapper and the block view.
Is it possible to add CSS classes to the child element wrapper from the block view? So what is today:
div.ContentArea > div > div.my-class
becomes:
div.ContentArea > div.my-class
If you want to avoid the extra wrapping divs, take a look into this post
My guess is that this is what you should render:
#Html.PropertyFor(x => x.Teasers,
new
{
ChildrenCustomTagName ="div",
ChildrenCssClass = "my-class"
})
Don't render a wrapping div element in the partial view, only the "inner content" (since a wrapping div element will be rendered regardless for each item in the content area).
The wrapping element rendered when the content area is rendered cannot be excluded, as that would break the on-page editing features in EPiServer.
Hope this helps and is clear enough.
I ended up using a custom content area renderer:
public class CustomContentAreaRenderer : ContentAreaRenderer
{
protected override string GetContentAreaItemCssClass(HtmlHelper htmlHelper, ContentAreaItem contentAreaItem)
{
var tag = GetContentAreaItemTemplateTag(htmlHelper, contentAreaItem);
return string.Format("block {0} {1} {2}", GetTypeSpecificCssClasses(contentAreaItem, ContentRepository), "my own classes", tag);
}
}
I apply the custom renderer to the container with this code:
container.For<ContentAreaRenderer>().Use<CustomContentAreaRenderer>();
Thank you for your help!
Here you can read all there is about exending contentarea, and also why they work like they do.
http://blog.tech-fellow.net/2015/06/11/content-area-under-the-hood-part-3/
It's possible to completely remove the extra div's by overriding the default content area. I've written quite a detailed tutorial here EpiServer 7 : Extra divs in content area how to remove them ?
Going with this approach is quite extreme though. If you only have this issue in one or two places then I would recommend using something like this
#Html.PropertyFor(x => Model.MainContentArea, new
{
CustomTag = "ul",
CssClass = "list",
ChildrenCustomTagName = "li",
ChildrenCssClass = "list_item",
Tag = string.Empty
})
You can read more about how these properties work here : How To Render EpiServer Blocks In Your Views Using PropertyFor

grails current page highlight

In grails I have a menu. I'm trying to highlight the menu item for the active page:
link1
link2 (show as bold if the controller action partially matches this gsp name)
link3
I have working code but it seems like there would be a better way.
Taglib works fine:
def active = { attrs, body ->
for (page in attrs.check) {
if (params.action.startsWith(page)) {
out << "current"
break
}
}
}
This option works fine, but seems wordy:
<li>Contact Info</li>
<li>About You</li>
This blows up:
<g:link action='myProfile' class="${<xyz:active check='${['myControllerAction']}'/>}">My Profile</g:link>
I don't believe you can pass a taglib as a parameter to g:link
I also have the requirement that multiple gsps/actions would cause a link to be active because of how they are named:
aboutYouLocation
aboutYouBackground
aboutYouEducation
all make this link the active one:
About You
I can do a partial match, but I've also got some actions/gsps that begin with aboutYour (extra R) resulting in my use of the array being passed into my taglib.
There's a standard way of doing that with the Platform Core plugin. It will provide you a Navigation API:
grails-app/conf/AppNavigation.groovy
navigation = {
// Declare the "app" scope, used by default in tags
app {
contact(action: 'contactInfo')
about(action: 'aboutYouFamily')
}
}
*grails-app/view/_menu.gsp* (template that you can use in your layout or GSP's)
<nav:menu scope="app" id="navigation" />
You can also customize the html generated for your menu, check the custom item rendering.

MVC View <text> Styling

This is probably for dummies question, but how to set styling inside <text>? For example to col put colour in:
#{
if (TempData.Count != 0)
{
<text>The quantity available is #TempData["checkQuantity"]</text>
}
}
<text> is not an HTML tag; rather, it's a special symbol that tells Razor that whatever is inside of it is not code.
If you want to apply CSS, you need to use an HTML tag.
Razor is smart enough to realize that an HTML tag inside a code block is not code, so you don't need to do anything different:
#if (TempData.Count > 0) {
<strong class="MyClass">...</strong>
}

another way to write this

Is there another way to write this:
//javascript and jquery area
'<% if (Model.Fruit == MyEnum.Apple) { %>'
$("#PaymentType option").each(function(){
//blah
});
'<% } %>'
i'm not sure i like the quotes around the whole if statement
In your view:
var isApple = <% Model.Fruit == MyEnum.Apple %>;
In an included javascript file:
if(isApple) {
$("#PaymentType option").each(function(){
//blah
});
}
If the goal is to have VS continue to correctly check/auto-reformat javascript then you must use your trick or one similar to avoid the issue.
In one of the answers to the following related question there is text from Microsoft indicating that this is a known issue for which they do not yet have a good solution.
Visual Studio confused by server code inside javascript

Resources