Umbraco PartialView Macros and #helper - umbraco

This has been driving me crazy for about 3 hours now. We upgraded from Umbraco 4 to Umbraco 7 and now our site menus are broken. We used to use a script that traversed the nodes and created a CSS menu system.
So I have started reading up on the new stuff and I just can't even get a #helper or #functions block to work. The script is now using a PartialView Macro that uses a parameter called MenuNode that is the Node I want to traverse down.
Here's the code that works:
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#{
var menuNode1 = string.IsNullOrEmpty((string)Model.MacroParameters["MenuNode"])? 0 : Convert.ToInt32(Model.MacroParameters["MenuNode"]);
}
<h1>#menuNode1</h1>
As soon as I try to add a #helper or #functions like in the Navigation PartialView example provided in Umbraco it stops working. Here is what breaks it.
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#{
var menuNode1 = string.IsNullOrEmpty((string)Model.MacroParameters["MenuNode"])? 0 : Convert.ToInt32(Model.MacroParameters["MenuNode"]);
}
#TestHelper(menuNode1)
#helper TestHelper(var testvalue)
{
<h1>#testvalue</h1>
}
Can anyone point me at what I'm doing wrong?

Problem solved. It was because I was using var in the #helper parameter list, changed to dynamic and it worked fine.

Related

How to manually minify a JavascriptResult content before returning it

I have a controller that has a special method to return me a js content uppon some requests params.
Everything is working greatly, I'm simply using a method that returns a JavaScriptResult and I'm rendering a view (that has the whole js content) to a string and returning it.
Now I want to take a step further on that solution. I want that js content to be minified. I've found (on NuGet) a CrockfordJsMinifier class (part of Web Markup Minifier package) that seemed to do the job.
Problem is: It's not a complete minifier, it's only "eating" the extra spaces, line breaks, etc... It is not compressing variable or function names and stuff like that.
Hence my question: Is it possible to use the minification from the "Bundling and Minification" solution from MVC5 on a string? If so, how should I do it?
Here's a brief example of my method just to illustrate:
[AllowAnonymous]
[HttpGet]
public JavaScriptResult GetAnonymousJS(string JSName)
{
//"PartialToString" just renders the view on a string.
string result = PartialToString(PartialView("PublicViewScripts/" + JSName));
var minifier = new CrockfordJsMinifier();
result = minifier.Minify(result, false).MinifiedContent;
//This result is not "really" minified (is just roughly minified)
return JavaScript(result);
}
How about Microsoft Ajax Minifier. It can compress variables and function names as you want. After added the Ajaxmin.dll to your project, you can call the minifier:
public JavaScriptResult GetAnonymousJS(string JSName)
{
//"PartialToString" just renders the view on a string.
string result = PartialToString(PartialView("PublicViewScripts/" + JSName));
var minifier = new Minifier();
result = minifier.MinifyJavaScript(result);
//This result is not "really" minified (is just roughly minified)
return JavaScript(result);
}
http://ajaxmin.codeplex.com/wikipage?title=AjaxMin%20DLL

Umbraco 6.2.0 Render maco inside a razor macroscript

I have the below code which works but is there a better way using the RenderMacroContent method. Not sure how to add parameters to that.
<umbraco:Macro runat="server" language="cshtml">#{
HtmlTextWriter writer = new HtmlTextWriter(this.Output);
var macroPressLogin = new umbraco.presentation.templateControls.Macro();
macroPressLogin.Alias = "Security-PressLogin";
macroPressLogin.Attributes.Add("TargetNode", Parameter.TargetNode);
macroPressLogin.RenderControl(writer); }</umbraco:Macro>
As long as your view inherits from Umbraco.Web.Mvc.UmbracoTemplatePage or Umbraco.Web.Mvc.UmbracoViewPage<YourModel> you should just be able to write something like:
#Umbraco.RenderMacro("MacroAlias", new { ParameterAlias1 = "value1", ParameterAlias2 = "value2" })
So in your case it would be:
#Umbraco.RenderMacro("Security-PressLogin", new { TargetNode = "targetNodeValue" })
If you're talking about calling one macro from within another then this should also work as long as your macro partial view inherits from Umbraco.Web.Macros.PartialViewMacroPage
From your example it looks like you're working with a legacy razor macro using umbraco.MacroEngines. If possible I would recommend upgrading to a partial view macro. Click here for some further info.
I know this question is a year old, but I hope someone finds a use for this information (using Umbraco version 6.x):
#(Html.Raw(umbraco.library.RenderMacroContent("<?UMBRACO_MACRO macroAlias=\"MacroAliasHere\" dynamicParameter=\""+ #dynamicValue + "\" staticParameter=\"staticValue\" ></?UMBRACO_MACRO>", Model.Id)))
Option number 2, which I prefer, is actually code to output a contour form using a value from the form picker datatype:
var helper = new UmbracoHelper(UmbracoContext.Current);
#Html.Raw(helper.RenderMacro("umbracoContour.RazorRenderForm", new { formGuid = #Model.formPickerAlias }))

knockout + partials + mvc + correct way to bind

