I18n based in gettext #3

Merged
absurdo merged 4 commits from i18n into master 2025-03-20 23:59:10 +00:00
11 changed files with 377 additions and 44 deletions
Showing only changes of commit f185be25a8 - Show all commits

View file

@ -37,7 +37,11 @@ if t.env.directories[1]!=tpl_path:
""" """
#modules_admin.append(['menu_users', 'people-circle', True]) #modules_admin.append(['menu_users', 'people-circle', True])
modules_admin['admin_app.admin_users']=[_('Admin users'), 'people-circle', ['admin_app.admin_permissions']] def admin_users():
return _('Admin users')
modules_admin['admin_app.admin_users']=[admin_users, 'people-circle', ['admin_app.admin_permissions']]
modules_admin_icons['admin_app.admin_users']='<symbol id="people-circle" viewBox="0 0 16 16"><path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/></symbol>' modules_admin_icons['admin_app.admin_users']='<symbol id="people-circle" viewBox="0 0 16 16"><path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/><path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/></symbol>'

View file

@ -0,0 +1,107 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-21 00:00+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: templates/layout.phtml:79
msgid "Applications"
msgstr ""
#: templates/layout.phtml:103 ausers.py:64
msgid "Dark theme"
msgstr ""
#: app.py:73
msgid "Admin"
msgstr ""
#: app.py:108
msgid "Login"
msgstr ""
#: app.py:125
msgid "Signup"
msgstr ""
#: app.py:136
msgid "Invalid user and password"
msgstr ""
#: app.py:186
msgid "Code for complete login"
msgstr ""
#: app.py:186
msgid ""
"We send to you a code for activate your account using double authentication:"
msgstr ""
#: app.py:263
msgid "Sorry, cannot create the new user"
msgstr ""
#: app.py:320
msgid "Auth check"
msgstr ""
#: ausers.py:40 ausers.py:86
msgid "Admin users"
msgstr ""
#: ausers.py:62
msgid "Without privileges"
msgstr ""
#: ausers.py:62
msgid "Selected privileges"
msgstr ""
#: ausers.py:62
msgid "Administrator"
msgstr ""
#: ausers.py:64
msgid "Light theme"
msgstr ""
#: ausers.py:66
msgid "No"
msgstr ""
#: ausers.py:66
msgid "Yes"
msgstr ""
#: ausers.py:132
msgid "User not found"
msgstr ""
#: ausers.py:137
msgid "Users permissions"
msgstr ""
#: ausers.py:142
msgid "Edit"
msgstr ""
#: ausers.py:144
msgid "User access"
msgstr ""
#: ausers.py:145
msgid "Delete"
msgstr ""

View file

@ -0,0 +1,107 @@
# Paramecio admin2 language file
# Copyright (C) 2025
# This file is distributed under the same license as the Paramecio package.
# Antonio de la Rosa <antonio.delarosa@salirdelhoyo.com>, 2025.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-21 00:00+0100\n"
"PO-Revision-Date: 2025-03-21 00:02+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.5\n"
#: templates/layout.phtml:79
msgid "Applications"
msgstr "Applications"
#: templates/layout.phtml:103 ausers.py:64
msgid "Dark theme"
msgstr "Dark theme"
#: app.py:73
msgid "Admin"
msgstr "Admin"
#: app.py:108
msgid "Login"
msgstr "Login"
#: app.py:125
msgid "Signup"
msgstr "Signup"
#: app.py:136
msgid "Invalid user and password"
msgstr "Invalid user and password"
#: app.py:186
msgid "Code for complete login"
msgstr "Code for complete login"
#: app.py:186
msgid "We send to you a code for activate your account using double authentication:"
msgstr "We send to you a code for activate your account using double authentication:"
#: app.py:263
msgid "Sorry, cannot create the new user"
msgstr "Sorry, cannot create the new user"
#: app.py:320
msgid "Auth check"
msgstr "Auth check"
#: ausers.py:40 ausers.py:86
msgid "Admin users"
msgstr "Admin users"
#: ausers.py:62
msgid "Without privileges"
msgstr "Without privileges"
#: ausers.py:62
msgid "Selected privileges"
msgstr "Selected privileges"
#: ausers.py:62
msgid "Administrator"
msgstr "Administrator"
#: ausers.py:64
msgid "Light theme"
msgstr "Light theme"
#: ausers.py:66
msgid "No"
msgstr "No"
#: ausers.py:66
msgid "Yes"
msgstr "Yes"
#: ausers.py:132
msgid "User not found"
msgstr "User not found"
#: ausers.py:137
msgid "Users permissions"
msgstr "Users permissions"
#: ausers.py:142
msgid "Edit"
msgstr "Edit"
#: ausers.py:144
msgid "User access"
msgstr "User access"
#: ausers.py:145
msgid "Delete"
msgstr "Delete"

