Opened 17 years ago

Closed 12 years ago

#5493 closed New feature (fixed)

make-messages.py not parses JS *.html templates for domain djangojs

Reported by: Manuel Saelices Owned by: nobody
Component: Internationalization Version: 1.4
Severity: Normal Keywords: javascript tools feature_request
Cc: Artem Skoretskiy Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When you do translations in javascripts and creates you want to create .po catalogs with:

  make-messages.py -d djangojs -l es

make-messages.py only parse *.js files but not code inside templates like this:

 <h1><script type="text/javascript">document.write(gettext('this is to be translated'));<script></h1>

Change History (9)

comment:1 by damien_szczyt, 17 years ago

I think you should place HTML code and JS code in different files. Your HTML page will be smaller, and your application will load faster.
I don't think this is a bug to resolve.

comment:2 by Philippe Raoult, 17 years ago

Keywords: feature_request added

comment:3 by Julian Bez, 17 years ago

Triage Stage: UnreviewedDesign decision needed

comment:4 by James Bennett, 17 years ago

I'd be -1 on parsing strings out of JS hard-coded in HTML, because it goes against best practices for application development.

comment:5 by Malcolm Tredinnick, 17 years ago

Component: ToolsInternationalization

comment:6 by Jacob, 17 years ago

Resolution: fixed
Status: newclosed
Triage Stage: Design decision neededAccepted

comment:7 by Artem Skoretskiy, 12 years ago

Cc: Artem Skoretskiy added
Easy pickings: unset
Has patch: set
Resolution: fixed
Severity: Normal
Status: closedreopened
Summary: make-messages.py not parses templates *.html for domain djangojsmake-messages.py not parses JS *.html templates for domain djangojs
Triage Stage: AcceptedUnreviewed
Type: Bug
UI/UX: unset
Version: master1.4

In 2012 it becomes very popular to use template engine right inside JS. That brings developers to need of translations for those templates.

Imagine this app:

index.js:

var objects = [];
$.ajax("/static/index.html", function(template){
    $('body').append(Template().render({"list": objects}));
});

index.html:

<%= ngettext("Show your photo", "Show all your photos", list.length) %>
<ul>
<% for obj in list %>
<li><%= obj.name %><a href="<%= obj.url %>"><img src="/media/images/graphics/1.png" /><%= gettext("See them all") %></a></li>
<% end %>
</ul>

But when you try to generate translations:

./manage.py makemessages -l de -e html -d djangojs

You would find that this index.html is being parsed by Django and terribly broken by prepare_js_for_gettext (as file is almost HTML).

Even if you try to use django domain -- it is broken by django.utils.translation.templatize.

My proposal is for djangojs domain to try to parse file only its extension is .js. Otherwise try to use original file. xgettext seems to be smart enough to find translations in given template.

Here is the patch that does the stuff:

diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py
--- a/django/core/management/commands/makemessages.py
+++ b/django/core/management/commands/makemessages.py
@@ -165,7 +165,8 @@
         is_templatized = True
         orig_file = os.path.join(dirpath, file)
         src_data = open(orig_file).read()
-        src_data = prepare_js_for_gettext(src_data)
+        if file_ext == ".js":
+            src_data = prepare_js_for_gettext(src_data)
         thefile = '%s.c' % file
         work_file = os.path.join(dirpath, thefile)
         f = open(work_file, "w")

comment:8 by Artem Skoretskiy, 12 years ago

Has patch: unset
Type: BugNew feature

It was a good start, but we need something more sophisticated as xgettext breaks in some cases on EJS files..

We need a way to provide a way to use custom pre-processors for makemessages for each of extensions.

In this case I would be able to simply attach needed parser to my file extension (e.g. .ejs) and do any needed logic there.

Something like this:

# in settings.py
GETTEXT_PROCESSORS = {
'.ejs': 'mysite.gettext_processors.ejs'
}

# in django/core/management/commands/makemessages.py
processor = django.conf.settings.GETTEXT_PROCESSORS.get(file_ext, default_processor)
src_data = processor(src_data)

It seems to be quite straightforward change that would break nothing but add a way to customize it.

Any better ideas how to allow using custom processors are welcome.

comment:9 by Aymeric Augustin, 12 years ago

Resolution: fixed
Status: reopenedclosed

To keep the tracker readable, please don't reopen five-year old bugs, especially to request tangentially related new features.

Per the contributing guide, the recommended way to request new features is to propose them on the mailing list and see if the idea gets traction. If it does, please open a new ticket with your proposal (and a link to the discussion). Thanks!

PS: relying on "xgettext seems to be smart enough" hasn't served us very well in the past. We used a 99%-correct approximation (or maybe 95%, or 80%, who knows) until Ned Batchelder bit the bullet and wrote a Javascript parser, which we're now using. If you want to parse JS in Django you really have to use it.

Note: See TracTickets for help on using tickets.
Back to Top