Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions connector_wordpress_wpml/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
========================
Connector WordPress WMPL
========================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:d23d756741cd2b3f004e61155d338ccb1a5c43949541285f54121e019b39c117
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-NuoBiT%2Fodoo--addons-lightgray.png?logo=github
:target: https://github.com/NuoBiT/odoo-addons/tree/18.0/connector_wordpress_wpml
:alt: NuoBiT/odoo-addons

|badge1| |badge2| |badge3|

- This module works with plugin WordPress Multi Language.
- https://wpml.org/

On WPML settings uncheck the options

- When uploading media to the Media library, make it available in all
languages.
- Duplicate media attachments for translations.

If we don't do this, the media files will be created once for each
language, which it can be a problem for the capacity of the server.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/NuoBiT/odoo-addons/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/NuoBiT/odoo-addons/issues/new?body=module:%20connector_wordpress_wpml%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* NuoBiT Solutions SL

Contributors
------------

- `NuoBiT <https://www.nuobit.com>`__:

- Kilian Niubo kniubo@nuobit.com
- Deniz Gallo dgallo@nuobit.com

Maintainers
-----------

This module is part of the `NuoBiT/odoo-addons <https://github.com/NuoBiT/odoo-addons/tree/18.0/connector_wordpress_wpml>`_ project on GitHub.

You are welcome to contribute.
1 change: 1 addition & 0 deletions connector_wordpress_wpml/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
20 changes: 20 additions & 0 deletions connector_wordpress_wpml/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# Copyright 2026 NuoBiT Solutions SL - Deniz Gallo <dgallo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

{
"name": "Connector WordPress WMPL",
"version": "18.0.1.0.0",
"author": "NuoBiT Solutions SL",
"license": "AGPL-3",
"category": "Connector",
"website": "https://github.com/NuoBiT/odoo-addons",
"depends": [
"connector_wordpress",
],
"data": [
"views/ir_attachment_views.xml",
"views/res_lang_views.xml",
"views/wordpress_backend_view.xml",
],
}
3 changes: 3 additions & 0 deletions connector_wordpress_wpml/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import backend
from . import ir_attachment
from . import res_lang
1 change: 1 addition & 0 deletions connector_wordpress_wpml/models/backend/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import backend
26 changes: 26 additions & 0 deletions connector_wordpress_wpml/models/backend/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# Copyright 2026 NuoBiT Solutions SL - Deniz Gallo <dgallo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import logging

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

_logger = logging.getLogger(__name__)


class WordPressBackend(models.Model):
_inherit = "wordpress.backend"

@api.constrains("lang_ids")
def check_lang_ids(self):
for rec in self:
for lang in rec.lang_ids:
if not lang.wordpress_wpml_lang_code:
raise ValidationError(
_(
"The language %(lang)s has no WPML code, please define "
"this code in language before using it."
)
% {"lang": lang.name}
)
5 changes: 5 additions & 0 deletions connector_wordpress_wpml/models/ir_attachment/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from . import adapter
from . import binder
from . import binding
from . import export_mapper
from . import exporter
27 changes: 27 additions & 0 deletions connector_wordpress_wpml/models/ir_attachment/adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# Copyright 2026 NuoBiT Solutions SL - Deniz Gallo <dgallo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from odoo.addons.component.core import Component


class WordPressIrAttachment(Component):
_inherit = "wordpress.ir.attachment.adapter"

# def _get_search_fields(self):
# res = super()._get_search_fields()
# res.append("lang")
# return res

def create(self, data): # pylint: disable=W8106
lang = data.pop("lang")
res = super().create(data)
res["lang"] = lang
return res

def write(self, external_id, data): # pylint: disable=W8106
lang = data.pop("lang")
external_id_values = self.binder_for().id2dict(external_id, in_field=False)
res = self._exec("put", f"media/{external_id_values['id']}", data=data)
res["lang"] = lang
return res
52 changes: 52 additions & 0 deletions connector_wordpress_wpml/models/ir_attachment/binder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from odoo.addons.component.core import Component


class WordPressIrAttachmentBinder(Component):
_inherit = "wordpress.ir.attachment.binder"

@property
def external_alt_id(self):
return super().external_alt_id + ["lang"]

# TODO: This funtions are the same as product wpml mixin
def get_binding_domain(self, record):
domain = super().get_binding_domain(record)
wp_wpml_code = self.env["res.lang"]._get_wpml_code_from_iso_code(
record._context.get("lang")
)
if wp_wpml_code:
domain += [
(
"wordpress_lang",
"=",
wp_wpml_code,
)
]
return domain

