mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
* Fixed several literals
* Added config type field for "choices" * removed old version snippets
This commit is contained in:
parent
3a1bd1eed3
commit
4fb863cfa7
@ -60,7 +60,8 @@ class Config(Handler):
|
||||
'value': cfg.get(),
|
||||
'crypt': cfg.isCrypted(),
|
||||
'longText': cfg.isLongText(),
|
||||
'type': cfg.getType()
|
||||
'type': cfg.getType(),
|
||||
'params': cfg.getParams()
|
||||
}
|
||||
logger.debug('Configuration: {0}'.format(res))
|
||||
return res
|
||||
|
@ -47,6 +47,8 @@ CLUSTER_SECTION = 'Cluster'
|
||||
saveLater = []
|
||||
getLater = []
|
||||
|
||||
# For custom params (for choices mainly)
|
||||
configParams = {}
|
||||
|
||||
class Config(object):
|
||||
'''
|
||||
@ -58,10 +60,13 @@ class Config(object):
|
||||
LONGTEXT_FIELD = 1
|
||||
NUMERIC_FIELD = 2
|
||||
BOOLEAN_FIELD = 3
|
||||
CHOICE_FIELD = 4 # Choice fields must set its parameters on global "configParams" (better by calling ".setParams" method)
|
||||
|
||||
class _Value(object):
|
||||
def __init__(self, section, key, default='', crypt=False, longText=False, **kwargs):
|
||||
logger.debug('Var: {} {} KWARGS: {}'.format(section, key, kwargs))
|
||||
self._type = kwargs.get('type', -1)
|
||||
|
||||
self._section = section
|
||||
self._key = key
|
||||
self._crypt = crypt
|
||||
@ -90,7 +95,7 @@ class Config(object):
|
||||
self._data = readed.value
|
||||
self._crypt = [self._crypt, True][readed.crypt] # True has "higher" precedende than False
|
||||
self._longText = readed.long
|
||||
if readed.field_type == -1 and self._type != -1:
|
||||
if self._type != -1: # readed.field_type == -1 and
|
||||
readed.field_type = self._type
|
||||
readed.save()
|
||||
self._type = readed.field_type
|
||||
@ -106,6 +111,9 @@ class Config(object):
|
||||
else:
|
||||
return self._data
|
||||
|
||||
def setParams(self, params):
|
||||
configParams[self._section.name() + self._key] = params
|
||||
|
||||
def getInt(self, force=False):
|
||||
try:
|
||||
return int(self.get(force))
|
||||
@ -137,6 +145,9 @@ class Config(object):
|
||||
def getType(self):
|
||||
return self._type
|
||||
|
||||
def getParams(self):
|
||||
return configParams.get(self._section.name() + self._key, None)
|
||||
|
||||
def set(self, value):
|
||||
if GlobalConfig.initDone is False:
|
||||
saveLater.append((self, value))
|
||||
@ -298,7 +309,7 @@ class GlobalConfig(object):
|
||||
CLUSTER_ELEGIBLE_MEMORYLOAD = Config.section(CLUSTER_SECTION).value('Migration Free Memory', '40', type=Config.NUMERIC_FIELD)
|
||||
|
||||
# Gui vars
|
||||
UDS_THEME = Config.section(GLOBAL_SECTION).value('UDS Theme', 'html5', type=Config.TEXT_FIELD)
|
||||
UDS_THEME = Config.section(GLOBAL_SECTION).value('UDS Theme', 'html5', type=Config.CHOICE_FIELD)
|
||||
RELOAD_TIME = Config.section(GLOBAL_SECTION).value('Page reload Time', '300', type=Config.NUMERIC_FIELD)
|
||||
|
||||
# This is used so templates can change "styles" from admin interface
|
||||
@ -306,6 +317,20 @@ class GlobalConfig(object):
|
||||
|
||||
initDone = False
|
||||
|
||||
@staticmethod
|
||||
def initThemes():
|
||||
import os
|
||||
themes = []
|
||||
try:
|
||||
for d in os.listdir(os.path.join(os.path.dirname(uds.__file__), 'templates', 'uds')):
|
||||
if d != 'admin':
|
||||
themes.append(d)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
GlobalConfig.UDS_THEME.setParams(themes)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def initialize():
|
||||
if GlobalConfig.initDone is False:
|
||||
@ -326,6 +351,13 @@ class GlobalConfig(object):
|
||||
logger.debug('Saving delayed value: {}'.format(c))
|
||||
c.set(v)
|
||||
saveLater[:] = []
|
||||
|
||||
# Process some global config parameters
|
||||
# GlobalConfig.UDS_THEME.setParams(['html5', 'semantic'])
|
||||
|
||||
# Search for themes & set them
|
||||
GlobalConfig.initThemes()
|
||||
|
||||
except Exception:
|
||||
logger.debug('Config table do not exists!!!, maybe we are installing? :-)')
|
||||
|
||||
|
@ -39,7 +39,7 @@ from uds.models import User
|
||||
import threading
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-04-22'
|
||||
__updated__ = '2016-04-25'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -89,7 +89,7 @@ class GlobalRequestMiddleware(object):
|
||||
'''
|
||||
Obtains the IP of a Django Request, even behind a proxy
|
||||
|
||||
Returns the obtained IP, that is always be a valid ip address.
|
||||
Returns the obtained IP, that always will be a valid ip address.
|
||||
'''
|
||||
behind_proxy = GlobalConfig.BEHIND_PROXY.getBool(False)
|
||||
try:
|
||||
|
@ -45,7 +45,7 @@ from .client import oVirtClient
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-04-18'
|
||||
__updated__ = '2016-04-25'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -97,7 +97,7 @@ class Provider(ServiceProvider):
|
||||
username = gui.TextField(length=32, label=_('Username'), order=3, tooltip=_('User with valid privileges on oVirt, (use "user@domain" form)'), required=True, defvalue='admin@internal')
|
||||
password = gui.PasswordField(lenth=32, label=_('Password'), order=4, tooltip=_('Password of the user of oVirt'), required=True)
|
||||
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently creating VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxRemovingServices = gui.NumericField(length=3, label=_('Removal concurrency'), defvalue='5', minValue=1, maxValue=65536, order=51, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
||||
timeout = gui.NumericField(length=3, label=_('Timeout'), defvalue='10', order=90, tooltip=_('Timeout in seconds of connection to oVirt'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
@ -50,7 +50,7 @@ import six
|
||||
# Python bindings for OpenNebula
|
||||
import oca
|
||||
|
||||
__updated__ = '2016-04-18'
|
||||
__updated__ = '2016-04-25'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -101,7 +101,7 @@ class Provider(ServiceProvider):
|
||||
username = gui.TextField(length=32, label=_('Username'), order=4, tooltip=_('User with valid privileges on OpenNebula'), required=True, defvalue='oneadmin')
|
||||
password = gui.PasswordField(lenth=32, label=_('Password'), order=5, tooltip=_('Password of the user of OpenNebula'), required=True)
|
||||
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently creating VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxRemovingServices = gui.NumericField(length=3, label=_('Removal concurrency'), defvalue='5', minValue=1, maxValue=65536, order=51, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
||||
timeout = gui.NumericField(length=3, label=_('Timeout'), defvalue='10', order=90, tooltip=_('Timeout in seconds of connection to OpenNebula'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
@ -44,7 +44,7 @@ from . import openStack
|
||||
|
||||
import logging
|
||||
|
||||
__updated__ = '2016-04-18'
|
||||
__updated__ = '2016-04-25'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -105,7 +105,7 @@ class Provider(ServiceProvider):
|
||||
username = gui.TextField(length=64, label=_('Username'), order=9, tooltip=_('User with valid privileges on OpenStack'), required=True, defvalue='admin')
|
||||
password = gui.PasswordField(lenth=32, label=_('Password'), order=10, tooltip=_('Password of the user of OpenStack'), required=True)
|
||||
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently creating VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxRemovingServices = gui.NumericField(length=3, label=_('Removal concurrency'), defvalue='5', minValue=1, maxValue=65536, order=51, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
||||
timeout = gui.NumericField(length=3, label=_('Timeout'), defvalue='10', minValue=1, maxValue=128, order=99, tooltip=_('Timeout in seconds of connection to OpenStack'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
@ -48,7 +48,7 @@ class IPMachinesService(services.Service):
|
||||
ipList = gui.EditableList(label=_('List of IPS'))
|
||||
|
||||
# Description of service
|
||||
typeName = _('Physical machines accessed by ip')
|
||||
typeName = _('Static IP machines service')
|
||||
typeType = 'IPMachinesService'
|
||||
typeDescription = _('This service provides access to POWERED-ON Machines by ip')
|
||||
iconFile = 'machine.png'
|
||||
|
@ -40,9 +40,9 @@ class PhysicalMachinesProvider(services.ServiceProvider):
|
||||
|
||||
# What services do we offer?
|
||||
offers = []
|
||||
typeName = 'Physical Machines Provider'
|
||||
typeName = 'Static IP Machines Provider'
|
||||
typeType = 'PhysicalMachinesServiceProvider'
|
||||
typeDescription = 'Provides connection to Virtual Center Services'
|
||||
typeDescription = 'Provides connection to machines by IP'
|
||||
iconFile = 'provider.png'
|
||||
|
||||
from .IPMachinesService import IPMachinesService
|
||||
|
@ -48,7 +48,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2016-04-18'
|
||||
__updated__ = '2016-04-25'
|
||||
|
||||
|
||||
CACHE_TIME_FOR_SERVER = 1800
|
||||
@ -99,7 +99,7 @@ class Provider(ServiceProvider):
|
||||
username = gui.TextField(length=32, label=_('Username'), order=2, tooltip=_('User with valid privileges on XenServer'), required=True, defvalue='root')
|
||||
password = gui.PasswordField(lenth=32, label=_('Password'), order=3, tooltip=_('Password of the user of XenServer'), required=True)
|
||||
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxPreparingServices = gui.NumericField(length=3, label=_('Creation concurrency'), defvalue='10', minValue=1, maxValue=65536, order=50, tooltip=_('Maximum number of concurrently creating VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
maxRemovingServices = gui.NumericField(length=3, label=_('Removal concurrency'), defvalue='5', minValue=1, maxValue=65536, order=51, tooltip=_('Maximum number of concurrently removing VMs'), required=True, tab=gui.ADVANCED_TAB)
|
||||
|
||||
macsRange = gui.TextField(length=36, label=_('Macs range'), defvalue='02:46:00:00:00:00-02:46:00:FF:FF:FF', order=90, rdonly=True,
|
||||
|
@ -19,7 +19,6 @@ gui.configuration.link = ->
|
||||
val = if $element.attr('type') is 'checkbox' then (if $element.is(":checked") then "1" else "0") else $element.val()
|
||||
$element.attr "data-val", val
|
||||
|
||||
|
||||
# Add handlers to buttons
|
||||
$("#form_config .button-undo").on "click", (event) ->
|
||||
fld = $(this).attr("data-fld")
|
||||
@ -56,4 +55,4 @@ gui.configuration.link = ->
|
||||
), gui.failRequestModalFnc
|
||||
return
|
||||
|
||||
return
|
||||
return
|
||||
|
@ -189,6 +189,7 @@
|
||||
{% js_template 'dashboard' %}
|
||||
{% js_template 'restricted' %}
|
||||
{% js_template 'providers' %}
|
||||
{% js_template 'service-info' %}
|
||||
{% js_template 'authenticators' %}
|
||||
{% js_template 'osmanagers' %}
|
||||
{% js_template 'connectivity' %}
|
||||
|
@ -47,13 +47,21 @@
|
||||
{{# ifequals value.type 1 }}
|
||||
<textarea class="form-control config-ctrl" data-section="{{ cfg_section }}" data-key="{{ cfg_key }}" rows="3">{{ value.value }}</textarea>
|
||||
{{ else }}
|
||||
{{# ifequals value.type 3 }}
|
||||
<input type="checkbox" data-on-text="{% endverbatim %}{% trans 'Yes' %}{% verbatim %}" data-off-text="{% endverbatim %}{% trans 'No' %}{% verbatim %}" class="config-ctrl" {{# ifequals value.value 1 }} checked{{/ ifequals }} data-section="{{ cfg_section }}" data-key="{{ cfg_key }}">
|
||||
{{ else }}
|
||||
<div>
|
||||
<input type="{{# ifequals value.type 2 }}numeric{{ else }}text{{/ ifequals}}" class="form-control config-ctrl" data-section="{{ cfg_section }}" data-key="{{ cfg_key }}" value="{{ value.value }}">
|
||||
</div>
|
||||
{{/ ifequals }}
|
||||
{{# ifequals value.type 3 }}
|
||||
<input type="checkbox" data-on-text="{% endverbatim %}{% trans 'Yes' %}{% verbatim %}" data-off-text="{% endverbatim %}{% trans 'No' %}{% verbatim %}" class="config-ctrl" {{# ifequals value.value 1 }} checked{{/ ifequals }} data-section="{{ cfg_section }}" data-key="{{ cfg_key }}">
|
||||
{{ else }}
|
||||
{{# ifequals value.type 4 }}
|
||||
<select class="selectpicker show-menu-arrow show-tick config-ctrl" data-style="btn-default" data-width="100%" id="{{ name }}_field" data-section="{{ cfg_section }}" data-key="{{ cfg_key }}">
|
||||
{{#each value.params }}
|
||||
<option value="{{ this }}"{{# ifequals this ../value.value }} selected{{/ ifequals }}>{{ this }}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
{{ else }}
|
||||
<div>
|
||||
<input type="{{# ifequals value.type 2 }}numeric{{ else }}text{{/ ifequals}}" class="form-control config-ctrl" data-section="{{ cfg_section }}" data-key="{{ cfg_key }}" value="{{ value.value }}">
|
||||
</div>
|
||||
{{/ ifequals }}
|
||||
{{/ ifequals }}
|
||||
{{/ ifequals }}
|
||||
{{/ if }}
|
||||
</div>
|
||||
@ -64,7 +72,7 @@
|
||||
{{ unset_var "cfg_section" }}
|
||||
{{/ eachKey }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@ -73,4 +81,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endverbatim %}
|
||||
{% endverbatim %}
|
||||
|
@ -60,76 +60,80 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="ui three column grid">
|
||||
<div class="row">
|
||||
<div class="six wide column centered" id="login">
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-dismissable alert-danger">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
{% trans 'invalid credentials'|capfirst %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form id="loginform" name="loginform" method="post">
|
||||
{% csrf_token %}
|
||||
{% for hidden in form.hidden_fields %}
|
||||
{{ hidden }}
|
||||
{% endfor %}
|
||||
<div class="ui raised segment signin">
|
||||
<h3 class="ui inverted blue block header"> {% trans 'Welcome to UDS' %} {{ version }}</h3>
|
||||
<div class="ui one column grid basic segment">
|
||||
<div class="column">
|
||||
<div class="ui blue stacked segment">
|
||||
<div class="ui form">
|
||||
<div class="field">
|
||||
<label> {% trans "Username" %} </label>
|
||||
<div class="ui left labeled icon input">
|
||||
<input type="text" id="id_{{form.user.name}}" name="{{form.user.name}}">
|
||||
<i class="user icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label> {% trans "Password" %} </label>
|
||||
<div class="ui left labeled icon input">
|
||||
<input type="password" id="id_{{form.password.name}}" name="{{form.password.name}}">
|
||||
<i class="lock icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
{% if form.fields.authenticator.choices|length > 1 %}
|
||||
<div class="inline field">
|
||||
<label> {% trans "Authenticator" %} </label>
|
||||
<select class="ui fluid dropdown" name="{{ form.authenticator.name }}" id="id_{{ form.authenticator.name }}">
|
||||
{% for val, txt in form.fields.authenticator.choices %}
|
||||
<option value="{{ val }}">{{ txt }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="ui vertical animated blue small button signin">
|
||||
<div class="visible content"> {% trans "Log In" %} </div>
|
||||
<div class="hidden content">
|
||||
<i class="sign in icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui container one column" id="login">
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-dismissable alert-danger">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
{% trans 'invalid credentials'|capfirst %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form id="loginform" name="loginform" method="post">
|
||||
{% csrf_token %}
|
||||
{% for hidden in form.hidden_fields %}
|
||||
{{ hidden }}
|
||||
{% endfor %}
|
||||
<div class="ui raised segment signin">
|
||||
<h3 class="ui inverted blue block header"> {% trans 'Welcome to UDS' %} {{ version }}</h3>
|
||||
<div class="ui one column grid basic segment">
|
||||
<div class="column">
|
||||
<div class="ui blue stacked segment">
|
||||
<div class="ui form">
|
||||
<div class="field">
|
||||
<label> {% trans "Username" %} </label>
|
||||
<div class="ui left labeled icon input">
|
||||
<input type="text" id="id_{{form.user.name}}" name="{{form.user.name}}">
|
||||
<i class="user icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label> {% trans "Password" %} </label>
|
||||
<div class="ui left labeled icon input">
|
||||
<input type="password" id="id_{{form.password.name}}" name="{{form.password.name}}">
|
||||
<i class="lock icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
{% if form.fields.authenticator.choices|length > 1 %}
|
||||
<div class="inline field">
|
||||
<label> {% trans "Authenticator" %} </label>
|
||||
<select class="ui fluid dropdown" name="{{ form.authenticator.name }}" id="id_{{ form.authenticator.name }}">
|
||||
{% for val, txt in form.fields.authenticator.choices %}
|
||||
<option value="{{ val }}">{{ txt }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="ui vertical animated blue small button signin">
|
||||
<div class="visible content"> {% trans "Log In" %} </div>
|
||||
<div class="hidden content">
|
||||
<i class="sign in icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
|
||||
<div id="nonStandard" style="display: none">
|
||||
<div id="nonStandardLogin" class="form">
|
||||
non standard logins
|
||||
</div>
|
||||
<div id="divBackToLogin">
|
||||
<a href="#" id="backToLogin" title="{% trans "Back to login" %}">{% trans "Back to login" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="customHtml">
|
||||
{% autoescape off %}
|
||||
{{ customHtml }}
|
||||
{% endautoescape %}
|
||||
</div>
|
||||
|
||||
<div id="nonStandard" style="display: none">
|
||||
<div id="nonStandardLogin" class="form">
|
||||
non standard logins
|
||||
</div>
|
||||
<div id="divBackToLogin">
|
||||
<a href="#" id="backToLogin" title="{% trans "Back to login" %}">{% trans "Back to login" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="customHtml">
|
||||
{% autoescape off %}
|
||||
{{ customHtml }}
|
||||
{% endautoescape %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,11 +0,0 @@
|
||||
{% load i18n static %}
|
||||
{% spaceless %}
|
||||
<div id="admin">
|
||||
<span>{% trans "Admin" %}</span>
|
||||
<ul>
|
||||
<!-- we can use as many LIs as we need -->
|
||||
<li><a href="{% url "uds.web.views.download" idDownload='' %}">{% trans "Downloads" %}</a></li>
|
||||
<li><a href="{% url "uds.admin.views.index" %}">{% trans "Dashboard" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endspaceless %}
|
@ -1,4 +0,0 @@
|
||||
{% load i18n static %}
|
||||
<div id="backtolist">
|
||||
<a href="{% url "uds.web.views.index" %}">{% trans "Back to services list" %}</a>
|
||||
</div>
|
@ -1,21 +0,0 @@
|
||||
{% load i18n static %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
{% get_language_info for LANGUAGE_CODE as lang %}
|
||||
{% spaceless %}
|
||||
<div id="lang" class="last">
|
||||
<form id="form_language" action="{% url "django.views.i18n.set_language" %}" method="post">
|
||||
{% csrf_token %}
|
||||
{% trans "Language" %}:
|
||||
<input id="id_language" type="hidden" name="language" value=""/>
|
||||
{% get_language_info_list for LANGUAGES as languages %}
|
||||
{% for language in languages %}
|
||||
{% if language.code != lang.code %}
|
||||
<a href="#" onclick='$("#id_language").val("{{ language.code }}"); $("#form_language").submit()'>
|
||||
<img src='{% get_static_prefix %}/img/flags/{{language.code}}.png' alt='{{ language.name_local }}' title='{{ language.name_local }}'/>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</form>
|
||||
</div>
|
||||
{% endspaceless %}
|
Loading…
Reference in New Issue
Block a user