Reputation: 8394
I need to generate HTML based off some models in an UWP/UAP project - written in C# entirely.
The problem is that no preexisting templating engines (I really wouldn't want to write one from scratch) are compatible with the platform. I looked up a few most popular alternatives, and none would work out of the box.
What would be your suggested solution for this substantive issue I am facing? I thought about porting one of available open-source libraries, but I'm not sure whether it would be worth the effort.
I'm not interested in opinionated answers, or recommendations of templating engines (that don't really work on UAP), only in the easiest route to solve the problem of templating in a Windows 10 universal app.
Upvotes: 2
Views: 219
Reputation: 884
If you are developing, using HTML/JavaScript
, you can use built-in WinJS
library for templating in HTML
. Also Microsoft created a number of adapters for Angular
, React
or Knockout
to use them in UWP
apps.
Usually most of JavaScript
code should just work, the only thing you should take into consideration is security limitations while embedding iframes or external script. To bypass such limitations you should update logic of used library or manually enforce by using the execUnsafeLocalFunction
method.
MSApp.execUnsafeLocalFunction(function() {
var body = document.getElementsByTagName('body')[0];
body.innerHTML = '<div style="color:' + textColor + '">example</div>';
});
== Update:
For C# there are two options:
In the second case it should be quite easy: 1) You should implement a converter from JSON to HTML (with template) using any library of your choose in JavaScript, it should be available for calling from external context (global function or object). Such function should receive data as a JSON-string and return a string (e.g. from innerHTML). 2) Use standard technics with InvokeScriptAsync/ScriptNotify event for the WebView control to transfer data between C# and JS environments. You don't need actually to display WebView inside your page. Just use it as environment for JS execution with access to DOM, required by corresponding libraries.
Here is code sample with WinJS: HTML/JS. template.html file with WinJS library. Global js-function:
function convertFromJSON2HTML(jsonString, templateHTML) {
var templateEl = document.createElement("div");
templateEl.innerHTML = templateHTML;
var jsonData = JSON.parse(jsonString);
if (WinJS != undefined) {
var template = new WinJS.Binding.Template(templateEl);
//promise
template.render(jsonData).done(function(output) {
window.external.notify(output.innerHTML);
});
} else {
// catch error
}
}
C# Code
public async Task<string> GenerateTemplate(string jsonData, string template)
{
var webView = new WebView();
webView.Source = new Uri("ms-appx-web:///HTML/template.html");
webView.DOMContentLoaded += async (o, e) =>
{
await webView.InvokeScriptAsync("convertFromJSON2HTML", new string[] { jsonData, template });
};
string output = "";
// Simple trick to convert event result to async result
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
webView.ScriptNotify += (o, e) =>
{
output = e.Value;
tcs.SetResult(true);
};
await tcs.Task;
return output;
}
Usage. I'm using WinJS-style templates here:
var result = await GenerateTemplate("{\"x\":\"test\"}","<p data-win-bind='textContent:x'></p>");
resultBox.Text = result;
Also to simplify communications I would recommend to use the AddAllowedWebObject method to pass WinRT-objects between two environments instead of just text.
Upvotes: 2