1

I understand that Django renders the templates at the server side. The browser receives HTML content, which can then be manipulated using JavaScript.

I have some JavaScript code to manipulate the Django language tag that will be difficult to maintain in its current form, so I am trying to come with a better way to code it, but I cannot think of such a way and need some help.

Here is my code:

The dynamic_language_code is a two letter code ie: en, fr, bg, ru, es, etc.

function dateCalculation(dynamic_language_code) {

    var c = dynamic_language_code;

    //arabic
    if (dynamic_language_code == 'ar'){

        var_month = "{% language 'ar' %}{% trans 'month' %}{% endlanguage %}";
        var_months = "{% language 'ar' %}{% trans 'months' %}{% endlanguage %}";
        var_year = "{% language 'ar' %}{% trans 'year' %}{% endlanguage %}";
        var_years = "{% language 'ar' %}{% trans 'years' %}{% endlanguage %}";

    //bulgarian.  
    } else if (dynamic_language_code == 'bg'){

        var_month = "{% language 'bg' %}{% trans 'month' %}{% endlanguage %}";
        var_months = "{% language 'bg' %}{% trans 'months' %}{% endlanguage %}";
        var_year = "{% language 'bg' %}{% trans 'year' %}{% endlanguage %}";
        var_years = "{% language 'bg' %}{% trans 'years' %}{% endlanguage %}";

    } 
    ........
    many more else if conditions
    ........
    //default value of English.  
    } else {

        var_month = "{% language 'en' %}{% trans 'month' %}{% endlanguage %}";
        var_months = "{% language 'en' %}{% trans 'months' %}{% endlanguage %}";
        var_year = "{% language 'en' %}{% trans 'year' %}{% endlanguage %}";
        var_years = "{% language 'en' %}{% trans 'years' %}{% endlanguage %}";

    } 
}

The code should dynamically change the language of the month, years according to the passed in dynamic_language_code value. There really should be no need for an if else statement, just the assignment of the var_month, var_months, var_year and var_years values using the passed in dynamic_language_code value.

How do I structure the code above to get rid of the if else condition and still return the correct language versions using the passed in dynamic_language_code?

EDIT

I want to get rid of the if else conditions and just assign the variables to the language code using the dynamic language tag. Not sure how I can do this or even if this can be done. For example:

var_month = "{% language dynamic_language_code %}{% trans 'month' %}{% endlanguage %}";
var_months = "{% language dynamic_language_code %}{% trans 'months' %}{% endlanguage %}";
var_year = "{% language dynamic_language_code %}{% trans 'year' %}{% endlanguage %}";
var_years = "{% language dynamic_language_code %}{% trans 'years' %}{% endlanguage %}";
user3354539
  • 1,245
  • 5
  • 21
  • 40
  • Is there any reason you must use JS to translate individual text? I think a good design is to leave the actual translation work to template system, while JS or server views only decide which language to use. For example, after user switch language, you can refresh page and send preferred language to server via request header. The server only renders translated text of preferred language. This [thread](http://stackoverflow.com/questions/2336785/set-language-within-a-django-view) talks about switch language in Django side. – ZZY Nov 04 '14 at 08:19
  • ZZY, I am using JavaScript to avoid a page refresh. I definately don't want a page refresh. The JS is used to display the timspan dynamically, before the data is sent to the database. – user3354539 Nov 04 '14 at 08:26

3 Answers3

2

Short answer is you cannot do that.

Because of the client side / server side relationship.

Try using an include to your project, that way the code is called multiple times, but you have only one reference of the code in your project.

Hope that helps you.

user4307426
  • 246
  • 2
  • 3
  • 9
  • actually it is not true, I was able to achieve his goal by the instructions I described below, but I doubt he even took the effort to try that. – andrean Dec 27 '14 at 07:11
0

To avoid page refreshing, you can put translations in a JSON file, such as {"en":{"month":"xxx","months":"xxx"}, "ar":{}}. Use AJAX to get the file on the fly. Or put translations in a dedicated JS file. Or checkout the Django doc https://docs.djangoproject.com/en/dev/topics/i18n/translation/#internationalization-in-javascript-code.

ZZY
  • 3,689
  • 19
  • 22
  • ZZY, this will still present me with code that will be difficult to maintain. If I add languages to my project, I will have to also add to your suggested code. – user3354539 Nov 04 '14 at 22:14
-1

To simplify the javascript code, you could do simple string replacement, something like:

function dateCalculation(dynamic_language_code) {
    var lang = dynamic_language_code || 'en';  //handle default case
    var_month = "{% language '<<lang>>' %}{% trans 'month' %}{% endlanguage %}".replace("<<lang>>", lang);
    var_months = "{% language '<<lang>>' %}{% trans 'months' %}{% endlanguage %}".replace("<<lang>>", lang);
    var_year = "{% language '<<lang>>' %}{% trans 'year' %}{% endlanguage %}".replace("<<lang>>", lang);
    var_years = "{% language '<<lang>>' %}{% trans 'years' %}{% endlanguage %}".replace("<<lang>>", lang);
}

But a better question is, how do you expect this to work? Javascript is executed inside the users browser, while the Django template engine is processing those tags on the server side. So by the time your HTML arrives in your browser, all your template syntax is already replaced with the appropriate content, and whatever additional tags you insert with javascript will be treated just as regular strings.

EDIT: Updated code to handle the default english case.

EDIT2: All right, I think I got it, I didn't understand how you intended it to work, so here it is:

  1. I guess you already have in your settings.py this tuple, if not add it:

    LANGUAGES = (
        ('en', 'English'),
        ('de', 'German'),
        ('es', 'Spanish'),
        ...
        ...
    )
    
  2. make sure your MIDDLEWARE_CLASSES include 'django.middleware.locale.LocaleMiddleware'

  3. Render your templates with a function that will pass the RequestContext into your template context, for instance django.shortcuts.render will do the job surely.

  4. Here is a sample template I used to demonstrate how it works:

    {% load i18n %}
    <html>
        <head></head>
        <body>
            <script type="text/javascript">
            var languages = {% templatetag openbrace %}{% for lang in LANGUAGES %}
                "{{ lang.0 }}": {% templatetag openbrace %}
                    "month": "{% language lang.0 %}{% trans 'month' %}{% endlanguage %}",
                    "months": "{% language lang.0 %}{% trans 'months' %}{% endlanguage %}",
                    "year": "{% language lang.0 %}{% trans 'year' %}{% endlanguage %}",
                    "years": "{% language lang.0 %}{% trans 'years' %}{% endlanguage %}",
                {% templatetag closebrace %}{% if not forloop.last %},{% endif %}
            {% endfor %}{% templatetag closebrace %};
    
            function dateCalculation(dynamic_language_code) {
                var_month = languages[dynamic_language_code].month;
                var_months = languages[dynamic_language_code].months;
                var_year = languages[dynamic_language_code].year;
                var_years = languages[dynamic_language_code].years;
                console.log(var_month);
                console.log(var_months);
                console.log(var_year);
                console.log(var_years);
            }
            dateCalculation('en');
            </script>
        </body>
    </html>
    

What happens here is that on the server-side, we prepopulate a javascript object with the available language codes as keys, and another object as it's value, which includes 4 subkeys in it: month, months, year and years. Each of these keys will contain the already translated words for them, so we just do a lookup inside the object, and get the output. This is the rendered HTML output from it:

    <html>
        <head></head>
        <body>
            <script type="text/javascript">
            var languages = {
                "en": {
                    "month": "month",
                    "months": "months",
                    "year": "year",
                    "years": "years",
                },

                "de": {
                    "month": "Monat",
                    "months": "Monate",
                    "year": "Jahr",
                    "years": "Jahre",
                },

                "es": {
                    "month": "mes",
                    "months": "meses",
                    "year": "año",
                    "years": "años",
                }               
            };

            function dateCalculation(dynamic_language_code) {
                var_month = languages[dynamic_language_code].month;
                var_months = languages[dynamic_language_code].months;
                var_year = languages[dynamic_language_code].year;
                var_years = languages[dynamic_language_code].years;
                console.log(var_month);
                console.log(var_months);
                console.log(var_year);
                console.log(var_years);
            }
            dateCalculation('es');
            </script>
        </body>
    </html>

And in my Javascript console, I got this output (because I invoked manually dateCalculation('es') ):

mes
meses
año
años
andrean
  • 6,717
  • 2
  • 36
  • 43
  • I think user3354539 embedded the js codes in a html. His server render translations of all languages in the codes. Then in client side, the js function chooses which text to use – ZZY Nov 04 '14 at 08:22
  • andrean, I could not get this replace code to work! The example javascript I provided in the question does work and is triggered to display the date timespan in the changed language dynamically. But I need to have the code more maintanable than it currently is. – user3354539 Nov 04 '14 at 08:24
  • @user3354539: I tested the code, as it is pasted here, when I `console.log` the variables, I get the correct output. Check if you copied it correctly, or if you modified it additionally, make sure you didn't introduce some other issue. – andrean Nov 04 '14 at 08:43
  • @user3354539 it's possible that the default when no language code is provided is the one with which you tested, I updated the code now to handle that case as well. – andrean Nov 04 '14 at 08:48
  • andrean, this code does not work. I have test it several different ways. – user3354539 Nov 04 '14 at 21:17
  • @user3354539 could you show me the output what you get? put a console.log line after the last `var_years` assignment, like: `console.log(var_years)` and please copy the output from Firebug or the developer toolbar,or whatever tool you use for debugging. – andrean Nov 05 '14 at 05:54
  • andrean, the django language tag is not translated. It just reverts to the default language version of en - English. I have removed the if else conditions and just assigned the variables There is no error per se, just the django language tag does not interact with the js replace and reverst to the english translation. – user3354539 Nov 05 '14 at 21:36