View file

@ -0,0 +1,107 @@
# Paramecio admin2 language file
# Copyright (C) 2025
# This file is distributed under the same license as the Paramecio package.
# Antonio de la Rosa <antonio.delarosa@salirdelhoyo.com>, 2025.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-03-21 00:00+0100\n"
"PO-Revision-Date: 2025-03-21 00:03+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.5\n"
#: templates/layout.phtml:79
msgid "Applications"
msgstr "Aplicaciones"
#: templates/layout.phtml:103 ausers.py:64
msgid "Dark theme"
msgstr "Tema oscuro"
#: app.py:73
msgid "Admin"
msgstr "Admin"
#: app.py:108
msgid "Login"
msgstr "Login"
#: app.py:125
msgid "Signup"
msgstr "Registrarse"
#: app.py:136
msgid "Invalid user and password"
msgstr "Nombre de usuario o contraseña inválida"
#: app.py:186
msgid "Code for complete login"
msgstr "Código para completar login"
#: app.py:186
msgid "We send to you a code for activate your account using double authentication:"
msgstr "Te enviáremos un código para activar tu cuenta usando doble autenticación:"
#: app.py:263
msgid "Sorry, cannot create the new user"
msgstr "Lo siendo, no puedo crear el nuevo usuario."
#: app.py:320
msgid "Auth check"
msgstr "Verificar login"
#: ausers.py:40 ausers.py:86
msgid "Admin users"
msgstr "Administrar usuarios"
#: ausers.py:62
msgid "Without privileges"
msgstr "Sin privilegios"
#: ausers.py:62
msgid "Selected privileges"
msgstr "Privilegios seleccionados"
#: ausers.py:62
msgid "Administrator"
msgstr "Administrador"
#: ausers.py:64
msgid "Light theme"
msgstr "Thema luminoso"
#: ausers.py:66
msgid "No"
msgstr "No"
#: ausers.py:66
msgid "Yes"
msgstr "Sí"
#: ausers.py:132
msgid "User not found"
msgstr "Usuario no encontrado"
#: ausers.py:137
msgid "Users permissions"
msgstr "Permisos de usuario"
#: ausers.py:142
msgid "Edit"
msgstr "Editar"
#: ausers.py:144
msgid "User access"
msgstr "Acceso de usuario"
#: ausers.py:145
msgid "Delete"
msgstr "Borrar"

View file

@ -1,7 +1,7 @@
<%inherit file="layout.phtml"/> <%inherit file="layout.phtml"/>
<%block name="content"> <%block name="content">
<h3>${tlang('User')}: ${user['username'].capitalize()}</h3> <h3>${tlang('User')}: ${user['username'].capitalize()}</h3>
<p><a href="${url_for('admin_app.admin_users')}">${tlang('Users')}</a> &gt;&gt; ${tlang('Permissions')}</p> <p><a href="${url_for('admin_app.admin_users')}">${_('Users')}</a> &gt;&gt; ${_('Permissions')}</p>
${privileges_admin|n} ${privileges_admin|n}
<p><a href="${url_for('admin_app.admin_users')}">${tlang('Users')}</a> &gt;&gt; ${tlang('Permissions')}</p> <p><a href="${url_for('admin_app.admin_users')}">${_('Users')}</a> &gt;&gt; ${_('Permissions')}</p>
</%block> </%block>

View file

@ -76,19 +76,27 @@ lang_selected=session['lang']
<div class="content_admin"> <div class="content_admin">
<nav id="menu" class="nav-collapse"> <nav id="menu" class="nav-collapse">
<ul> <ul>
<li class="menu_title"><%block name="applications"><i class="fa fa-gear" aria-hidden="true"></i>${tlang('Applications')}</li></%block> <li class="menu_title"><%block name="applications"><i class="fa fa-gear" aria-hidden="true"></i>${_('Applications')}</li></%block>
% for module, mod_v in modules_admin.items(): % for module, mod_v in modules_admin.items():
<li> <li>
% if module in session['modules']: % if module in session['modules']:
% if len(mod_v)>2 and type(mod_v[2]).__name__=='str': % if len(mod_v)>2 and type(mod_v[2]).__name__=='str':
<div class="father_admin"> <div class="father_admin">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#${mod_v[1]}"></use></svg> <svg class="bi me-2" width="16" height="16"><use xlink:href="#${mod_v[1]}"></use></svg>
% if type(mod_v[0]).__name__=='function':
${mod_v[0]()}
% else:
${mod_v[0]} ${mod_v[0]}
%endif
</div> </div>
% else: % else:
<a href="${url_for(module)}" class="${'selected_menu' if module==module_selected else ''}"> <a href="${url_for(module)}" class="${'selected_menu' if module==module_selected else ''}">
<svg class="bi me-2" width="16" height="16"><use xlink:href="#${mod_v[1]}"></use></svg> <svg class="bi me-2" width="16" height="16"><use xlink:href="#${mod_v[1]}"></use></svg>
% if type(mod_v[0]).__name__=='function':
${mod_v[0]()}
% else:
${mod_v[0]} ${mod_v[0]}
%endif
</a> </a>
% endif % endif
% endif % endif

