【问题标题】:Loading Scripts Conditionally with JS for multilingual django app that uses jquery validation plugin使用 JS 为使用 jquery 验证插件的多语言 django 应用程序有条件地加载脚本
【发布时间】:2020-02-25 11:47:51
【问题描述】:

我有一个 Django 表单,我在其中使用 Jquery 验证插件进行验证。我的表单需要以多种语言显示,并且我允许用户通过单击按钮来更改表单语言(每种可能的语言一个按钮)。每种语言都有一个单独的脚本要加载,以允许内置验证消息以该语言显示。例如,如果我希望此插件的默认验证消息为俄语,我将加载 "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>

谢谢!

【问题讨论】:

  • 在服务器端框架中工作时,为什么要使用 JavaScript 来交换脚本?只需为所选语言动态撰写页面。当您可以完全控制该页面的构建方式和发送到浏览器的方式时,我认为加载所有不需要的脚本是没有意义的。我正在删除 jQuery Validate 标记,因为问题是关于将脚本加载到页面上,而不是关于插件的正确使用。
  • 好的。你能给我一些关于如何做到这一点的提示吗?我不确定“为所选语言动态撰写页面”是什么意思。
  • 这就是服务器端框架的重点。在这种情况下我不能更具体,因为我不是 Django 专家。

标签: javascript django multilingual django-multilingual


【解决方案1】:

好的。我没有使用 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 步: 在我的模板中,我添加了 &lt;script src="{{ lang_script }}"&gt;&lt;/script&gt; 我希望加载脚本的位置,这将导致我的验证以不同的语言显示(我可以从我的上下文中访问它)。

第 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 语言插件的验证消息将以正确的语言显示!!

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2012-04-30
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2013-01-23
    相关资源
    最近更新 更多