odoo / owl

OWL: A web framework for structured, dynamic and maintainable applications
https://odoo.github.io/owl/
Other
1.11k stars 334 forks source link

Templates not translated in Odoo env #1553

Closed chrisb-c01 closed 8 months ago

chrisb-c01 commented 8 months ago

Hi,

I'm running into an issue where my component templates are not being translated. Not quite sure if this is an error on the owl side or Odoo side. I do realise that this repo is not for Odoo related issues, however as owl is often used in combination with Odoo I thought it would be OK if I posted it here. Important: I am using owl to render components that are displayed through a public website (so not within Odoo's web client).

An example of my setup, perhaps you can give me a hint on what my error is.

The web controller:

    ...
    @http.route("/some-endpoint", auth="public", website=True)
    def some_endpoint(self):
        return http.request.render("example_module.index")

The template called by the endpoint:

    <template id="index">
        <t t-call="web.frontend_layout">
        <div id="wrap" class="oe_structure oe_empty">
            <div id="some-id" />
        </div>
        </t>
    </template>

My component (example_module/static/src/components/example_component/example_component.js) which is mounted on the div in the index template:

import { templates } from "@web/core/assets";
import { _t } from "@web/core/l10n/translation";
import { makeEnv } from '@web/env';
const { Component, useState, mount, whenReady } = owl;

export class ExampleComponent extends Component {
    setup() {
        super.setup(...arguments);

        this.state = useState({
            ..
        });

    }
};

ExampleComponent.template = "example_module.ExampleComponent";

whenReady(() => {
    if (document.querySelector('#some-id')) {
        const env = makeEnv();
        mount(
            ExampleComponent,
            document.querySelector("#some-id"),
            {
                env, templates, translateFn: _t, dev: true }
        );
    }
});

And its template (example_module/static/src/components/example_component/example_component.xml):

<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

    <t t-name="example_module.ExampleComponent" owl="1">
    <div>Some string</div>
    </t>

</templates>

And the translation file (example_module\i18n\nl.po):

...
#. module: example_module
#. odoo-javascript
#: code:addons/example_module/static/src/components/example_component/example_component.xml:0
#, python-format
msgid "Some string"
msgstr "Translated string"

Also my module manifest:

{
  ..
    "assets": {
        "web.assets_frontend": [
            "example_module/static/src/components/**/*",
        ],
    },
  ..
}
sdegueldre commented 8 months ago

You forgot to start the services, the localization service loads the translations. You can take a look at createPublicRoot in self_order_index.js of the pos_self_order module as an example, as the new pos self ordering app is an owl app served from a controller. But indeed this is not the appropriate repo for this question.

ged-odoo commented 8 months ago

we should have a howto on the official owl documentation for a setup for a controller in odoo with a minimal set of files, owl, templates properly setup, and translations as well

ged-odoo commented 8 months ago

task created id=3580007

chrisb-c01 commented 8 months ago

we should have a howto on the official owl documentation for a setup for a controller in odoo with a minimal set of files, owl, templates properly setup, and translations as well

That would be super helpful!

You forgot to start the services, the localization service loads the translations. You can take a look at createPublicRoot in self_order_index.js of the pos_self_order module as an example, as the new pos self ordering app is an owl app served from a controller. But indeed this is not the appropriate repo for this question.

Thanks for the quick reply @sdegueldre, sometimes it is difficult to pinpoint if its an issue on the owl side or Odoo side. I've added the startServices() as per your recommendation:

if (document.querySelector('#some-div')) {
    await whenReady();
    const env = makeEnv();
    await startServices(env);
    mount(
        ExampleComponent,
        document.querySelector("#some-div"),
        {
            env, templates, translateFn: _t, dev: true }
    );
}

However, I am now faced with all sorts of errors in the console (it even gets in a loop of errors):

Error: Cannot add 'EffectContainer' in the registry: it already exists
Error: Cannot add 'DialogContainer' in the registry: it already exists
Error: Cannot add '...' in the registry: it already exists
TypeError: Cannot redefine property: userContext
OwlError: Cannot make the given value reactive
TypeError: env.services.dialog.add is not a function
Error: UI service not initialized!

I tried to mount an App instance instead of the component itself as per the example you suggested (POS self order), however that did not solve it:

import { Component, whenReady, App } from "@odoo/owl";
const app = new App(ExampleComponent, {
        templates,
        env,
        dev: env.debug,
        translateFn: _t,
        translatableAttributes: [],
    });
app.mount(document.querySelector("#some-id");

Perhaps you have any suggestion?

cc @ged-odoo