Offering snippets to the user

The website designer offers building blocks in website edit mode which can be dragged on the page. This recipe discusses how to offer your own blocks, called snippets, internally.

Getting ready

As we make use of the library.book model, get chapter 4's code for my_module. For convenience, this recipe's code contains a copy of it.

How to do it...

A snippet is actually just a QWeb view that gets injected in the Insert blocks bar, which is defined by a QWeb view itself:

  1. Add a file called views/snippets.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <odoo>
        <template id="book_snippet" inherit_id="website.snippets">
            <!-- points 2, 3 go here /-->
        </template>
    </odoo>
  2. Add a view for your snippet:
    <xpath expr="//div[@id='snippet_feature']/div[@class='o_panel_body']" position="inside">
        <div>
            <div class="oe_snippet_thumbnail">
                <div style="background: white;box-shadow:none" class="oe_snippet_thumbnail_img" >
                    <i class="fa fa-book fa-5x text-muted" />
                </div>
                <span class="oe_snippet_thumbnail_title">Latest books</span>
            </div>
            <div class="oe_snippet_body book_snippet">
                <section class="container">
                    <h2>Latest books</h2>
                    <table class="table">
                        <tr>
                            <th>Name</th>
                            <th>Release date</th>
                        </tr>
                    </table>
                </section>
            </div>
        </div>
    </xpath>
  3. Add options:
    <xpath expr="//div[@id='snippet_options']" position="inside">
        <div data-selector=".book_snippet"
            data-drop-near="p, h1, h2, h3, blockquote, .well, .panel"
            data-drop-in=".content">
            <li class="dropdown-submenu">
                <a href="#">Show books</a>
                <ul class="dropdown-menu">
                    <li data-select_class="book_snippet-show3">
                        <a>3</a>
                    </li>
                    <li data-select_class="book_snippet-show5">
                        <a>5</a>
                    </li>
                    <li data-select_class="book_snippetshow10">
                        <a>10</a>
                    </li>
                    <li data-select_class="book_snippetshow15">
                        <a>15</a>
                    </li>
                </ul>
            </li>
        </div>
        <div data-selector=".book_snippet table">
            <li class="dropdown-submenu">
                <a href="#">Table style</a>
                <ul class="dropdown-menu">
                    <li data-toggle_class="table-striped">
                        <a>Striped</a></li>
                    <li data-toggle_class="tablebordered">
                        <a>Bordered</a></li>
                    <li data-toggle_class="tablecondensed">
                        <a>Condensed</a>
                    </li>
                </ul>
            </li>
        </div>
    </xpath>
  4. Add JavaScript code to populate our snippet:
    odoo.define('ch13_r03.snippets_animation', function(require)
    {
        "use strict";
        var animation = require('web_editor.snippets.animation'),
            Model = require('web.Model');
    
        animation.registry.book_snippet = animation.Class.extend({
            selector: ".book_snippet",
            start: function()
            {
                var self = this,
                    number = 3;
                _.each(this.$el.attr('class').split(/s+/), function(cls)
                {
                    if(cls.indexOf('book_snippet-show') == 0)
                    {
                        number = parseInt(cls.substring('book_snippet-show'.length));
                    }
                });
                this.$el.find('td').parents('tr').remove();
                new Model('library.book')
                .call(
                    'search_read', [],
                    {
                        domain: [],
                        fields: ['name', 'date_release'],
                        order: 'date_release desc',
                        limit: number,
                    })
                .then(function(data)
                {
                    var $table = self.$el.find('table');
                    _.each(data, function(book)
                    {
                        $table.append(
                            jQuery('<tr />')
                            .append(
                                jQuery('<td />').text(book.name),
                                jQuery('<td />').text(book.date_release)
                            )
                        );
                    })
                });
            },
        });
    });

After updating your module, you're offered a snippet called Latest books, which shows a configurable amount of books in a list, ordered by their publication date.

How it works...

You inject your snippet directly into the snippet bar's view. What is crucial is that you attach the right classes and insert your code at the right place.

A snippet needs to have one root element (in our case, the outermost div) that contains an element with the class oe_snippet_thumbnail and another with class oe_snippet_body. The first is used to display the snippet in the bar, the second contains the actual definition of the snippet. For the thumbnail, it makes sense to use a fontawesome icon and add some classes for the layout. For the snippet body, you can add whatever HTML you need for your goals. In general, it's a good idea to use section elements and the bootstrap classes, because, for them, Odoo's editor offers edit and resize controls out of the box.

The position to insert the snippet determines in which section of the bar it shows up. Our choice was //div[@id='snippet_feature']/div[@class='o_panel_body'], which places it in the features section. With the IDs snippet_structure, snippet_content, and snippet_effect, you can place your snippet in the respective other sections.

The div we injected in //div[@id='snippet_options'] offers the user choices in the customize menu. Note the attribute data-selector that contains a JQuery selector determining for which element the option is to be shown. In the example, the first option list is shown when the whole container is selected, while the second one, about the table style, is shown when the table is selected.

The attributes data-drop-near and data-drop-in determine where the snippet can be placed when dragging it out of the snippet bar. Those are also JQuery selectors and, in the example, we allow putting the snippet basically anywhere that content can go.

For the options themselves, the attributes data-select_class and data-toggle_class allow the user to set either one (select) or multiple (toggle) classes on the element selected by the data-selector attribute. Our first set of options sets classes later used by the JavaScript code. The second set of options sets classes directly in the table, which will change its layout accordingly.

The JavaScript code uses the snippet animation framework to execute some code every time the snippet is loaded. We use it to query the current list of books to be presented to the user.

There's more...

After completing this recipe, you know enough to create Odoo themes. An addon is considered a theme if it contains only data files, CSS and JavaScript code. Use QWeb views and snippets to adapt the website's HTML code as necessary and CSS for styling. For the addon to be recognized as such in the app store, the addon's manifest must set the application key to True and use a subcategory of theme, as found on https://www.odoo.com/apps/themes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.102.112