Creating 2sxc Content Template - razor

I followed the steps as per the following guide tutorial:
http://2sxc.org/en/Learn/Getting-started-with-creating-stuff/First-Content-Template
But I am having trouble with one or two issues.
When I get to Step 2.2 Add the Demo Template by pasting in the Template.txt file into my newly created Template .cshtml file, I am not seeing as expected with my Heading (Content.Title) and my Call to Action button/link (Content.LinkText) are not appearing on screen. This is preventing me from creating even the most simple of templates
After pasting in the Template.txt code:
<div class="sc-element"> #Edit.Toolbar(Content) <!--- Edit toolbar -->
<div class="co-person-image col-sm-4">
#if (!String.IsNullOrEmpty(Content.Photo))
{
<img src="#Content.Photo?w=350" alt="#Content.Name" class="img-responsive" />
}
else
{
<div class="co-person-placeholder"></div>
}
</div>
<div class="co-person-text col-sm-8">
<p>
<strong>#Content.Name</strong><br />
#if (!String.IsNullOrEmpty(Content.Position))
{
#Content.Position<br />
}
</p>
<p>
#if (!String.IsNullOrEmpty(#Content.EMail))
{
#Content.EMail<br />
}
#if (!String.IsNullOrEmpty(Content.Phone))
{
<text>#Content.Phone<br /></text>
}
</p>
#Html.Raw(Content.Description)
</div>
</div>
I am not seeing any placeholder and when I upload an image using ADAM it too wont appear to screen?
Not sure what I am doing wrong but would really appreciate some help on this as I also tried simply pasting in code from another one of your bootstrap templates into my new template but am getting the following error:
Error: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: The best
overloaded method match for 'string.IsNullOrEmpty(string)' has some
invalid arguments at CallSite.Target(Closure , CallSite , Type ,
Object ) at
System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite
site, T0 arg0, T1 arg1) at
ASP._Page_Portals_0_2sxc_Content__text_block_image_block_12_cshtml.Execute()
in d:\Inventise\trunk\Customers\St Josephs
Foundation\Projects\Website\Sources\DNN-Root\Portals\0\2sxc\Content_text
block_image block_12.cshtml:line 26 at
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() at
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext
pageContext, TextWriter writer, WebPageRenderingBase startPage) at
ToSic.SexyContent.Engines.RazorEngine.RenderTemplate() in
C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\2Sexy
Content Razor\RazorEngine.cs:line 76 at
ToSic.SexyContent.Engines.EngineBase.Render() in
C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\SexyContent\Engines\EngineBase.cs:line
89 at ToSic.SexyContent.SxcInstance.Render() in
C:\Projects\2SexyContent\Web\DesktopModules\ToSIC_SexyContent\SexyContent\SxcInstance.cs:line
200
The path mentioned in the above error message appears wrong but I don't know where this can be amended?
I would appreciate help on this issue.
Regards

I'll try to guide you through it, but I'm guessing you forgot to set a demo-item.
The demo-item is used to show data on a template, till a user adds his own. So it's really important to create an item in the admin UI (Step 1.5) and assign it to the template (Step 1.5.1). This allows the template to render, before you add any data to a page :).
If you don't have a demo-item, the template assumes it can't render, and will show a message that it doesn't have data yet - or it will try to render, and fail with errors like the one above.
Did that help?

Related

Space Between Text In Same JSON String

I am volunteering to write a quick AngularJS App for a non-profit. I have set up Angular successfully but the one problem I am coming across stems from the JSON.
I have a JSON object that contains multiple paragraphs. Therefore I need to separate the paragraphs onto two lines. I did some research and I found some answers to similar questions but because they were not put in context I did not understand them. I tried looking to see if JSON had something built in that forced a line break, because that would do, but I did not find that.
Help is greatly appreciated!
HTML w/ Angular JS
<div class="bio">
{{exhibits[whichItem].bio}}
</div>
JSON
[
{
"name":"Name goes here",
"bio":"First long block of text goes here then it needs a break <br /> and the second long block of text is here."
}
]
#user5854648 Your back-end sending the JSON response in this format .If you are using angular version greater than 1.2 to display the text content with html tags(People's calling this as unsafe html ) use angularjs inbuilt service called $sce .To make it as a reusable component created a custom filter.
var demoApp = angular.module('demoApp',[]);
demoApp.filter('trustAsHtml', [
'$sce',
function($sce) {
return function(value) {
return $sce.trustAsHtml('html', value);
}
}
]);
then make changes in html like
<div class="bio">
{{exhibits[whichItem].bio | trustAsHtml}}
</div>
or
<div class="bio">
<p ng-bind='exhibits[whichItem].bio | trustAsHtml'></p>
</div>

How do I check the Html.ValidationSummary for errors?