View file

@ -25,12 +25,12 @@
<%block name="content"> <%block name="content">
<div class="card"> <div class="card">
<div class="card-header bg-primary"> <div class="card-header bg-primary">
${tlang('Login')} ${_('Login')}
</div> </div>
<div class="card-body"> <div class="card-body">
<form method="POST" action="${url_for('admin_app.check_login_admin')}" id="login_form" class="needs-validation" novalidate> <form method="POST" action="${url_for('admin_app.check_login_admin')}" id="login_form" class="needs-validation" novalidate>
<div class="mb-3"> <div class="mb-3">
<label for="username_form" class="form-label">${tlang('Username')}</label> <label for="username_form" class="form-label">${_('Username')}</label>
<input type="text" class="form-control form-control-lg has-validation" id="username_form" name="password" aria-describedby="username" autocomplete="off" required> <input type="text" class="form-control form-control-lg has-validation" id="username_form" name="password" aria-describedby="username" autocomplete="off" required>
<div class="invalid-feedback"> <div class="invalid-feedback">
@ -40,12 +40,12 @@
<label for="password_form" class="form-label">Password</label> <label for="password_form" class="form-label">Password</label>
<input type="password" class="form-control form-control-lg has-validation" id="password_form" name="password" autocomplete="off" required> <input type="password" class="form-control form-control-lg has-validation" id="password_form" name="password" autocomplete="off" required>
<div class="invalid-feedback" id="login_invalid"> <div class="invalid-feedback" id="login_invalid">
${tlang('Error: username or password invalid')} ${_('Error: username or password invalid')}
</div> </div>
</div> </div>
<div class="mb-3 form-check"> <div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="remember_login_form" name="remember_login" value="1"> <input type="checkbox" class="form-check-input" id="remember_login_form" name="remember_login" value="1">
<label class="form-check-label" for="autologin">${tlang('Remember login')}</label> <label class="form-check-label" for="autologin">${_('Remember login')}</label>
</div> </div>
<button type="submit" id="login_submit" class="btn btn-primary">Submit</button> <button type="submit" id="login_submit" class="btn btn-primary">Submit</button>
${csrf_token()|n} ${csrf_token()|n}
@ -117,7 +117,7 @@
$('#loader-div').hide(); $('#loader-div').hide();
$('#login_submit').prop('disabled', false); $('#login_submit').prop('disabled', false);
alert('${tlang("Error: please, try again later")}'); alert('${_("Error: please, try again later")}');
}, },
}).done(function(data) { }).done(function(data) {
@ -132,19 +132,19 @@
else else
{ {
$('#username_form').get(0).setCustomValidity("${tlang('Error: username or password invalid')}"); $('#username_form').get(0).setCustomValidity("${_('Error: username or password invalid')}");
$('#password_form').get(0).setCustomValidity("${tlang('Error: username or password invalid')}"); $('#password_form').get(0).setCustomValidity("${_('Error: username or password invalid')}");
console.log(JSON.stringify(data)); console.log(JSON.stringify(data));
if(data.no_login) { if(data.no_login) {
$('#login_invalid').html("${tlang('Error: you try login excessive times, please wait some minutes for try again')}"); $('#login_invalid').html("${_('Error: you try login excessive times, please wait some minutes for try again')}");
} }
else { else {
$('#login_invalid').html("${tlang('Error: username or password invalid')}"); $('#login_invalid').html("${_('Error: username or password invalid')}");
} }

View file

@ -2,30 +2,30 @@
<%block name="content"> <%block name="content">
<div class="card"> <div class="card">
<div class="card-header bg-primary"> <div class="card-header bg-primary">
${tlang('Auth code')} ${_('Auth code')}
</div> </div>
<div class="card-body"> <div class="card-body">
<form method="POST" action="#" id="auth_code_form" class="needs-validation" novalidate> <form method="POST" action="#" id="auth_code_form" class="needs-validation" novalidate>
<div class="mb-3"> <div class="mb-3">
<label for="code_form" class="form-label">${tlang('Check your email for get instructions for complete login with double auth or')} <a href="${url_for('admin_app.logout_admin')}">logout</a> and login again with other user</label> <label for="code_form" class="form-label">${_('Check your email for get instructions for complete login with double auth or')} <a href="${url_for('admin_app.logout_admin')}">logout</a> and login again with other user</label>
<input type="text" class="form-control form-control-lg has-validation" id="code_form" name="code" aria-describedby="code" autocomplete="off" required> <input type="text" class="form-control form-control-lg has-validation" id="code_form" name="code" aria-describedby="code" autocomplete="off" required>
<div class="invalid-feedback" id="txt_error_code"> <div class="invalid-feedback" id="txt_error_code">
${tlang('You need a valid code')} ${_('You need a valid code')}
</div> </div>
</div> </div>
<button type="submit" id="code_submit" class="btn btn-primary">${tlang('Check code')}</button> <button type="submit" id="code_submit" class="btn btn-primary">${_('Check code')}</button>
${csrf_token()|n} ${csrf_token()|n}
</form> </form>
</div> </div>
<!--<div class="form"> <!--<div class="form">
<p align="center">${tlang('Check your email for get instructions for complete login with double auth or')} <a href="${url_for('admin_app.logout_admin')}">logout</a> and login again with other user</p> <p align="center">${_('Check your email for get instructions for complete login with double auth or')} <a href="${url_for('admin_app.logout_admin')}">logout</a> and login again with other user</p>
<p><label>${tlang('Code')} *</label><input type="text" class="" name="code" id="code_form" value="" /> <span class="error" id="code_error"></span></p> <p><label>${_('Code')} *</label><input type="text" class="" name="code" id="code_form" value="" /> <span class="error" id="code_error"></span></p>
${csrf_token()|n} ${csrf_token()|n}
</div> </div>
<div id="submit_block"> <div id="submit_block">
<input type="submit" value="${tlang('Send code')}" class="submit" id="code_submit"/> <input type="submit" value="${_('Send code')}" class="submit" id="code_submit"/>
<span id="loading">&nbsp;</span> <span id="loading">&nbsp;</span>
</div>--> </div>-->
@ -74,7 +74,7 @@
form.classList.add('was-validated'); form.classList.add('was-validated');
alert(textStatus); alert(textStatus);
$('#code_submit').prop('disabled', false); $('#code_submit').prop('disabled', false);
$('#code_form').get(0).setCustomValidity("${tlang('Error, please try again later')}"); $('#code_form').get(0).setCustomValidity("${_('Error, please try again later')}");
} }
}).done(function(data) { }).done(function(data) {
@ -100,22 +100,22 @@
if(data.hasOwnProperty('disable')) { if(data.hasOwnProperty('disable')) {
//$('#code_error').html("${tlang('Error, your user is disabled, you need support of web administration')}"); //$('#code_error').html("${_('Error, your user is disabled, you need support of web administration')}");
$('#code_form').get(0).setCustomValidity("${tlang('Error, your user is disabled, you need support of web administration')}"); $('#code_form').get(0).setCustomValidity("${_('Error, your user is disabled, you need support of web administration')}");
$('#txt_error_code').html("${tlang('Error, your user is disabled, you need support of web administration')}"); $('#txt_error_code').html("${_('Error, your user is disabled, you need support of web administration')}");
} else { } else {
$('#code_form').get(0).setCustomValidity("${tlang('Error, wrong code')}"); $('#code_form').get(0).setCustomValidity("${_('Error, wrong code')}");
//$('#code_error').html("${tlang('Error, wrong code')}"); //$('#code_error').html("${_('Error, wrong code')}");
$('#txt_error_code').html("${tlang('Error, wrong code')}"); $('#txt_error_code').html("${_('Error, wrong code')}");
} }
if(data.you_cannot_login) { if(data.you_cannot_login) {
//$('#code_error').html("${tlang('Error, excessive tries, wait some minutes for login again')}"); //$('#code_error').html("${_('Error, excessive tries, wait some minutes for login again')}");
$('#code_form').get(0).setCustomValidity("${tlang('Error, excessive tries, wait some minutes for login again')}"); $('#code_form').get(0).setCustomValidity("${_('Error, excessive tries, wait some minutes for login again')}");
$('#txt_error_code').html("${tlang('Error, excessive tries, wait some minutes for login again')}"); $('#txt_error_code').html("${_('Error, excessive tries, wait some minutes for login again')}");
} }
@ -170,17 +170,17 @@
if(data.hasOwnProperty('disable')) { if(data.hasOwnProperty('disable')) {
$('#code_error').html("${tlang('Error, your user is disabled, you need support of web administration')}"); $('#code_error').html("${_('Error, your user is disabled, you need support of web administration')}");
} else { } else {
$('#code_error').html("${tlang('Error, wrong code')}"); $('#code_error').html("${_('Error, wrong code')}");
} }
if(data.you_cannot_login) { if(data.you_cannot_login) {
$('#code_error').html("${tlang('Error, excessive tries, wait some minutes for login again')}"); $('#code_error').html("${_('Error, excessive tries, wait some minutes for login again')}");
} }

View file

@ -2,39 +2,39 @@
<%block name="content"> <%block name="content">
<div class="card"> <div class="card">
<div class="card-header bg-primary"> <div class="card-header bg-primary">
${tlang('Signup')} ${_('Signup')}
</div> </div>
<div class="card-body"> <div class="card-body">
<form method="POST" action="${url_for('admin_app.signup_insert_admin')}" id="login_form" class="needs-validation" novalidate> <form method="POST" action="${url_for('admin_app.signup_insert_admin')}" id="login_form" class="needs-validation" novalidate>
<div class="mb-3"> <div class="mb-3">
<label for="username_form" class="form-label">${tlang('Username')}*</label> <label for="username_form" class="form-label">${_('Username')}*</label>
<input type="text" class="form-control form-control-lg has-validation" id="username_form" name="password" aria-describedby="username" autocomplete="off" minlength="4" pattern="\w{4,32}" required> <input type="text" class="form-control form-control-lg has-validation" id="username_form" name="password" aria-describedby="username" autocomplete="off" minlength="4" pattern="\w{4,32}" required>
<div class="invalid-feedback"> <div class="invalid-feedback">
${tlang('You need a valid username')} ${_('You need a valid username')}
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="email_form" class="form-label">${tlang('Email')}*</label> <label for="email_form" class="form-label">${_('Email')}*</label>
<input type="email" class="form-control form-control-lg has-validation" id="email_form" name="email" autocomplete="off" minlength="4" required> <input type="email" class="form-control form-control-lg has-validation" id="email_form" name="email" autocomplete="off" minlength="4" required>
<div class="invalid-feedback"> <div class="invalid-feedback">
${tlang('You need an email')} ${_('You need an email')}
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="password_form" class="form-label">Password*</label> <label for="password_form" class="form-label">Password*</label>
<input type="password" class="form-control form-control-lg has-validation" id="password_form" name="password" autocomplete="off" minlength="2" required> <input type="password" class="form-control form-control-lg has-validation" id="password_form" name="password" autocomplete="off" minlength="2" required>
<div class="invalid-feedback"> <div class="invalid-feedback">
${tlang('You need a password')} ${_('You need a password')}
</div> </div>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="repeat_password_form" class="form-label">${tlang('Repeat password')}*</label> <label for="repeat_password_form" class="form-label">${_('Repeat password')}*</label>
<input type="password" class="form-control form-control-lg has-validation" id="repeat_password_form" name="repeat_password" autocomplete="off" minlength="2" required> <input type="password" class="form-control form-control-lg has-validation" id="repeat_password_form" name="repeat_password" autocomplete="off" minlength="2" required>
<div class="invalid-feedback"> <div class="invalid-feedback">
${tlang('You need the same password in this field and not empty')} ${_('You need the same password in this field and not empty')}
</div> </div>
</div> </div>
<button type="submit" id="login_submit" class="btn btn-primary">${tlang('Create user')}</button> <button type="submit" id="login_submit" class="btn btn-primary">${_('Create user')}</button>
${csrf_token()|n} ${csrf_token()|n}
</form> </form>
</div> </div>
@ -49,7 +49,7 @@ $(document).ready( function () {
console.log('No match'); console.log('No match');
$('#repeat_password_form').get(0).setCustomValidity("${tlang('Passwords doesn\'t match')}"); $('#repeat_password_form').get(0).setCustomValidity("${_('Passwords doesn\'t match')}");
} }
else { else {
@ -105,7 +105,7 @@ $(document).ready( function () {
$('#loader-div').hide(); $('#loader-div').hide();
$('#login_submit').prop('disabled', false); $('#login_submit').prop('disabled', false);
alert('${tlang("Error: please, try again later")}'); alert('${_("Error: please, try again later")}');
}, },
}).done(function(data) { }).done(function(data) {