views:

6675

answers:

6

I want to use JSTL's fmt tag in javascript to localize my alert messages. My javascript file is a standalone file and when I include fmt tag in js file browser gives javascript errors, is it possible to treat .js file as .jsp file using web.xml configuration? Can anyone please suggest me how can I do that?

+1  A: 

You could do the following. You store the translated message in a variable that can be resolved later on in the JSP.

<fmt:message key="your.alert" var="theAlert"/>

<script type="text/javascript">
alert("${theAlert}");
</script>
Kees de Kooter
This requires that you inline all your javascript. The javascript should really be separated in its own file, for browser caching, easier maintenance, reuse across pages, and to allow compression.
Magnar
Then make the javascript file qualify as JSP by tweaking your default web.xml file. Then the JS file is both, javascript AND JSP. The file extension is simply that, an extension. Use whatever you want. Works great with CSS files as well.
Will Hartung
A: 

You can't use tags in JavaScript but there is a workaround: Put the tag into an hidden DIV (<div style="display: none;" id="msg"><fmt:...>

Now you can use JS to look up the DIV by its ID and get the innerHTML.

That said, fmt is just a wrapper for Java's i18n functions which you can use directly between <% %>.

Aaron Digulla
+1  A: 

You should strive to keep your javascript code in a separate file from the jsp-code. This is to get browser caching, easier maintenance, reuse across pages, and to allow compression.

I suggest that you create a global object for text in the jsp, to be used by your javascript files. Like this:

<script>
    var text = text || {}; // play well with other jsps on the page
    text.this_page_name = {
        required_field_error: "<fmt:message key="required.field.error"/>",
        system_error: "<fmt:message key="system.error"/>"
    };
</script>

Later you use it in your javascript:

alert(text.this_page_name.required_field_error);
Magnar
A: 

If your javascript is 'inline' with the rest of your JSP page, then simply use the technique suggested by Kees de Kooter.

If your javascript needs to be in an external file (For sharing across pages, for example) then simply put it in its own JSP file.

<%@page contentType="text/javascript" %>
<fmt:message key="some.message" var="someMessage"/>"
<fmt:message key="another.message" var="anotherMessage"/>"
var someMessage = "${someMessage}"
var anotherMessage = "${anotherMessage}"/>"

And include it like this...

        <script src="yourScript.jsp" language="JavaScript" type="text/javascript"></script>

You can then refer to 'someMessage' and 'anotherMessage' from within the file that includes the JSP, or from any javascript file that is included after 'yourScript.jsp.

Note the use of the contentType attribute - 'text/javascript' prevents the JSP parser from complaining that the output isn't well formed XML - and that the tage refers to a JSP file.

A combination of this technique and that suggested by @Magner should bring you to a sensible solution.

EDIT: Changed the example to use 'text/javascript' insetad of 'text/plain' - thanks to @bobince for making me realise this error (Even though 'text/plain' works, it's more correct to use 'text/javascript'). Also, if the number of strings that need to be internationalised is small, and/or you can justify having your 'resources' in more than one place - one for the server side stuff and another for the client side stuff - @bobince's technique of using dynamic includes is a good one.

belugabob
+5  A: 

is it possible to treat .js file as .jsp file using web.xml configuration?

Yes:

<servlet>
    <servlet-name>scriptjsp</servlet-name>
    <jsp-file>/script.jsp</jsp-file> 
</servlet>
<servlet-mapping>
    <servlet-name>scriptjsp</servlet-name>
    <url-pattern>/script.js</url-pattern>
</servlet-mapping>

But, there is no actual advantage in doing this, because JavaScript files do not have to have URLs ending in ‘.js’. What determines whether a file is a JavaScript file is what MIME media type it is served as. You can set this from JSP using:

<%@ page contentType="text/javascript" %>

at the top. Then you can link directly to:

<script type="text/javascript" src="/script.jsp"></script>

(Aside: in current browsers, scripts linked to with the <script> tag will work even without having the Content-Type properly set, but that's probably not something to rely on.)

I want to use JSTL's fmt tag in javascript

This is probably not a good idea. The fmt tag deals with HTML-escaping for characters, but what you want is JavaScript string literal escaping, for example to backslash-escape quote characters. JSTL doesn't provide this capability. You'll get unexpectedly-escaped ‘&amp;’ characters showing up in your JavaScript strings, and use of apostrophe or double quote in messages will break the whole script.

Also, serving commonly-included scripts from JSP risks poor performance and cacheing.

I'd suggest an independent language lookup system in JavaScript. For example, include a per-language external script:

<script type="text/javascript" src="/script/lang/en.js"></script>

(changing 'en' to match whichever language you want), and in that file define a lookup like:

var msg= {
    messageName: 'Message in English',
    ...
};

Then look up msg.messageName for each localisable string in the script.

bobince
A: 

I would suggest you write a servlet that generates an array or javascript object that contains all the localized information you desire. You can use Java resource bundles which can be shared by both the client and server sides, then you don't have to intermix JSP code and Javascript code, and the servlet response will be cached by the browser.

Create a servlet, map it to a path, have it read the locale from a request parameter then generate the Javascript code.

Use a line like <script src="/mydict&lang=en"></script> then load you script afterwards <script src="/myscript.js"></script>

BeWarned