I am writing an mvc web app and I'm trying to check to see if there are any errors in the Html.ValidationSummary to determine if I need to display the div that handles the messages.
#if(Html.ValidationSummary() != null)
{
<div class="registration-val-summary">
<label class="registration-val-label">
Please correct the following issues with your registration:
</label>
#Html.ValidationSummary()
</div>
}
This is the error that I receive:
Unexpected "if" keyword after "#" character. Once inside code, you do
not need to prefix constructs like "if" with "#".
From what I read in this post: Unexpected "foreach" keyword after "#" character It is due to the "Html" that I have inside my code. I understand the error but I do not know how to get around it. I want to avoid displaying the div that wraps the ValidationSummary unless there are actually errors to display otherwise the message about correcting your error shows up and displaces my form.
How do I hide this if ValidationSummary has no messages to display?
You are recieving that error because you are rendering the partial view rasor code from Html.ValidationSummary() into your if statement. The compiler then sees any # symbols the validationSummary renders and fails.
A simple check to see if there are validation errors is to do #if(!ViewData.ModelState.IsValid)
#if(!ViewData.ModelState.IsValid)
{
<div class="registration-val-summary">
<label class="registration-val-label">
Please correct the following issues with your registration:
</label>
#Html.ValidationSummary()
</div>
}
Html.ValidationSummary() is displayed IF and ONLY IF there validation errors on the page.
What you are trying to do is already achieved by the Html.ValidationSummary() helper and it returns an HTML div element that contains an unordered list of all validation error messages from the model-state dictionary [Source]
Html.ValidationSummary() renders a partial view, but you can customize/extend the view by following this answer
In your case, you might want to put the following code inside the customized view that you will create
<div class="registration-val-summary">
<label class="registration-val-label">
Please correct the following issues with your registration:
</label>
</div>

recursive/circular template calls

I have a setup with Angular 2 where the home.html has a
<widgetcontainer></widgetcontainer> call, which in turn calls certain widget templates.
Those widget templates however would need to call widgetcontainer again so their sub-widgets can be displayed as well.
It looks somewhat like this:
home.html:
<div> home site specific content </div>
<ul>
<widgetcontainer *ng-for="#widget of widgetList" [containerwidget]="widget"></widgetcontainer>
</ul>
widgetcontainer.html:
<li>
<div [ng-switch]="containerwidget.type">
<p *ng-switch-when="1"><widget1 [widget]="containerwidget"></widget1></p>
<p *ng-switch-when="2"><widget2 [widget]="containerwidget"></widget2></p>
<p *ng-switch-default>Error in widget-data</p>
</div>
</li>
now widget1 and widget2 are pretty much identical except for the first bit of content:
<div> widget 1 or 2 specific content </div>
<div *ng-if="widget.widgetSubList">
<div class="widget-sub-listing" *ng-for="#widget of widgetlocal.widgetSubList">
<widgetcontainer *ng-for="#widget of widgetlocal.widgetSubList" [containerwidget]="widget"></widgetcontainer>
</div>
</div>
The reason why I need to do it this way is that widget1 can contain a series of widget2 (and others) which in turn can contain widget1 again.
The .ts counterparts of each widget contain the required #Input part, so if I leave out the call to widgetcontainer, it does work just fine, though of course therefor can't display the subwidgets anymore. Reading out the subwidgets works as well, tested that with console.logs.
I found similiar problems like this one: How do I inject a parent component into a child component?
where, from what I gathered, the problem is solved by importing Input and forwardRef and using
constructor( #Inject(forwardRef(() => widgetcontainer)) private _parent: widgetcontainer) { }
in the children, in my case widget 1 and 2. I tried that as well, but I still get an error. Importing widgetcontainer to the widget.ts files works without trouble, adding it to the directives or adding the <widgetcontainer></widgetcontainer> call into the html of widget1 or 2 breaks the program and throws me the error message:
EXCEPTION: TypeError: Die Eigenschaft "length" eines undefinierten oder Nullverweises kann nicht abgerufen werden. in [null]
As a little translation-attempt: it basicly says
the property "length" of an undefined or null-reference can not be called. in [null]
And I can't locate where exactly the error is. Considering it works without adding widgetcontainer to the directives in widget1 or 2, I would guess that is where the whole thing breaks though.
Previously I had a similiar error, though instead of length it stated to have failed calling forEach though now I am unable to replicate the error.
From what I have been reading up on the problem is the circular reference/call of the <widgetcontainer></widgetcontainer> template. It should be possible to have it work, though it needs a stopping-condition to not turn into an infinite loop. Therefor I already have the *ng-if condition in my widget1 and 2 which is tested already with simple listings of the subwidget IDs and worked just fine as a condition.
The question is now where am I going wrong here? Or how can I get the circular call to work?

Simplifying ASP.Net MVC Razor Code

I'm looking for suggestions on how to simplify/optimize a piece of code in one of my view files in my ASP.Net MVC project. The code works, but I'm not sure if I've written it the best way.
Basically, the code is used to display a list of links to documents, with little thumbnails to the left of each link. The main problem, is that there are two different types of documents, and each type has to have it's thumbnail image stored in a different location, this is a project requirement and can't be changed.
I'm currently accomplishing this with the view code shown below.
// Display a link to every document.
foreach (var document in documentList)
{
<a href="#Url.Content("~/Document/DownloadDocument/" +
document.documentid)" target="_blank">
#{
// This will be the root of all the paths.
var path = "~/Document/DisplayImage/";
// If it's a Type 1 document, we need to use a different path.
if (document.documentType == "Type 1") {
path += "Path/To/Image/Folder";
<img id="imageHolder" src="#Url.Content(path)"
onerror="imgError(this);" />
#document.documentname
}
else {
path += "Path/To/Different/Image/Folder";
<img src="#Url.Content(path)" />
#document.documentname
}
}
</a>
<br />
}
Like I said, the code works, but I'm not too happy with how it's written. Does anyone have any suggestions?
When working with MVC, it's best to keep your Views dumb (no logic, simply rendering).
You can accomplish this by using a strongly-typed View and performing all of the logic in the Controller. It looks like you may already be doing this since you have a documentList.
In this case, documentList should be a list of View Model objects that already have the appropriate image path already set on them from the controller.
I would suggest moving the path to your document image into your model. That way you can just display the image from the path in the model and you wouldn't have to put any logic in your view.

