I'm using Apache Freemarker as one of the code languages in a HTML editor where users can code a template. Let's say, a user writes this code for a list:
<#list items as item>...</#list>
This is the correct way to create a list in Freemarker. But, when I load the template at a later moment with functions such as $("div").html(TEMPLATECODE), it will be rendered as:
<#list items as item>...<!--#list-->
How's this possible and how can I prevent html from transforming it to comments?
Thanks!
A FreeMarker template is not HTML, but jQuery's .html(string) expects a string that's valid HTML. So if you pass a template to it, such weird things are bound to happen. Only passing in the output of the template makes sense. If you want to show the markup to the user instead, you should use .text(string).
Related
For a f:link show action in my fluid list template i want to pass a javascript variable to the arguments, basically the uid (to pass that specific object to the showAction), but it doesn't work the way i intend to do it. Is there a workaround for this particular problem?
The naked template looks like this:
<f:for each="{termins}" as="termin">
<tr>
<td><f:link.action action="show" arguments="{termin : termin}"> {termin.mitarbeiter}</f:link.action></td>
<td><f:link.action action="show" arguments="{termin : termin}"> {termin.kunde}</f:link.action></td>
</tr>
</f:for>
</table>
You can't - and you also can't (read: never should) generate links to controller actions from JS since it needs to generate a security checksum. Modifying the URL you create will generate a security error. The checksum exists to prevent DDOS so it has good reason.
There are two options:
You can generate all links in advance
You can make a link-generating service that you call with XHR to generate the necessary links from JS.
Only the first one is appropriate to your use case. Especially so since you want to pass UID values which always refer to an object in the database - which means you can easily generate a list of links to all possible detail views, then read/pass that list of links from your JS to select the right one.
The JS is something working after the fluid template. The right order is, your fluid template is parsed into the HTML, and then the browser render the HTML/JS/CSS to you. So, you can not expect to use JS value in your fluid template.
There are 2 possibilities:
1) Instead of a link use a form and transmit it via POST. Set a form field dynamically with JavaScript. That way your variable isn't included in the (cHash-) checksum.
2) Create an AJAX action that accepts your variable as argument. Let it generate a valid link. Use POST to call it with your variable data. Show the link on your page with JavaScript.
I'm working on a project where it has a number of pages. Each page displays 10 rows where the layout that is using for each page is different. Until now I had the html code of each row in a javascript code and based on the page's url I was using the appropriate html code (if statement). The if statement is inside into a loop which is looping based on the number of rows. The results of the rows are coming from an ajax method. Now I want somehow to separate it so it can be more easily for me to maintain it, basically to remove the html code from the javascript and keep each row's html code into a different file.
Note: the Ajax is in a given time, is sending automatically requests to the php file for any new rows.
One solution which I came out is that I can use the php to create a variable with the html code .
Second solution is to create an array of each record with the html code and then pass it to jquery to print it.
Both solutions I don't know if are good solutions and can help me to maintain the project in the future.
You might consider a template library such as handlebars to help with templating. Frameworks such as AngularJS and Ember also excel at solving these kinds of problems.
Your Web Services API should be returning JSON though, not HTML fragments. Let the client build the DOM, and let the server focus on data.
You should return structured data (see JSON for example) to your AJAX request. This way, you can support multiple interfaces (e.g., a website, an application): each interface will get only the data, and will handle the rendering as it needs.
In your example, you ask for data via an AJAX request, your server responds with a JSON-structured response. JQuery reads it and converts it to javascript array thanks to jQuery.getJSON. With your array, you loop through each element and insert html elements into the webpage.
You have two options:
If your HTML templates is not changing frequently, the best way is to define html templates in your HTML structure using some java script template library (eg. Handlebars) and fill it with data from your AJAX (JSON) requests.
If your HTML templates change frequently or depends on some conditions (data) in row, you should create PHP partial views which generate proper html structure already filled with data.
For many rows it is better idea to create whole table server side to reduce requests.
My understanding of drango templates is that everything happens on server side and then it generates an html out of the templates. After, generation, it is just plain text in the html. But for some reason, I am able to use django variables dynamically in javascript.
Here is a javascript example:
$("#smth").append("<li>{{djangoObject.0.id}}</li>");
Even if I put this in an event handler, meaning, it for sure will be called after the html generation, it works just fine.
How and most importantly, WHY does django keep the variable in the client-side?
It's not being used client side, it's just being rendered directly into the Javascript string. So if djangoObject[0].id were 12, for example, the resulting code would look like
$("#smth").append("<li>12</li>");
Which, obviously, would run just fine. It's not dynamic though, and be sure to keep that in mind - it doesn't fetch id at the point of the event happening. It fetches it at template rendering, which happens before the HTML (and embedded Javascript) is sent to the client (your browser).
This code rendered to something like $("#smth").append("<li>123</li>");. Of course this work without any problem after the html generation.
Recently I became interested of the jQuery template engine.
For the ajax call is very performant, because the data exchange is less.
But when I load my application the first time, I use only php and html for print the data, so for use this technic do I have to duplicate the template? One for php html and one for javascript?
How could I resolve this problem?
It is possible to use the same templates on the server side and the client. For example, mustache has implementations in several languages including PHP and Javascript. But generally I find it's easier to stick to one approach.
If you're using jQuery templating to render on the client anyway, why not render in Javascript the first time as well. To avoid needing an extra AJAX call, you can inject your data model into the page as a javascript object and pass that into the template renderer.
Here's an example. The json_encode function should be useful for this.
<script type="text/javascript">
// This line gets generated by your PHP code.
// You'll want to use the JSON methods instead of generating it by hand.
var myModel = { name: 'Fred', surname: 'Bloggs' };
$(document).ready(function() {
// Here you render the template using the data that's
// already in myModel
});
</script>
You could try Distal templating engine.
Your HTML page serves as part of the template.
<div>
Hi, <span data-qtext="user.name">Guest</span>
</div>
When you first load it displays "Hi, Guest" then you run the template and you can substitute for "Guest".
Update: after another day of digging
into this issue, I have found that the
current jQuery template lib provides
no way to do this. this article
describes a good approach.
I would still like to hear of any
additional thoughts on doing this. The
article linked above requires that the
returned string of templates be
inserted into the DOM. Seems as though
leaving the DOM out of this would be
ideal, and less overhead on the
browser. Imagine a large page, with
multiple composite templates that may
not get used. Although, maybe because
the templates are wrapped in a script
tag, there is only a single DOM item per template? Come on, let's
hear some thoughts...
Using jQuery template libs, what's the best way to combine multiple, related, relatively small templates together? Do you need a single <script> tag for each individual template? What about in the case of dynamically pulling these templates via AJAX? Can I combine these templates somehow?
Consider the following:
<script id="movieTemplate" type="text/x-jquery-tmpl">
{{tmpl "#titleTemplate"}}
<tr class="detail"><td>Director: ${Director}</td></tr>
</script>
<script id="titleTemplate" type="text/x-jquery-tmpl">
<tr class="title"><td>${Name}</td></tr>
</script>
Now because these two templates are very closely related (and one depends on the other) it would make sense to consolidate these into a single AJAX call, and get them both at once. I have a few ideas, but I'd like to know if there is common/best way to do this? Currently I pull in a chunk of HTML, and then do a .find() to get the specific peice of HTML for a template... e.g.:
var templatePackage = fancyAjaxCalltoGetTemplates();
"templatePackage" might then look like this:
<div id="templatePkg">
<div id="movieTemplate">
{{tmpl "#titleTemplate"}}
<tr class="detail"><td>Director: ${Director}</td></tr>
</div>
<div id="titleTemplate">
<tr class="title"><td>${Name}</td></tr>
</div>
</div>
I could then do:
var titleTemplate = jQuery.template('titleTemplate', $(templatePackage).find('#titleTemplate') );
and
var movieTemplate = jQuery.template('movieTemplate', $(templatePackage).find('#movieTemplate') );
...let me know what you think... what would you do?
I like the referenced article in your update, except the assumption that you can't cache templates unless you insert them into the DOM. From the jQuery.tmpl documentation,
"To cache the template when using markup that is obtained from a string (rather than from inline markup in the page), use $.template( name, markup ) to create a named template for reuse. See jQuery.template()."
Using this, we can build a javascript template management system that allows us to load as many templates at a time as we need while keeping the DOM clean. On the client, keep a hash of template objects by name. You can use your favorite object based javascript pattern here, but I would think the structure could be like this:
templates[templateName] = {
templateMarkup: markupFromServer,
loadedAt: Date.now(),
compiledTemplateFunction: jQuery.template( templateName, markupFromServer )
}
Then use the templates to generate HTML like this:
templates['unique-name'].compiledTemplateFunction(inputData)
Then, build an unload mechanism to free up memory:
function unload(templateName) {
delete templates[templateName];
delete jquery.template[templateName];
}
Most importantly, you now have a method of storing multiple templates so you can make requests like: $.get('/TemplateManagement/Render', arrayOfTemplateNamesToLoad, loadManyTemplatesSuccess) to load multiple templates at a time. The only thing we need is a controller TemplateManagement that will take an array of template names as an input and return JSON that pairs a template name with its markup. There are a few ways to do this but it seems to me the most convenient is to define partial views for each template. In ASP.NET MVC 3, you can use this technique and RenderPartial to emit each template's markup into a JSON response. You can either name the partial views the same as the templates or map the names in some custom way.
OK, I read the article you reference in this post. As I see it, his way is probably one of the best ways to load up the template page(s). The only thing I don't like is the asynchronous problems that could crop up, esp. if you need to immediately do some templating before the async get returns... plus any binding issues that could happen before it returns something. In several projects I have done I use his "ancient" SSI (server side includes), but I just use something even easier like:
<% Response.WriteFile("this_page_template_file.html"); %>
You could put it anywhere where you'd place a tag. Like he says, just put in only the templates you need, or maybe include two templates: one is a "base" template with commonly-used items and the second one would have the page-specific ones with template references {{tmpl}}.
Is this even close to an answer? ;-)
[First off, great question. I love this topic]
I have no experience with the plugin "jquery-template-libs", but there is a particular lightweight javascript template plugins that are becoming almost a standard and plays very nicely with jQuery, which is probably better suited for the task than JTL, Mustache:
https://github.com/janl/mustache.js
It's got something that's called a "partial" which is essentially a way to include smaller templates within another one. Which sounds like it will help you out a lot.
On top of that there is a library called ICanHaz.js:
http://icanhazjs.com/
ICanHaz essentially extends Mustache to include built in functionality for templates and works incredibly well.
Mustache/ICanHaz allow you to add templates by variable, by a json call or by using tags. The choice is yours.
I know this is an old question but you might want to take a look at Closure-Templates. They provide the kind of functionality you're after with the added advantage of being compiled into JavaScript at compile-time instead of at run-time in each user's browser.
If you do decide to look into using them then I'd suggest using plovr for building them.