首页 > 解决方案 > 使用 JS 为使用 jquery 验证插件的多语言 django 应用程序有条件地加载脚本

问题描述

我有一个 Django 表单,我在其中使用 Jquery Validation Plugin 进行验证。我的表单需要以多种语言显示,并且我允许用户通过单击按钮来更改表单语言(每种可能的语言一个按钮)。每种语言都有一个单独的脚本要加载,以允许内置验证消息以该语言显示。例如,如果我希望这个插件的默认验证消息是俄语的,我会加载"https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_ru.min.js"脚本。

我的问题如下:

  1. 我真的应该像下面那样将新脚本附加到标题部分吗?然后,如果用户在语言按钮上来回单击,我的 DOM 中将会有一堆完全不必要的脚本,它们会被最后加载的脚本覆盖。这有问题吗?画风不好?有一个更好的方法吗?
  2. 如果他们单击“英语”按钮,我不确定该怎么做,因为在这种情况下,我必须摆脱所有其他语言脚本,使其默认为英语。有没有一种简单的方法可以做到这一点?我想过遍历 header 的所有孩子并取出所有最后一个,直到我回到引导程序(这是我在这些脚本之前的最后一个),但是如果我或其他人选择添加另一个脚本到头了,这段代码会乱的……

也许有一些方法可以在标题中为这些脚本保留一个特定的空间,我可以根据用户单击的按钮替换或删除该空间中的内容?

  1. 有没有办法在脚本源中使用变量?除了指定语言的两个字母之外,它们都完全相同,所以我觉得我的代码非常多余。
  2. 我也不确定如何将已单击的元素传递给我的 ChangeValidationLanguage 方法。

到目前为止,为了根据按钮单击加载正确的脚本,我所拥有的 js 代码是这样的:

window.onload = function() {
document.getElementsByClassName('btn-outline-secondary').setAttribute('onclick', "ChangeValidationLanguage()");
};

function ChangeValidationLanguage(element) {
         var head = document.getElementsByTagName('head')[0];
         var js = document.createElement("script");

         js.type = "text/javascript";
        if (element.id === '#form_ru') {
            js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_ru.min.js";
        }
        else if (element.id === '#form_fr'){
            js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_fr.min.js";
        }
        else if (element.id === '#form_es'){
            js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_es.min.js";
        }
        else if (element.id === '#form_he'){
            js.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_he.min.js";
        }
        // else{ //if (element.id === '#form_en')
        //     js.src = ""
        // }

        head.appendChild(js);


     }

我在 html 中的按钮如下所示:

    <div class="language-buttons">       
          <form action="/i18n/setlang/" method="post" id="form_en" style="display:inline!important;">
          <input type="hidden" name="csrfmiddlewaretoken" value="...">
            <input name="next" type="hidden" value="" />
            <input name="language" type="hidden" value="en" />
          </form>
          <a><button class="btn-outline-secondary" type="submit" form="form_en" value="Submit">English </button></a>

          <form action="/i18n/setlang/" method="post" id="form_ru" style="display:inline!important;">
          <input type="hidden" name="csrfmiddlewaretoken" value="...">
            <input name="next" type="hidden" value="" />
            <input name="language" type="hidden" value="ru" />
          </form>
          <a><button class="btn-outline-secondary" type="submit" form="form_ru" value="Submit">Русский </button></a>

          <form action="/i18n/setlang/" method="post" id="form_fr" style="display:inline!important;">
          <input type="hidden" name="csrfmiddlewaretoken" value="...">
            <input name="next" type="hidden" value="" />
            <input name="language" type="hidden" value="fr" />
          </form>
          <a><button class="btn-outline-secondary" type="submit" form="form_fr" value="Submit">français </button></a>

          <form action="/i18n/setlang/" method="post" id="form_es" style="display:inline!important;">
          <input type="hidden" name="csrfmiddlewaretoken" value="...">
            <input name="next" type="hidden" value="" />
            <input name="language" type="hidden" value="es" />
          </form>
          <a><button class="btn-outline-secondary" type="submit" form="form_es" value="Submit">español </button></a>

          <form action="/i18n/setlang/" method="post" id="form_he" style="display:inline!important;">
          <input type="hidden" name="csrfmiddlewaretoken" value="...">
            <input name="next" type="hidden" value="" />
            <input name="language" type="hidden" value="he" />
          </form>
          <a><button class="btn-outline-secondary" type="submit" form="form_he" value="Submit">עברית </button></a>

    </div>

谢谢!

标签: javascriptdjangomultilingualdjango-multilingual

解决方案


好的。我没有使用 Javascript(因为上面的 Sparky 建议不要使用它),而是执行了以下操作:

第 1 步:在我的 views.py 中,我创建了一个函数来根据给定的语言代码返回正确的语言脚本:

def getLangScript(language_code='en'):
    if language_code == 'ru':
        lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_ru.min.js"
    elif language_code == 'fr':
        lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_fr.min.js"
    elif language_code == 'es':
        lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_es.min.js"
    elif language_code == 'he':
        lang_script = "https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/localization/messages_he.min.js"
    else:
        lang_script = ""
    return lang_script

第 2 步:我更改了视图以接受语言代码作为参数,如果未传递任何参数,则默认使用英语。我调用上面的函数来获取正确的脚本,然后将该脚本传递到上下文中,这样我就可以在我的模板中访问它:

def post_list(request, language_code='en'):
.
.
.
lang_script = getLangScript(language_code)
return render(request, 'template.html', {'form': form, 'lang_script': lang_script})

第 3 步:我在 urls.py 中更改了路径以接受 url 参数,该参数将是语言代码(即英语的“en”):

urlpatterns = [
    .
    .
    .

    path('test/<str:language_code>/', views.post_list, name='post_list'),
]

第 4 步:在我的模板中,我添加<script src="{{ lang_script }}"></script>了我希望加载脚本的位置,这将导致我的验证以不同的语言显示(我可以从我的上下文中访问它)。

第 5 步:(这是令人兴奋的部分!)在名为“next”的输入元素中,我通过 language.code 参数传入了我希望它重定向到的 url。根据将传递给视图的这个参数,视图将调用我的 getLangScript 函数,确定要加载的脚本,然后将该脚本作为上下文变量传递给模板。见下文。

<div class="language-buttons">
        {% get_current_language as LANGUAGE_CODE %}
        {% get_available_languages as LANGUAGES %}
        {% get_language_info_list for LANGUAGES as languages %}
        {% for language in languages %}
          <form action="{% url 'set_language' %}" method="post" id="form_{{ language.code }}" style="display:inline!important;">
          {% csrf_token %}
            <input name="next" type="hidden" value="{% url 'post_list' language.code%}" />
            <input name="language" type="hidden" value="{{ language.code }}" />
          </form>
          <a><button class="btn-outline-secondary" type="submit" form="form_{{ language.code }}" value="Submit">{{ language.name_local}} </button></a>
        {% endfor %}
    </div>

这样,当用户单击按钮时,正确的脚本将被加载到 DOM 中,并且来自 jquery 语言插件的验证消息将以正确的语言显示!

如果有人对这是否是明智的做法或是否有更好的方法有进一步的评论,我会很感兴趣。


推荐阅读