Issue migrating MVC3 Application to MVC4: Compiler Error Message: CS1513: } expected

This is a really weird error, I think it may be a razor bug. I'm using VS 2012, MVC4, Framework 4.5.
Following these instructions: http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253806
I created a new MVC4 project and then I copied all my code (controllers, views, viewmodels) to it from the MVC3 project.
Eveything worked just fine, until I tested one View which has a custom helper and inside it it has one foreach, one switch, three if statements and then I call some other custom helpers in there too.
It's exactly the same code in both projects, in MVC3 it works, but in MVC4 it shows this message:
Compiler Error Message: CS1513: } expected
So I tried adding one curly bracket but it shows the same error, so I keep adding brackets and it won't stop telling me the same thing.
I googled this issue but I just found this question with no answer:
http://www.1771.in/asp-net-mvc-4-issues-migrating-mvc3-view-in-vs-2012-rc.html
has anyone experienced this issue?
The Razor parser of MVC4 is different from MVC3.
Razor v3 is having advanced parser features and on the other hand strict parsing compare to MVC3.
You may run into syntax error in view while converting MVC3 to MVC4 if you have not used razor syntaxes in correct manner.
Solution of some common razor code mistakes that are not allowed in Razor v2 are :
--> Avoid using server blocks in views unless there is variable declaration section.
Don’t : #{if(check){body}}
Recommended : #if(check){body}
--> Avoid using # when you are already in server scope.
Don’t : #if(#variable)
Recommended : #if(variable)
Don't : #{int a = #Model.Property }
Recommended : #{int a = Model.Property }
I had exactly the same issue.
In Razor MVC3 i was accessing the vars like this: #vSuggestion but in MVC4 the # is not necessary.
My example, i had this code in MVC3 working:
#{
var vSuggestion = ((dynamic)ViewData["suggestion"]);
}
<!-- more code here -->
#{ int suggestion = #vSuggestion;
switch (suggestion)
{
case Suggestion.INCORRECT_PASSWORD:
case Suggestion.USER_ALREADY_IN_DATABASE:
<span>Trata de iniciar sesión de nuevo</span><br />
<span>Recupera tu contraseña #Html.ActionLink("aquí", "Recover", "Account")</span>
break;
case Suggestion.EMAIL_DONT_EXISTS:
<span>Comprueba que el correo electrónico está bien escrito</span><br />
<span>Registrate (abajo)</span>
break;
}
}
In MVC4, Razor wasn't catching the first curly bracket from the switch statement. So i removed the # from #vSuggestion and razor parsed the code properly.
Hope it helps.
I ran into this "Expected }" issue as well and the culprit turned out to be an apostrophe in an HTML comment This seems like a bug in Razor.
Here is an example on how to reproduce this issue in the default MVC 4 application with VS 2012. Just add the following a comment with an apostrophe to the #section featured {} in the default.cshtml. Remove the apostrophe from the comment and it works OK.
#section featured {
<!-- hello world it's not cool -->
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<p>...</p>
</div>
</section>
}
This may be more of a long shot but sometimes if you are using a keyword it will cause that error
List of Keywords VS 2012
http://msdn.microsoft.com/en-us/library/x53a06bb%28v=vs.110%29.aspx
I know two of the new keywords are await and async for 4.5
See the following for an example of what I am talking about
http://www.wduffy.co.uk/blog/css-class-property-asp-net-mvc-htmlattributes/
Try to add this line in web.config
<compilation debug="true" batch="false">
Now, when getting the error you should be able to open the temporary generated .cs file and take a look at generated code.
Maybe then you will more easily spot the problem.
For details look here Debugging ASP.NET generated code
Most helpful thing to do that will solve 6/10 of these for you is in VS2012
File-> Source Control -> Advanced -> Format this Document.
This will solve any un-closed div's, conditional statements even ul's and li's which cause big errors for .net.
I experienced this error but narrowed it down to a missing slash to close a tag. this worked in MVC3:
#helper metatags()
{
<meta charset="utf-8">
}
but not in MVC4. it requires this:
#helper metatags()
{
<meta charset="utf-8" />
}