def _additional_external_binding_fields(self, external_data, relation):
# TODO: this additional fields probably should be
# included in binding as m2o to res lang on upper binder
return {
**super()._additional_external_binding_fields(external_data, relation),
"wordpress_lang": external_data.get("lang") or self.env.context.get("lang"),
}

def _get_external_record_alt(self, relation, id_values):
res = super()._get_external_record_alt(relation, id_values)
if res:
relation_wp_lang = self.env["res.lang"]._get_wpml_code_from_iso_code(
relation.env.context.get("lang")
)
if res.get("lang") != relation_wp_lang:
if res.get("translations") and res["translations"].get(
relation_wp_lang
):
adapter = self.component(usage="backend.adapter")
res = adapter.read(res["translations"][relation_wp_lang])
else:
return None
return res
34 changes: 34 additions & 0 deletions connector_wordpress_wpml/models/ir_attachment/binding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from odoo import fields, models


class WordPressIrAttachment(models.Model):
_inherit = "wordpress.ir.attachment"

wordpress_lang = fields.Char(
string="Language",
required=True,
)

# we overwrite the db constraints, so they must have exactly the same name
# as the parent inherited
_sql_constraints = [
(
"internal_uniq",
"unique(backend_id, odoo_id, wordpress_lang)",
"A binding already exists with the same Internal ID (odoo_id)",
)
]

def _prepare_relation(self, relation, record):
res = super()._prepare_relation(relation, record)
context = relation.env.context.copy()
iso_lang = self.env["res.lang"]._get_iso_code_from_wpml_code(
record.wordpress_lang
)
if iso_lang:
context.update({"lang": iso_lang, "resync_export": True})
relation.env.context = context
return res
18 changes: 18 additions & 0 deletions connector_wordpress_wpml/models/ir_attachment/export_mapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from odoo.addons.component.core import Component
from odoo.addons.connector.components.mapper import changed_by, mapping


class WordPressIrAttachmentExportMapper(Component):
_inherit = "wordpress.ir.attachment.export.mapper"

@changed_by("lang")
@mapping
def lang(self, record):
# TODO: unify this code. Probably do a function in res lang
lang = self.env["res.lang"]._get_wpml_code_from_iso_code(
record._context.get("lang")
)
return {"lang": lang}
25 changes: 25 additions & 0 deletions connector_wordpress_wpml/models/ir_attachment/exporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)

from odoo.addons.component.core import Component


class WordPressIrAttachmentExporter(Component):
_inherit = "wordpress.ir.attachment.record.direct.exporter"

def run(self, relation, always=True, internal_fields=None):
res = []
# langs_to_export = []
# if relation.env.context.get("resync_export"):
# langs_to_export.append(relation.env.context.get("lang"))
# else:
langs_to_export = self.backend_record.lang_ids.mapped("code")

for lang in langs_to_export:
result = super().run(
relation.with_context(lang=lang),
always=always,
internal_fields=internal_fields,
)
res.append(result)
return res
40 changes: 40 additions & 0 deletions connector_wordpress_wpml/models/res_lang.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright NuoBiT Solutions - Kilian Niubo <kniubo@nuobit.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import logging

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError

_logger = logging.getLogger(__name__)


class Lang(models.Model):
_inherit = "res.lang"

wordpress_wpml_lang_code = fields.Char()

_sql_constraints = [
(
"wordpress_wpml_lang_code_uniq",
"unique(wordpress_wpml_lang_code)",
"The WPML lang code must be unique !",
),
]

@api.model
def _get_wpml_code_from_iso_code(self, code):
lang = self.env["res.lang"].search([("code", "=", code)])
if not lang:
raise ValidationError(_("Language not found with code %s") % code)
if not lang.wordpress_wpml_lang_code:
raise ValidationError(_("WPML code not found for lang: %s") % lang)
return lang.wordpress_wpml_lang_code

@api.model
def _get_iso_code_from_wpml_code(self, wpml_code):
lang = self.env["res.lang"].search(
[("wordpress_wpml_lang_code", "=", wpml_code)]
)
if not lang:
raise ValidationError(_("Language not found with wpml code %s") % wpml_code)
return lang.iso_code
3 changes: 3 additions & 0 deletions connector_wordpress_wpml/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
3 changes: 3 additions & 0 deletions connector_wordpress_wpml/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [NuoBiT](https://www.nuobit.com):
- Kilian Niubo <kniubo@nuobit.com>
- Deniz Gallo <dgallo@nuobit.com>
10 changes: 10 additions & 0 deletions connector_wordpress_wpml/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- This module works with plugin WordPress Multi Language.
- <https://wpml.org/>

On WPML settings uncheck the options
- When uploading media to the Media library, make it available in all
languages.
- Duplicate media attachments for translations.

If we don't do this, the media files will be created once for each
language, which it can be a problem for the capacity of the server.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading