Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a qweb template by action button?

Tags:

odoo

qweb

odoo-15

I have Qweb template like this:

<template id="test_template">
    <h1>My template</h1>
    <script type="text/javascript">
        console.log('it works');
    </script>
    <div>
        <t t-foreach="my_items" t-as="item">
            ...
        </t>
    </div>
</template>

I can render it in website by a controller like this

@http.route('/test_template', type="http", auth="user", methods=['GET'], website=True)
    def test_template(self, **kw):
        return request.render('my_module.test_template', {'my_items': [1, 2, 3]})

but I want to be able to render this template not in a separate website tab, but in the framework itself directly, as it works with actions and views enter image description here

any ideas, how can I do this?

like image 577
Wald Sin Avatar asked Jun 30 '26 17:06

Wald Sin


1 Answers

Odoo transforms a <template> element into a <record> (ir.ui.view in this case) and will not be available to the JavaScript qweb renderer function.

You can define a client action and use _rpc to call a model function to render the template and return the result

Example: Call ir.ui.view render template function

return self.env["ir.ui.view"]._render_template("my_module.test_template", 
    {'my_items': items}
)

EDIT Add A custom view to render QWEB

class ActWindowView(models.Model):
    _inherit = 'ir.actions.act_window.view'

    view_mode = fields.Selection(selection_add=[('qweb_view', "QWEB View")], ondelete={'qweb_view': 'cascade'})


class View(models.Model):
    _inherit = 'ir.ui.view'

    type = fields.Selection(selection_add=[('qweb_view', "QWEB View")], ondelete={'qweb_view': 'cascade'})

Add the following JS code under assets/web.assets_backend in the manifest file:

/** @odoo-module **/

import { Renderer, Controller, View } from 'web.qweb';
import registry from 'web.view_registry';


var QwebController = Controller.extend({
    init: function (parent, model, renderer, params) {
        params.withControlPanel = false;
        this._super.apply(this, arguments);
    },
});

var QwebRenderer = Renderer.extend({
    _render: function () {
        var self = this;
        return this._super.apply(this, arguments).then(function () {
            self.$el.html(self.state.body);
            $('head').append(self.$el.find('script'));
        });
    },
});

var QwebView = View.extend({
    config: _.extend({}, View.prototype.config, {
        Controller: QwebController,
        Renderer: QwebRenderer,
    }),
    viewType: 'qweb_view',
    groupable: false,
});

registry.add('qweb_view', QwebView);

Define a qweb_view view to call your template and use it in the window action:

<record model="ir.ui.view" id="company_structure_test">
   <field name="name">company.structure.qweb</field>
   <field name="model">res.company</field>
   <field name="mode">primary</field>
   <field name="arch" type="xml">
       <qweb_view>
            <t t-call="qweb_view.company_structure_test_template">
                <t t-set="model" t-value="res_company"/>
            </t>
        </qweb_view>
    </field>
</record>
        
<record id="action_company_structure" model="ir.actions.act_window">
    <field name="name">Структура компанії</field>
    <field name="res_model">res.company</field>
    <field name="view_mode">qweb_view</field>
    <field name="view_id" ref="company_structure_test"/>
</record>
like image 120
Kenly Avatar answered Jul 04 '26 15:07

Kenly



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!