* [enhance] set doctype label via Customize Form frappe/erpnext#2019 * Update customize_form.pyversion-14
@@ -56,8 +56,6 @@ def get_lang_dict(fortype, name=None): | |||||
:param fortype: must be one of `doctype`, `page`, `report`, `include`, `jsfile`, `boot` | :param fortype: must be one of `doctype`, `page`, `report`, `include`, `jsfile`, `boot` | ||||
:param name: name of the document for which assets are to be returned.""" | :param name: name of the document for which assets are to be returned.""" | ||||
if local.lang=="en": | |||||
return {} | |||||
from frappe.translate import get_dict | from frappe.translate import get_dict | ||||
return get_dict(fortype, name) | return get_dict(fortype, name) | ||||
@@ -103,16 +103,18 @@ def get_allowed_pages(): | |||||
return page_info | return page_info | ||||
def load_translations(bootinfo): | def load_translations(bootinfo): | ||||
if frappe.local.lang != 'en': | |||||
messages = frappe.get_lang_dict("boot") | |||||
messages = frappe.get_lang_dict("boot") | |||||
bootinfo["lang"] = frappe.lang | |||||
bootinfo["lang"] = frappe.lang | |||||
# load translated report names | |||||
for name in bootinfo.user.all_reports: | |||||
messages[name] = frappe._(name) | |||||
# load translated report names | |||||
for name in bootinfo.user.all_reports: | |||||
messages[name] = frappe._(name) | |||||
bootinfo["__messages"] = messages | |||||
# only untranslated | |||||
messages = {k:v for k, v in messages.iteritems() if k!=v} | |||||
bootinfo["__messages"] = messages | |||||
def get_fullnames(): | def get_fullnames(): | ||||
"""map of user fullnames""" | """map of user fullnames""" | ||||
@@ -5,10 +5,11 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from frappe.translate import clear_cache | |||||
class Translation(Document): | class Translation(Document): | ||||
def on_update(self): | def on_update(self): | ||||
frappe.cache().hdel('lang_user_translations', self.language_code) | |||||
clear_cache() | |||||
def on_trash(self): | def on_trash(self): | ||||
frappe.cache().hdel('lang_user_translations', self.language_code) | |||||
clear_cache() |
@@ -9,6 +9,7 @@ frappe.ui.form.on("Customize Form", { | |||||
frm.set_query("doc_type", function() { | frm.set_query("doc_type", function() { | ||||
return { | return { | ||||
translate_values: false, | |||||
filters: [ | filters: [ | ||||
['DocType', 'issingle', '=', 0], | ['DocType', 'issingle', '=', 0], | ||||
['DocType', 'custom', '=', 0], | ['DocType', 'custom', '=', 0], | ||||
@@ -15,6 +15,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "doc_type", | "fieldname": "doc_type", | ||||
"fieldtype": "Link", | "fieldtype": "Link", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -40,6 +41,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "doc_type", | "depends_on": "doc_type", | ||||
"fieldname": "properties", | "fieldname": "properties", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
@@ -65,6 +67,33 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "label", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Change Label (via Custom Translation)", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "default_print_format", | "fieldname": "default_print_format", | ||||
"fieldtype": "Link", | "fieldtype": "Link", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -90,6 +119,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "", | "depends_on": "", | ||||
"fieldname": "max_attachments", | "fieldname": "max_attachments", | ||||
"fieldtype": "Int", | "fieldtype": "Int", | ||||
@@ -115,6 +145,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "allow_copy", | "fieldname": "allow_copy", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -139,6 +170,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "istable", | "fieldname": "istable", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -164,6 +196,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "istable", | "depends_on": "istable", | ||||
"fieldname": "editable_grid", | "fieldname": "editable_grid", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -190,6 +223,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"default": "1", | "default": "1", | ||||
"fieldname": "quick_entry", | "fieldname": "quick_entry", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -216,6 +250,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "eval: doc.image_field", | "depends_on": "eval: doc.image_field", | ||||
"fieldname": "image_view", | "fieldname": "image_view", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -242,6 +277,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "column_break_5", | "fieldname": "column_break_5", | ||||
"fieldtype": "Column Break", | "fieldtype": "Column Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -266,6 +302,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "Use this fieldname to generate title", | "description": "Use this fieldname to generate title", | ||||
"fieldname": "title_field", | "fieldname": "title_field", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -292,6 +329,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "Must be of type \"Attach Image\"", | "description": "Must be of type \"Attach Image\"", | ||||
"fieldname": "image_field", | "fieldname": "image_field", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -318,6 +356,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "Fields separated by comma (,) will be included in the \"Search By\" list of Search dialog box", | "description": "Fields separated by comma (,) will be included in the \"Search By\" list of Search dialog box", | ||||
"fieldname": "search_fields", | "fieldname": "search_fields", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -343,6 +382,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "doc_type", | "depends_on": "doc_type", | ||||
"fieldname": "section_break_8", | "fieldname": "section_break_8", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
@@ -368,6 +408,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "sort_field", | "fieldname": "sort_field", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -392,6 +433,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "column_break_10", | "fieldname": "column_break_10", | ||||
"fieldtype": "Column Break", | "fieldtype": "Column Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -416,6 +458,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "sort_order", | "fieldname": "sort_order", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -441,6 +484,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "doc_type", | "depends_on": "doc_type", | ||||
"description": "Customize Label, Print Hide, Default etc.", | "description": "Customize Label, Print Hide, Default etc.", | ||||
"fieldname": "fields_section_break", | "fieldname": "fields_section_break", | ||||
@@ -467,6 +511,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "fields", | "fieldname": "fields", | ||||
"fieldtype": "Table", | "fieldtype": "Table", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -500,7 +545,7 @@ | |||||
"issingle": 1, | "issingle": 1, | ||||
"istable": 0, | "istable": 0, | ||||
"max_attachments": 0, | "max_attachments": 0, | ||||
"modified": "2016-07-08 04:40:57.045612", | |||||
"modified": "2016-09-16 02:36:09.171273", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Custom", | "module": "Custom", | ||||
"name": "Customize Form", | "name": "Customize Form", | ||||
@@ -7,6 +7,7 @@ from __future__ import unicode_literals | |||||
Thus providing a better UI from user perspective | Thus providing a better UI from user perspective | ||||
""" | """ | ||||
import frappe | import frappe | ||||
import frappe.translate | |||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import cint | from frappe.utils import cint | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -84,8 +85,36 @@ class CustomizeForm(Document): | |||||
new_d[property] = d.get(property) | new_d[property] = d.get(property) | ||||
self.append("fields", new_d) | self.append("fields", new_d) | ||||
# load custom translation | |||||
translation = self.get_name_translation() | |||||
self.label = translation.target_name if translation else '' | |||||
# NOTE doc is sent to clientside by run_method | # NOTE doc is sent to clientside by run_method | ||||
def get_name_translation(self): | |||||
'''Get translation object if exists of current doctype name in the default language''' | |||||
return frappe.get_value('Translation', | |||||
{'source_name': self.doc_type, 'language_code': frappe.local.lang or 'en'}, | |||||
['name', 'target_name'], as_dict=True) | |||||
def set_name_translation(self): | |||||
'''Create, update custom translation for this doctype''' | |||||
current = self.get_name_translation() | |||||
if current: | |||||
if self.label and current!=self.label: | |||||
frappe.db.set_value('Translation', current.name, 'target_name', self.label) | |||||
frappe.translate.clear_cache() | |||||
else: | |||||
# clear translation | |||||
frappe.delete_doc('Translation', current.name) | |||||
else: | |||||
if self.label: | |||||
frappe.get_doc(dict(doctype='Translation', | |||||
source_name=self.doc_type, | |||||
target_name=self.label, | |||||
language_code=frappe.local.lang or 'en')).insert() | |||||
def clear_existing_doc(self): | def clear_existing_doc(self): | ||||
doc_type = self.doc_type | doc_type = self.doc_type | ||||
@@ -104,6 +133,7 @@ class CustomizeForm(Document): | |||||
self.set_property_setters() | self.set_property_setters() | ||||
self.update_custom_fields() | self.update_custom_fields() | ||||
self.set_name_translation() | |||||
validate_fields_for_doctype(self.doc_type) | validate_fields_for_doctype(self.doc_type) | ||||
frappe.msgprint(_("{0} updated").format(_(self.doc_type))) | frappe.msgprint(_("{0} updated").format(_(self.doc_type))) | ||||
@@ -1146,6 +1146,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ | |||||
}); | }); | ||||
this.input = this.$input.get(0); | this.input = this.$input.get(0); | ||||
this.has_input = true; | this.has_input = true; | ||||
this.translate_values = true; | |||||
var me = this; | var me = this; | ||||
this.setup_buttons(); | this.setup_buttons(); | ||||
this.setup_autocomplete(); | this.setup_autocomplete(); | ||||
@@ -1337,7 +1338,11 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ | |||||
$(this).autocomplete("close"); | $(this).autocomplete("close"); | ||||
}) | }) | ||||
.data('ui-autocomplete')._renderItem = function(ul, d) { | .data('ui-autocomplete')._renderItem = function(ul, d) { | ||||
var html = "<strong>" + __(d.value) + "</strong>"; | |||||
var _value = d.value; | |||||
if(me.translate_values) { | |||||
_value = __(d.value) | |||||
} | |||||
var html = "<strong>" + _value + "</strong>"; | |||||
if(d.description && d.value!==d.description) { | if(d.description && d.value!==d.description) { | ||||
html += '<br><span class="small">' + __(d.description) + '</span>'; | html += '<br><span class="small">' + __(d.description) + '</span>'; | ||||
} | } | ||||
@@ -1387,14 +1392,23 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ | |||||
} else if(typeof(get_query)==="string") { | } else if(typeof(get_query)==="string") { | ||||
args.query = get_query; | args.query = get_query; | ||||
} else { | } else { | ||||
// get_query by function | |||||
var q = (get_query)(this.frm && this.frm.doc, this.doctype, this.docname); | var q = (get_query)(this.frm && this.frm.doc, this.doctype, this.docname); | ||||
if (typeof(q)==="string") { | if (typeof(q)==="string") { | ||||
// returns a string | |||||
args.query = q; | args.query = q; | ||||
} else if($.isPlainObject(q)) { | } else if($.isPlainObject(q)) { | ||||
// returns a plain object with filters | |||||
if(q.filters) { | if(q.filters) { | ||||
set_nulls(q.filters); | set_nulls(q.filters); | ||||
} | } | ||||
// turn off value translation | |||||
if(q.translate_values !== undefined) { | |||||
this.translate_values = q.translate_values; | |||||
} | |||||
// extend args for custom functions | // extend args for custom functions | ||||
$.extend(args, q); | $.extend(args, q); | ||||
@@ -116,7 +116,6 @@ frappe.ui.toolbar.Toolbar = Class.extend({ | |||||
var link = links[i]; | var link = links[i]; | ||||
var url = link.url; | var url = link.url; | ||||
var app_name = url.split('//', 2)[1].split('/', 2)[1]; | var app_name = url.split('//', 2)[1].split('/', 2)[1]; | ||||
console.log(app_name) | |||||
var data_path = url.slice(url.indexOf('/user')); | var data_path = url.slice(url.indexOf('/user')); | ||||
if(data_path.lastIndexOf('.')){ | if(data_path.lastIndexOf('.')){ | ||||
data_path = data_path.slice(0, data_path.lastIndexOf('.')); | data_path = data_path.slice(0, data_path.lastIndexOf('.')); | ||||
@@ -209,8 +209,12 @@ _f.Frm.prototype.get_files = function() { | |||||
_f.Frm.prototype.set_query = function(fieldname, opt1, opt2) { | _f.Frm.prototype.set_query = function(fieldname, opt1, opt2) { | ||||
if(opt2) { | if(opt2) { | ||||
// on child table | |||||
// set_query(fieldname, parent fieldname, query) | |||||
this.fields_dict[opt1].grid.get_field(fieldname).get_query = opt2; | this.fields_dict[opt1].grid.get_field(fieldname).get_query = opt2; | ||||
} else { | } else { | ||||
// on parent table | |||||
// set_query(fieldname, query) | |||||
this.fields_dict[fieldname].get_query = opt1; | this.fields_dict[fieldname].get_query = opt1; | ||||
} | } | ||||
} | } | ||||
@@ -113,8 +113,13 @@ def get_dict(fortype, name=None): | |||||
messages += frappe.db.sql("select 'Module:', label from `tabDesktop Icon` where standard=1 or owner=%s", | messages += frappe.db.sql("select 'Module:', label from `tabDesktop Icon` where standard=1 or owner=%s", | ||||
frappe.session.user) | frappe.session.user) | ||||
translation_assets[asset_key] = make_dict_from_messages(messages) | |||||
translation_assets[asset_key].update(get_dict_from_hooks(fortype, name)) | |||||
message_dict = make_dict_from_messages(messages) | |||||
message_dict.update(get_dict_from_hooks(fortype, name)) | |||||
# remove untranslated | |||||
message_dict = {k:v for k, v in message_dict.iteritems() if k!=v} | |||||
translation_assets[asset_key] = message_dict | |||||
cache.hset("translation_assets", frappe.local.lang, translation_assets) | cache.hset("translation_assets", frappe.local.lang, translation_assets) | ||||
@@ -245,16 +250,17 @@ def get_user_translations(lang): | |||||
return out | return out | ||||
# def get_user_translation_key(): | |||||
# return 'lang_user_translations:{0}'.format(frappe.local.site) | |||||
def clear_cache(): | def clear_cache(): | ||||
"""Clear all translation assets from :meth:`frappe.cache`""" | """Clear all translation assets from :meth:`frappe.cache`""" | ||||
cache = frappe.cache() | cache = frappe.cache() | ||||
cache.delete_key("langinfo") | cache.delete_key("langinfo") | ||||
# clear translations saved in boot cache | |||||
cache.delete_key("bootinfo") | |||||
cache.delete_key("lang_full_dict") | cache.delete_key("lang_full_dict") | ||||
cache.delete_key("translation_assets") | cache.delete_key("translation_assets") | ||||
cache.delete_key("lang_user_translations") | |||||
def get_messages_for_app(app): | def get_messages_for_app(app): | ||||
"""Returns all messages (list) for a specified `app`""" | """Returns all messages (list) for a specified `app`""" | ||||