How Can I Internationalize Strings located in Javascript File while Building a Spring MVC WebApp ?
I'm using <spring:message code="label1" /> to Internationalize some static Strings In the JSP Files, but what about error messages located in my js files for example? is there a way to resolve internationalization without including the plain js code in the jsp file ?
I thought about creating a list of values, one for each error, and proceed with ajax calls whenever the page is refreshed, so I can get the right message according the value of the lang variable, but is it wise to do so ?!
Include this piece of code in some common jsp , say header.jsp.
<script type="text/javascript">
function getSystemLocale() {
var systemLocale ='<%=RequestContextUtils.getLocale(request)%>';
return systemLocale;
}
function getResource(){
jQuery.i18n.properties({
name:'JS_Messages',
path: getContextPath()+'/resource-bundles/JS_Messages/',
mode:'both',
language:getSystemLocale(),
callback: function() {
jQuery.i18n.prop('error_message');
}
});
}
</script>
Structure will something as below. It will load all the properties files from the given path and search for the variable based on locale.
Remember the naming convention of file , ending with locale.
Need to include jquery.i18n.properties-min-1.0.9 for the same.
and simply in javascript you can access the key as alert(error_occured);
Related
Freemarker (by default) uses the locale to build the file names it looks for when loading and including templates. For example, loading tos.ftl (the template) with the en_US locale would look for:
tos_en_US.ftl
tos_en.ftl
tos.ftl
This can be useful to translate whole pages when the pages are completely different between different languages. For example, a "Terms of Service" page might be mostly static so different languages would have completely different content. In this case, it is a hassle to externalize the whole content to messages loaded from message bundles.
I am now learning Thymeleaf and can't find any information about a similar functionality. I know that Thymeleaf uses localized message bundles to fill in th:text elements, but can it load localized versions of the template files?
Note: I'm using Spring Boot
I know it's a little bit too late but here is how I would attempt to solve this using the current version of Thymeleaf:
Presuming you have these 2 localised templates under path (from the template root) path/to/template:
localized_template_en.html
localized_template_ru.html
In your SomeController.class:
#GetMapping( "/locale_test" )
public String getLocalisedPage( Model model ) {
return "path/to/template/localized_template_"
+ LocaleContextHolder.getLocale().getLanguage();
}
As a result you will get the correct template given you use Spring localisation features (such as LocaleChangeInterceptor). If not - instead of using LocaleContextHolder implement your custom logic for postfix selection.
Thymeleaf's behaviour the same as Spring 4 MVC Internationalization (I guess you using Thymeleaf with Spring??), it uses messages.properties to realize that.
For example you have a template with #{hello} message:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
</head>
<body>
<span th:text="#{hello}">
</body>
#{hello} text will be binded to the messages.properties proprty hello.
If you locale would be another, e.g. ru_RU you just add messages_ru_RU.properties and change the locale of your application.
After that, your message will be taken from localized properties file.
Note that necessarily to have messages.properties file if you using localized messages file.
I am new to Django but i am advanced programmer in other frameworks.
What i intend to do:
Press a form button, triggering Javascript that fires a Ajax request which is processed by a Django View (creates a file) that return plain simple JSON data (the name of the file) - and that is appended as a link to a DOM-Element named 'downloads'.
What i achieved so far instead:
Press the button, triggering js that fires a ajax request which is process by a Django view (creates a file) that return the whole page appended as a duplicate to the DOM-Element named 'downloads' (instead of simple JSON data).
here is the extracted code from the corresponding Django view:
context = {
'filename': filename
}
data['filename'] = render_to_string(current_app+'/json_download_link.html', context)
return HttpResponse(json.dumps(data), content_type="application/json")
I tried several variants (like https://stackoverflow.com/a/2428119/850547), with and without RequestContext object; different rendering strats.. i am out of ideas now..
It seems to me that there is NO possibility to make ajax requests without using a template in the response.. :-/ (but i hope i am wrong)
But even then: Why is Django return the main template (with full DOM) that i have NOT passed to the context...
I just want JSON data - not more!
I hope my problem is understandable... if you need more informations let me know and i will add them.
EDIT:
for the upcoming questions - json_download_link.html looks like this:
Download
But i don't even want to use that!
corresponding jquery:
$.post(url, form_data)
.done(function(result){
$('#downloads').append(' Download CSV')
})
I don't understand your question. Of course you can make an Ajax request without using a template. If you don't want to use a template, don't use a template. If you just want to return JSON, then do that.
Without having any details of what's going wrong, I would imagine that your Ajax request is not hitting the view you think it is, but is going to the original full-page view. Try adding some logging in the view to see what's going on.
There is no need to return the full template. You can return parts of template and render/append them at the frontend.
A template can be as small as you want. For example this is a template:
name.html
<p>My name is {{name}}</p>
You can return only this template with json.dumps() and append it on the front end.
What is your json_download_link.html?
assuming example.csv is string
data ={}
data['filename'] = u'example.csv'
return HttpResponse(simplejson.dumps(data), content_type="application/json")
Is this what you are looking for?
I am very new to AJAX and I am stuck with a problem. I have a <div> in my JSP. I have another JSP that is included in the above JSP using <jsp:include>. The problem is that the included JSP does DB operations and it takes a lot of time to render. I want the former JSP to be loaded first and then latter JSP to be rendered in the DIV. I searched but couldn't understand how to resolve it. Basically, I want the former JSP to be displayed and then the latter to be displayed once it completes operations. Currently, the former JSP takes lots of time to load as the latter is included in the former JSP and will render only when the latter JSP has completed loading.
Appreciate your help. :)
I believe this is not the correct approach . The DB interaction part should be done by the DAO classes triggered by some Servlet . Using JSP for DB interactions is bad . Having said that your current problem can be solved by the below approach :
Remove all the DB operations from the JSP.
Keep a div inside your main JSP.
On load , trigger an AJAX call to a Servlet.
Servlet/DAO class performs the DB operations and returns back the result. Store the result in session if needed.
Inside the success handler of the AJAX request function , write a call back function which loads the other JSP file.
Check this answer Load a jsp page using AJAX load method.
The popular approach is to use javascript library such as jQuery and invoke the long-running operation using ajax
$.ajax('/longrunningop', {
type: 'POST',
data: 'a=1&b=2'}).done(function(data) {
// code to display data to div here..
});
Good practice is you code the long running operation to return JSON instead of JSP
Question:
What is a clear, safe and systematic way to call my MVC controllers/actions from JavaScript, but keep the related URLs in a central place for updating when controllers change? Or to dynamically generate the URLs at run-time? Or to get compile-time checking for AJAX controller linkage?
Research/Past Attempts:
I've recently plugged in T4MVC to my MVC project. Great! Compile-time checking for controller linkage in my views - but I still have controller URLs littered all over my JavaScript. Worse, I have evolved how I do it over the project lifetime, so I do it multiple ways that I'm still not satisfied with.
1) One way:
locationAutoComplete = new AjaxQueue({
Controller: "Utilities", // null for current controller
Action: "GetMatchingLocations",
DataModel: null, // null for raw JSON, or a local model to populate
MaxQueuedRequests: 0
});
2) Another way:
locationAutoComplete = function (location) {
return $.ajaxPost(resolveUrl("~/Utilities/GetMatchingLocations"));
}
3) Both 1 and 2 above make use of a project root defined in a Master/Layout JavaScript snippet, but still use unchecked URL strings. So now I've started benefiting from T4MVC by simply defining controller strings in my .CSHTML view:
var locationLookupController = #Url.Action(MVC.Utilities.GetMatchingLocations());
4) The SO article ( Ajax call Into MVC Controller- Url Issue ) addresses this a little. It talks about method 3, but also suggests using the AjaxHelper namespace. Since I make heavy use of jQuery AJAX with some pretty customized interactions (e.g. loading results into a local data model, not at a click event but at a timed interval), I don't think it will help me much. Today I don't even include the MS AJAX JavaScript code on any of my pages.
Thanks!
Continue to use T4MVC. Mix it in with a little jQuery and HTML5 data-* attributes. Here's an example:
<div data-location-lookup-url="#Url.Action(MVC.Utilities.GetMatchingLocations())">
...
locationAutoComplete = function (location) {
var url = $('[data-location-lookup-url]').data('location-lookup-url');
return $.ajaxPost(url);
}
I have a CouchDB list function returning the html for the jstree. I am not sure if the url in my HTML form, to invoke the list is correct, since the jstree doesn't render. (with the same html pasted locally, it does). CouchDB is running on localhost.
The location of my list function is standard, "appname/app/lists/myList.js". I have tried several combinations of url, on the lines of "/appname/_design/appname/_list/listname/viewname".
What should be the correct form ?
Thanks.
The format should be as follows:
GET /db/_design/design-doc/_list/list-name/view-name
I copied this directly from the CouchOne Documentation.
OK, since I couldn't find a definite answer for rendering jstree with dynamic data using a CouchDB list, I went the other way and used after.js functionality in evently.
This is for anyone who might find it useful. This is what worked for me,
get the data using data.js
render it as <ul><li/></ul> in mustache.html
in after.js write the function for jstree as shown in the jstree documentation for html_data plugin
(after.js looks like this
function (e) {
$('.mytree').jstree({
"plugins" : [ "themes", "html_data", "checkbox" ]
});
}