Dear fellow programmers
I got myself into a pickle. Ive been in to knockout for like 2 weeks now and im afraid i dont understand the basic idea of it. So be gentle with me.
Situation:
I got a master view layout page /Master to make it simple. Here i got 2 column layout.
On the left a listbox with patients, after clicking one, you will see prescriptions added to the listbox below it. pretty simple...
Dont mind the renderbody here, this is faulty. Just use this image to see 2 big parts. The red en and the yellow.
Now i got the Master working pretty well, when i click on a patient i want to load a specific partial view on the yellow part of the screen. The same with clicking a prescription , then i want to load the prescription partial on the yellow part.
I got these 2 editscreens working but without the master included. these pages look like this:
#model FysioNotes.WebMVC.Models.ViewModels.EditPatientViewModel
form + bindings here
#section scripts {
<script src="~/MyScripts/patientVm.js" />
<script>
$(function () {
ko.applyBindings(new editPatientVm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model))));
});
</script>
}
You see that i use razor here to fill in the data in the editPatientVm. the js file looks like this :
var patientVm = function (data) ...
var editPatientVm = function (data) ...
var createPatientVm = function (data) ...
This is the same with the prescriptions .
Now when i try to load the prescription partial into the yellow part of the screen, i try to do it like this. And this is probably very faulty....
-- this is at the bottom of the master view --
<script type="text/javascript">
$(document).ready(function () {
$('#tablePrescriptions').on('click', 'tr', function (event) {
var selectedId = $(this).data("prescriptionid");
// this data gets filled without troubles
$(this).addClass('selectedrow').siblings().removeClass('selectedrow');
openDetail("prescription", selectedId);
});
and then this function
function openDetail(type, selectedId) {
if (debug)
alert(type + " : " + selectedId);
var url = baseurl + "/Prescription/Edit?prescriptionId=" + selectedId;
$("#mainContent").load(url);
//CHECK THIS
ko.cleanNode($("#mainContent")[0]);
$("#mainContent").load(url, function () {
//ko.applyBindings(new viewModel(), $("#mainContent")[0]);
ko.applyBindings(new editPrescriptionVm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(new FysioNotes.WebMVC.Models.ViewModels.EditPrescriptionViewModel(12836)))), document.getElementById("mainContent"));
});
}
like you see , the fixed number 12836 is totally wrong to do it like this. But i wanted to just try if this would work and it did. But apparantly i cant send a js var to razor , because this is impossible.... so this let me to the idea that im doing something completely wrong
the master view has this at the bottom:
<script src="~/MyScripts/patientVm.js"></script>
<script src="~/MyScripts/prescriptionVm.js"></script>
<script>
$(function () {
ko.applyBindings(new masterVm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model))));
})
</script>
I think i need to put the viewmodels that i need in the partial into my viewmodel of the master maybe ? and then send it trough but this will mean that EVERY viewmodel needs to be on the master. This cant be good for initial loading ! And this seems wrong to me to do it like this , but ive been wrong before....
please help :(
#section scripts cannot work in partials views that are retrieved through ajax... you'll have to execute your code between those tags after the code that retrieves the view in the first place. #section scripts is kept into the request items and rendered when the page is rendered. But since this is ajax, the server has long passed the point where it would keep into account scripts defined between this section

JSF 2 doesn't find my method

So I have a view that create pie chart. Th recurring code looks like this.
function drawChart() {
var dataBest = new google.visualization.DataTable();
dataBest.addColumn('string', 'Name');
dataBest.addColumn('number', 'Number');
dataBest.addRows([
<ui:repeat value="#{dashboardController.bestSelling()}" var="sale">
[ '#{sale[0].prodId.prodName}', #{sale[1]}],
</ui:repeat >
]);
var options = {'title':'Best Sold Products', 'width':400,'height':300};
var chart = new google.visualization.PieChart(document.getElementById('test'));
chart.draw(dataBest, options);
}
And in my controller called DashboardController I have:
public String bestSelling() {
List<Sales> bestSelling = saleService.getBestSellingProduct(country,gender,status,income);
return new Gson().toJson(bestSelling);
}
But, when I go on my page, I have the following error:
/faces/all.xhtml #22,83 value="#{dashboardController.bestSelling}": The class 'com...managedbean.DashboardController' does not have the property 'bestSelling'.
I don't understand what I did wrong there.
You're not running the code you think you're running. Look at the error message:
/faces/all.xhtml #22,83 value="#{dashboardController.bestSelling}
It mentions the method without the parentheses. So, you've apparently added it later in, but the webapp project is not properly been saved/cleaned/rebuilt/redeployed/restarted.
Unrelated to the concrete problem, there's many more wrong with this approach (attempting to use <ui:repeat> to iterate over a Java String as #1 thinking mistake), but you'll experience this as soon as you fix the current problem. Hint: JSF is a HTML code generator and JS is part of that HTML.

ASP.NET MVC 4 Dev Preview Razor in Sections Error

Well, I think the ASP.NET MVC team released a pretty significant bug in the developer preview for asp.net mvc 4, or I'm doing something stupid... Here's the issue and steps to reproduce.
Create a new MVC 4 mobile application
create a new section in the layout (ex. #RenderSection("head",false))
in the controller action just throw a Message into the ViewBag
then in a view that uses the main layout, add the following code below.
#section head {
$(function() {
var newVariableName = "#(ViewBag.Message)";
});
}
You'll notice that the razor parser actually thinks that the section has been completed for the jquery on dom loaded ending brace instead of the section's ending brace. I tried the exact same code in an asp.net MVC 3 application and it worked with no issues.
Has anyone else come across this bug in the ASP.NET MVC 4 Developer Preview?
A quick hack to solving this issue is to use < text > blocks < /text > around the java script. Here's what it might look like until the ASP.NET MVC team resolves this bug.
#{
<text>
$(function()
{
var newVariableName = "#(ViewBag.Message)";
});
</text>
}
As mentioned above, try this in your cshtml file...
#section head {
#{
function JSMeth1()
{
// doing your stuff, razor parser wont suck
}
}}

Resources