I have helpers that return a string that contains helperbars expressions.
What I would like to achieve is that the expressions returned will also be resolved (and so on).
It can be done quite easily without handlebars internal support by simply doing compileInLine on the result until the string returned doesn't change anymore.
Was wondering if there is some kind of configuration or better way to achieve it?
I need to use it in Java but my question applies both for handlebars.js and the jknack/handlebars project.
Map<String, String> model = Map.of("first", "pie", "second", "cake");
Template template = handlebars.compileInline("{{first}} {{second}}!");
System.out.println(template.apply(model));
This should print "pie cake"
Related
The end goal is to render an editor template, for a model property, known only at run time, that will not take it's value from the ViewBag.
Html.Editor will use the ViewBag value if the property names match. I don't want this and I hate this "feature".
I hope that this is possible somehow:
var propName = "MyProperty";
var expression = GiveMeTheExpression();
#Html.EditorFor(expression,"MyEditorTemplate")
If not this then some way of rendering an editor template without the viewbag values being used instead of the model's values. I'm totally fine with doing this, IF I CAN IGNORE THE VIEWBAG VALUES SOMEHOW:
#Html.Editor(propName, other, arguments)
You'll probably have to use Html.Partial with a custom ViewDataDictionary.
object knownAtRuntime = ViewBag.ObjectName; // Adapt to your solution
string templateName = String.Concat("EditorTemplates/", knownAtRuntime.GetType().Name);
#Html.Partial(templateName, knownAtRuntime, new ViewDataDictionary(knownAtRuntime));
Note: I made this example simple to illustrate the core concept but you can of course extend it to read UIHintAttribute etc if you like.
Note 2: You may also want to copy values from Html.ViewData to the new ViewDataDictionary to keep your modelstate etc.
Why not try this ?
#Html.EditorFor(x=>x.SomePropertyName)
Assuming SomePropertyName is the name of a Property of your Model which is strongly typed to your view.
Shyju taking about strongly typed object, if I understand you correctly, you need something like: asp.net mvc 3 and dynamic view generation
My solution was to use the #Html.Editor() method with property name as string and to use ViewBag keys that are very unlikely to be found on the model object.
Not ideal, but should work well.
Does anybody know if it is possible in a compound template to use a string item in the package and execute it as if were a dreamweaver template? And whether you apply the same method to other mediators (like razor)?
Thanks
Mark
I suspect this is not possible.
Package.EvaluateExpression may be useful, but as the name suggests it'll only work on expressions, not large snippets of code with embedded expressions (i.e. TEL)
Engine.GetMediator expects a Template and returns the appropriate Mediator for it. Your problem then is that the IMediator interface only defines the Transform method, which requires an Engine, a Template and a Package.
I can't think of any elegant ways around these. Maybe write your own Mediator, but that would still expect a Package, not a string, so you'd have to first store the string based Item from another TBB.
My advice: Sounds like you need to go back to the drawing board and find an alternative solution to your problem.
I'm afraid that won't be possible on just any item in the Package, since the Engine expects Templates to be based on Tridion items.
If your Template Item is based on a Tridion Item you can probably get pretty far by starting at the Engine.GetMediator method. If it isn't, you'll have to find some way to turn it into a valid Template object.
Template template = ...
IMediator mediator = engine.GetMediator(template);
mediator.Transform(engine, template, package);
When I have to create a Component object from a Tridion-based Item in the Package, I normally do something like this:
Component component = new Component(item.GetAsXmlDocument().DocumentElement,
engine.GetSession);
I haven't tried, but expect that you can do the same for a Template - given that you start with a valid Item from the Package representing a Template to begin with. You can probably clone the XML from an existing Item or find some other way to fake it.
If you get this to work, it will work across all registered template types. The Engine provides no special treatment for the types that come with Tridion.
I am creating some Magnolia templates and would like to know if any one has found a way to create a #cms.newBar and somehow use a node as the list of available paragraphs. The syntax is as below:
[#cms.newBar newLabel="Add Content" paragraph="template1, template2" /]
I want to use the node instead to avoid having to come back and add new templates when they are created.
I have seen the docs here and know that nothing is specified but wanted to see if anyone had found a way?
You can do several things, all boiling down to the same:
configure a string property containing "template1, template2", in your template definition. Assuming you're using Freemarker as the templating language, refer to it with ${def.thatProperty} (def references your template definition)
have your model class return that value: ${model.whatsCooking}, where your model class has a method String getWhatsCooking() which returns "template1, template2" (or whatever else you could come up with that decides what paragraphs should be available
STK does something similar to (1) - its template definitions contains Lists of "available" paragraphs, and its templates use some utility method to turn that into a comma-separated list, use with the new bar, so something like ${stk.toStringList(def.main.paragraphs)} (I can't recall the exact names and semantics, but you get the gist).
You should perhaps consider looking into STK for that, and a whole lot of things.
As for documentation, perhaps the templating guide and other docs will be more useful than the javadoc/tlddoc in this case.
HTH,
I'm trying to make a form where I'm storing values outside of the context. Storing is done and working well but now I would like the update method to fill the form on rendering process. So I'm overriding update method of the Form class that way:
def update(self):
super(ConfigurationForm,self).update()
form = self.request.form
if not form:
#We are on a rendering process
provider = self.getProvider()
settings = provider.get()
#TODO: update widget values !?
settings is a dict where keys are equals to Interface fields's names.
So I have tried many ways to update widgets values:
Using dataconverter (too much complex and don't know if this is the only way
Updating the self.request.form dict and call again the update method
playing with field objects
What is the good way to achieve this ? (supporting all kind of field ?)
Don't do ignoreContext. Override getContent() to return a dict instead. The dict will be used as a pseudo context.
I am using the ASP.NET command
var returnValue = new JsonResult { Data = items.Skip((pageNumber - 1) * pageSize).Take(pageSize) };
return returnValue;
to return the paged contents of a table via JSON, but when I got to try to parse it, in jQuery, the $.each takes each character as an individual element.
The output from that is along the lines of
[{"ItemNumber":1,"Description":"Description1"}, {"ItemNumber":2,"Description":"Description2"}]
listing all the rows and fields correctly. However this doesn't look like correctly formatted JSON to me (I beleive it should be encased in {}), is it?
If not what should I be doing to correctly output the table? If so, how can I loop round each element in jQuery, and extract the field values?
This is correctly formatted JSON.
You could try evaluating it with
var someVar = eval(jsonValue);
but this may lead to XSS.
Or even use this plugin.
This question may be related too.
Actually, using eval might be dangerous: unlike the case when it's enclosed in {}, it's possible to subvert the construction of an array. This occurs when eval tries to create an array using the Array constructor. See this post.
If you're not worried about that, you can use eval - for safety, the JQuery plugin in wtaniguchi's answer.
Can you not loop through like this?
for (i = 0; i <= returnValue.length - 1; i++){
//access your properties like this:
returnValue[i].ItemNumber;
returnValue[i].Description;
}
I don't know if using JsonResult will work like that, but if you return a list of objects in your server side code, it will work like that. Assuming you're using Asp.Net AJAX it will serialize automatically.
As far as I know there exists also the following json deserializer in Asp.net Ajax:
Sys.Serialization.JavaScriptSerializer.deserialize(...)
You'd have to browse for the exact usage since I don't know it by heard now.
I use the AJAX.NET function Sys.Serialization.JavaScriptSerializer.deserialize to get my JSON data when I've created it using System.Web.Script.Serialization.JavaScriptSerializer.Serialize.