Skip to content

Commit

Permalink
Merge menu_item_rename and user_group_rename into same module (#46)
Browse files Browse the repository at this point in the history
* Merge menu_item_rename and user_group_rename into same module
  • Loading branch information
ddufresne authored Dec 3, 2019
1 parent a174017 commit 5e68cd0
Show file tree
Hide file tree
Showing 23 changed files with 189 additions and 165 deletions.
3 changes: 1 addition & 2 deletions .docker_files/main/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

'auditlog',
'base_extended_security',
'base_xml_rename',
'disable_install_from_website',
'ir_attachment_access_token_portal',
'ir_attachment_name_autocomplete',
Expand All @@ -24,12 +25,10 @@
'mail_message_from_author',
'mail_notification_no_footer',
'mail_recipient_unchecked',
'menu_item_rename',
'note_no_default_stage',
'private_data_group',
'queue_job_auto_requeue',
'super_calendar',
'user_group_rename',
'web_email_field_new_tab',
],
'installable': True,
Expand Down
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ USER odoo

COPY auditlog /mnt/extra-addons/auditlog
COPY base_extended_security /mnt/extra-addons/base_extended_security
COPY base_xml_rename /mnt/extra-addons/base_xml_rename
COPY disable_install_from_website /mnt/extra-addons/disable_install_from_website
COPY ir_attachment_access_token_portal /mnt/extra-addons/ir_attachment_access_token_portal
COPY ir_attachment_name_autocomplete /mnt/extra-addons/ir_attachment_name_autocomplete
Expand All @@ -25,13 +26,11 @@ COPY mail_follower_picker /mnt/extra-addons/mail_follower_picker
COPY mail_message_from_author /mnt/extra-addons/mail_message_from_author
COPY mail_notification_no_footer /mnt/extra-addons/mail_notification_no_footer
COPY mail_recipient_unchecked /mnt/extra-addons/mail_recipient_unchecked
COPY menu_item_rename /mnt/extra-addons/menu_item_rename
COPY note_no_default_stage /mnt/extra-addons/note_no_default_stage
COPY private_data_group /mnt/extra-addons/private_data_group
COPY queue_job_auto_requeue /mnt/extra-addons/queue_job_auto_requeue
COPY super_calendar /mnt/extra-addons/super_calendar
COPY test_http_request /mnt/extra-addons/test_http_request
COPY user_group_rename /mnt/extra-addons/user_group_rename
COPY web_email_field_new_tab /mnt/extra-addons/web_email_field_new_tab

COPY .docker_files/main /mnt/extra-addons/main
Expand Down
91 changes: 91 additions & 0 deletions base_xml_rename/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
Base XML Rename
===============
This module allows to rename UI elements using XML data files in modules.

.. contents:: Table of Contents

Context
-------
Renaming a menu in Odoo directly through the web interface is not a good idea.

* We rapidly loose track of what was modified.
* The menu names are not changed in test environments (except with replication of the prod).
* The changes are lost if someone forces the override of translations.

The same applies for renaming other objects such as user groups.

Module Design
-------------
A mixin ``xml.rename.mixin`` is added.

This mixin has a method ``rename`` which takes 3 mandatory parameters:

* ``ref``: the xml reference of the record.
* ``lang``: the language of the term.
* ``value``: the new term.

Optionaly, a ``field`` parameter can be supplied, in case the field is not ``name``.

The mixin can be added to any model.

For now, the module adds the mixin to ir.ui.menu and res.groups.

Usage
-----
Here are 2 examples for renaming menu items and user groups.

Renaming a Menu
~~~~~~~~~~~~~~~
Inside an xml file:

* Add a `function` node with model="ir.ui.menu".
* Inside the `function` node, you must set 3 `value` nodes.

These nodes must have type="char" and respectively contain the following data:

1. The XML ID of the menu item
2. The languge code
3. The new label to set

Here is an example to rename the `Settings` menu to `Administration`.

.. code-block:: XML
<function name="rename" model="ir.ui.menu">
<value type="char">base.menu_administration</value>
<value type="char">en_US</value>
<value type="char">Administration</value>
</function>
Here is the result after loading the module containg the XML file.

.. image:: static/description/admin_menu.png

