Skip to Content

Welcome!

Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together.

Sign up

You need to be registered to interact with the community.
This question has been flagged
1 Reply
36 Views

I'm working on Odoo 18 and trying to add a custom field to the SEO modal popup that appears when editing a page on the website (the “Website > Optimize SEO” dialog). I want to include a field called to let users pick the Schema.org type for the current page (like , , etc.).webpage_schema_typeWebPageContactPage


I managed to create the field on the model and make it available, but I can't figure out how to inject it into the modal form UI. The modal is built using OWL components, and I couldn't find an easy way to extend or patch it.



Here’s what I tried:


1. Field on the model:


from odoo import models, fields


class WebsitePage(models.Model):

    _inherit = 'website.page'


    webpage_schema_type = fields.Selection([

        ('WebPage', 'WebPage'),

        ('AboutPage', 'About Page'),

        ('CheckoutPage', 'Checkout Page'),

        ('CollectionPage', 'Collection Page'),

        ('ContactPage', 'Contact Page'),

        ('FAQPage', 'FAQ Page'),

        ('ProfilePage', 'Profile Page'),

        ('SearchResultsPage', 'Search Results Page'),

    ], string="WebPage Schema Markup", default="WebPage", help="Select Schema Markup for your page. Search engines use structured data to display rich results in SERPs. For more information, visit https://schema.org/WebPage")



2. Trying to patch the modal component (JS):


// In website.assets_editor


/** @odoo-module **/

import { patch } from "@web/core/utils/patch";

import { SeoDialog } from "@website/js/components/dialog/seo";


patch(SeoDialog.prototype, {

    setup() {

        this._super(...arguments);

        this.state.webpage_schema_type = this.props.values.webpage_schema_type || "";

    },

});


But nothing appears in the modal.



What I need:


  • How to properly extend or patch the SEO modal form to show and save my custom field?
  • Do I need to replace the whole component, or is there a cleaner way to inject just one new field?


Any help or example would be appreciated 🙏. I'm open to OWL/JS code if needed. Thanks in advance!


Avatar
Discard

Hi Shravya,
To properly add your webpage_schema_type field to the SEO dialog, you'll need to modify both the Python model and the OWL component. Here's a complete solution:

1. First, ensure your model extension is correct (Python)

python

from odoo import models, fields

class WebsitePage(models.Model):
    _inherit = 'website.page'

    webpage_schema_type = fields.Selection(
        selection=[
            ('WebPage', 'WebPage'),
            ('AboutPage', 'About Page'),
            ('CheckoutPage', 'Checkout Page'),
            ('CollectionPage', 'Collection Page'),
            ('ContactPage', 'Contact Page'),
            ('FAQPage', 'FAQ Page'),
            ('ProfilePage', 'Profile Page'),
            ('SearchResultsPage', 'Search Results Page'),
        ],
        string="Schema.org Type",
        default="WebPage",
        help="Select Schema Markup type for structured data"
    )
2. Create a JS module to extend the SEO dialog

Create a new file in your module: static/src/js/seo_dialog_extension.js

javascript

/** @odoo-module **/

import { patch } from "@web/core/utils/patch";
import { SeoDialog } from "@website/js/components/dialog/seo";

patch(SeoDialog.prototype, {
    setup() {
        super.setup();
        this.schemaOptions = [
            { value: 'WebPage', label: 'WebPage' },
            { value: 'AboutPage', label: 'About Page' },
            { value: 'CheckoutPage', label: 'Checkout Page' },
            { value: 'CollectionPage', label: 'Collection Page' },
            { value: 'ContactPage', label: 'Contact Page' },
            { value: 'FAQPage', label: 'FAQ Page' },
            { value: 'ProfilePage', label: 'Profile Page' },
            { value: 'SearchResultsPage', label: 'Search Results Page' },
        ];
    },

    /**
     * @override
     */
    async willStart() {
        const res = await super.willStart(...arguments);
        this.state.webpage_schema_type = this.initialValues.webpage_schema_type || 'WebPage';
        return res;
    },

    /**
     * @override
     */
    _prepareSEOPayload() {
        const payload = super._prepareSEOPayload();
        payload.webpage_schema_type = this.state.webpage_schema_type;
        return payload;
    },
});

// Add the field to the template
SeoDialog.template = 'your_module.SeoDialogExtended';
3. Create an XML template extension

Add to your module's views: views/seo_dialog_extension.xml

xml

<template id="SeoDialogExtended" inherit_id="website.SeoDialog" name="SEO Dialog Extended">
    <xpath expr="//div[hasclass('o_seo_configuration')]" position="before">
        <div class="form-group">
            <label class="col-form-label">Schema.org Type</label>
            <select t-att-name="'webpage_schema_type'" class="form-select" t-att-value="state.webpage_schema_type">
                <t t-foreach="schemaOptions" t-as="option">
                    <option t-att-value="option.value" t-esc="option.label"/>
                </t>
            </select>
        </div>
    </xpath>
</template>
4. Update your module assets

Add to your module's manifest (__manifest__.py):

python

'assets': {
    'web.assets_frontend': [
        'your_module/static/src/js/seo_dialog_extension.js',
    ],
    'web.assets_qweb': [
        'your_module/views/seo_dialog_extension.xml',
    ],
},
5. Update the website controller (optional)

To make the field available in the editor:

python

class Website(models.Model):
    _inherit = 'website'

    def _prepare_website_page_values(self, page):
        values = super()._prepare_website_page_values(page)
        values['webpage_schema_type'] = page.webpage_schema_type
        return values
Key Points:
  1. The patch modifies the original SeoDialog component to:
    • Add your schema options
    • Include the field in the state
    • Ensure it's saved with the SEO data
  2. The template inheritance adds your field to the existing dialog layout
  3. The manifest updates ensure your JS and XML are properly loaded
  4. This approach doesn't replace the whole component, just extends it cleanly

After implementing this, your field should appear in the SEO dialog and be properly saved with the page data. The value will be available on the website.page model for use in your templates or other business logic.


If this answer helped you save time, money, or frustration, consider:

✅ Upvoting (👍) to help others find it faster

✅ Marking as "Best Answer" if it resolved your issue

Your feedback keeps the Odoo community strong! 💪

(Need further customization? Drop a comment—I’m happy to refine the solution!)

1

Avatar
Discard

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!