英文:
How to render a qweb template by action button?
问题
我有一个Qweb模板,像这样:
<template id="test_template">
<h1>我的模板</h1>
<script type="text/javascript">
console.log('它工作了');
</script>
<div>
<t t-foreach="my_items" t-as="item">
...
</t>
</div>
</template>
我可以通过这样的控制器在网站上呈现它:
@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]})
但我想要能够在框架本身直接呈现这个模板,而不是在单独的网站标签页中呈现,就像使用操作和视图一样。
有什么想法,我该如何做到这一点?
英文:
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
any ideas, how can I do this?
答案1
得分: 1
Odoo将<template>
元素转换为<record>
(在本例中为ir.ui.view
),并不会在JavaScript qweb渲染器函数中可用。
您可以定义一个客户端操作并使用 _rpc
调用模型函数来渲染模板并返回结果。
示例: 调用 ir.ui.view
渲染模板函数
return self.env["ir.ui.view"]._render_template("my_module.test_template",
{'my_items': items}
)
编辑 添加自定义视图以渲染 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'})
在清单文件的 assets/web.assets_backend
下添加以下 JavaScript 代码:
/** @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);
定义一个 qweb_view
视图来调用您的模板并在窗口操作中使用它:
<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>
英文:
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>
答案2
得分: 0
你需要继承设置视图 base.res_config_settings_view_form,如下所示:
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.account</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="40"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Invoicing" string="Invoicing" data-key="account" >
<!-- 这里放置子视图的所有代码 -->
</div>
</xpath>
</field>
</record>
如果还有其他需要翻译的部分,请提供具体内容。
英文:
you a typical view to be inherit the settings view base.res_config_settings_view_form. like the following:
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.account</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="40"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Invoicing" string="Invoicing" data-key="account" >
<!-- Here all your code for sub-views -->
</div>
</xpath>
</field>
</record>
答案3
得分: 0
Here is the translation of the text you provided:
"好的,大家,我花了差不多一个月的时间寻找解决方案,不幸的是,关于我尝试实现的内容,答案有些偏离,但最终我成功了。
我们可以使用 ir.actions.act_window 以 "qweb" 视图模式来完成这项任务。
<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</field>
<field name="view_id" ref="tada.company_structure_test"/>
</record>
这是我的测试模板
<template id="company_structure_test">
<h1>qweb 工作了</h1>
<t t-set="test_data" t-value="model.get_company_structure_data()"/>
<p t-esc="test_data"/>
<p t-esc="test_data['test_str']"/>
<p t-esc="test_data['test_list'][-1]"/>
<script type="text/javascript">
console.log('这不起作用');
</script>
</template>
结果:
我有印象它根本不应该起作用,但以某种方式在这种格式下它确实起作用。顶部的面板可以使用 JavaScript 脚本轻松隐藏,如果需要的话。
但是,如果你想要使用 JavaScript,就会出现问题。我尝试过,但它不起作用。当我使用 request.render('my_template',{}) 时遇到了相同的问题。如果在网站中呈现模板,JavaScript 起作用。如果在 Odoo 本身或空白页面上呈现,JavaScript 就不起作用,在浏览器控制台中没有 console.log。"
Please note that I've left the code parts in their original English since you requested not to translate the code.
英文:
ok guys, I spent almost a month searching for a solution, unfortunately the answers were a bit off about what I was trying to implement, but I got it at some point.
We can use ir.actions.act_window with "qweb" view_mode to get this job done.
<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</field>
<field name="view_id" ref="tada.company_structure_test"/>
</record>
here is my test template
<template id="company_structure_test">
<h1>qweb works</h1>
<t t-set="test_data" t-value="model.get_company_structure_data()"/>
<p t-esc="test_data"/>
<p t-esc="test_data['test_str']"/>
<p t-esc="test_data['test_list'][-1]"/>
<script type="text/javascript">
console.log('this don`t work');
</script>
</template>
and result:
I'm under the impression that it shouldn't work at all, but somehow it does in this format. The panel at the top can be simply hidden using a js script, if necessary
but there is a problem if you want to use js. I tried but it didn't work. i encountered the same problem when using request.render('my_template',{}). If you render your template in website, js works. If in odoo itself or on empty page, js didn`t work. there is no console.log in browser console.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论