Renaming a User Group
~~~~~~~~~~~~~~~~~~~~~
Here is an example of renaming a user group. This works the same way as renaming a menu item.

.. code-block:: XML
<function name="rename" model="res.groups">
<value type="char">account.group_account_user</value>
<value type="char">fr_FR</value>
<value type="char">Comptable</value>
</function>
Before loading the XML, the group is named ``Montrer les fonctions de comptabilité complète`` in french.

.. image:: static/description/group_before.png

After loading the XML, the group is named ``Comptable``.

.. image:: static/description/group_after.png

Known Issues
~~~~~~~~~~~~
If you reload translations with ``Overwrite Existing Terms`` checked, the terms loaded with XML
will not be reloaded automatically. You will need to update the modules containing these XML files).

Contributors
------------
* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import models
from . import (
ir_ui_menu,
res_groups,
xml_rename_mixin,
)
23 changes: 23 additions & 0 deletions base_xml_rename/models/ir_ui_menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import api, models
from .xml_rename_mixin import is_lang_installed


class IrUiMenu(models.Model):

_inherit = ('ir.ui.menu', 'xml.rename.mixin')
_name = 'ir.ui.menu'

@api.model
def rename(self, ref, lang, value, field='name'):
super().rename(ref, lang, value, field)

menu = self.env.ref(ref)
should_update_action_name = (
is_lang_installed(self.env, lang) and
menu.action and field == 'name'
)
if should_update_action_name:
menu.action.with_context(lang=lang).name = value
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import models


class ResGroups(models.Model):

_inherit = ('res.groups', 'xml.rename.mixin')
_name = 'res.groups'
50 changes: 50 additions & 0 deletions base_xml_rename/models/xml_rename_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# © 2019 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

import logging
from odoo import api, models
from odoo.exceptions import ValidationError


_logger = logging.getLogger(__name__)


def is_lang_installed(env: 'Environment', lang: str):
return lang in dict(env['res.lang'].get_installed())


class XMLRenameMixin(models.AbstractModel):

_name = 'xml.rename.mixin'
_description = 'Mixin For Renaming Records Through XML'

@api.model
def rename(self, ref, lang, value, field='name'):
"""Rename the record to rename.
:param ref: the XML ID of the record to rename
:param lang: the language of the term
:param value: the new name for the record
"""
if not is_lang_installed(self.env, lang):
_logger.debug(
'Skip renaming the record {ref} for the language {lang}. '
'The language is not installed.'
.format(ref=ref, lang=lang)
)
return

_logger.info(
'Renaming the record {ref} with the label `{value}` '
'for the language {lang}.'
.format(ref=ref, lang=lang, value=value)
)
record = self.env.ref(ref)
if record._name != self._name:
raise ValidationError(
'The XML ID {ref} does not reference a record of model {model}. '
'It references a record of model {record_model}'
.format(ref=ref, model=self._name, record_model=record._name)
)

record.with_context(lang=lang).write({field: value})
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,8 @@ def test_after_rename_menu_with_en__action_fr_translation_unchanged(self):
new_label = 'New label'
self._rename_menu('en_US', new_label)
assert self.action.with_context(lang='fr_FR').name == self.menu_name_fr

def test_if_lang_not_active__term_ignored(self):
self.fr_lang.active = False
self._rename_menu('fr_FR', 'Nouveau libellé')
assert self.menu.name == self.menu_name_en
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,8 @@ def test_after_rename_group_with_en__fr_translation_unchanged(self):
new_label = 'New label'
self._rename_group('en_US', new_label)
assert self.group.with_context(lang='fr_FR').name == self.group_name_fr

def test_if_lang_not_active__term_ignored(self):
self.fr_lang.active = False
self._rename_group('fr_FR', 'Nouveau libellé')
assert self.group.name == self.group_name_en
42 changes: 0 additions & 42 deletions menu_item_rename/README.rst

This file was deleted.

39 changes: 0 additions & 39 deletions menu_item_rename/models.py

This file was deleted.

29 changes: 0 additions & 29 deletions user_group_rename/README.rst

This file was deleted.

14 changes: 0 additions & 14 deletions user_group_rename/__manifest__.py

This file was deleted.

Loading

0 comments on commit 5e68cd0

Please sign in to comment.