From 9ae7f5a2612a2e69a32d33dca5ba78775a8b09a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= <tde@odoo.com>
Date: Tue, 19 Feb 2019 10:41:15 +0000
Subject: [PATCH] [IMP] website_slides: perform some code linting and re-order
 frontend templates

Purpose is to perform some linting in code. No functional change should
occur with this commit, only some code move. Diff may appear huge but
it is just because some files are split.

This cleaning allow to better understand code and templates architecture
now that eLearning feature has landed in Odoo Community. It will ease future
additions, modifications and fixes.

Containing :
 * [REF] make some internal slide-related methods private as they are not
   intended to be called by outside world;
 * [MOV] new channel invite wizard in wizard folder;
 * [MOV] split frontend templates in some files to better locate code. There is
   now files for homepage, course, lesson, embed and utils in addition to
   slide-related profile template;
 * [REM] dead (unused) templates;

Commit linked to task ID 1941250 and PR #31272.
---
 addons/website_slides/__init__.py             |   1 +
 addons/website_slides/__manifest__.py         |  10 +-
 addons/website_slides/controllers/__init__.py |   1 +
 addons/website_slides/controllers/main.py     |   6 +-
 addons/website_slides/models/__init__.py      |   2 +-
 addons/website_slides/models/slide_channel.py |  75 ++-
 addons/website_slides/models/slide_slide.py   |  54 +-
 .../views/website_slides_templates_course.xml | 420 ++++++++++++++++
 ...ml => website_slides_templates_lesson.xml} | 475 +-----------------
 ...website_slides_templates_lesson_embed.xml} |   0
 .../views/website_slides_templates_utils.xml  |  41 ++
 addons/website_slides/wizard/__init__.py      |   4 +
 .../slide_channel_invite.py                   |   0
 .../slide_channel_invite_views.xml            |   0
 14 files changed, 541 insertions(+), 548 deletions(-)
 create mode 100644 addons/website_slides/views/website_slides_templates_course.xml
 rename addons/website_slides/views/{website_slides_templates.xml => website_slides_templates_lesson.xml} (57%)
 rename addons/website_slides/views/{website_slides_embed_templates.xml => website_slides_templates_lesson_embed.xml} (100%)
 create mode 100644 addons/website_slides/views/website_slides_templates_utils.xml
 create mode 100644 addons/website_slides/wizard/__init__.py
 rename addons/website_slides/{models => wizard}/slide_channel_invite.py (100%)
 rename addons/website_slides/{views => wizard}/slide_channel_invite_views.xml (100%)

diff --git a/addons/website_slides/__init__.py b/addons/website_slides/__init__.py
index 7d34c7c054ab..887107072278 100644
--- a/addons/website_slides/__init__.py
+++ b/addons/website_slides/__init__.py
@@ -3,3 +3,4 @@
 
 from . import controllers
 from . import models
+from . import wizard
diff --git a/addons/website_slides/__manifest__.py b/addons/website_slides/__manifest__.py
index 32b4f407e675..a5df3cf0cefa 100644
--- a/addons/website_slides/__manifest__.py
+++ b/addons/website_slides/__manifest__.py
@@ -25,16 +25,18 @@ Share and Publish Videos, Presentations and Documents'
     'data': [
         'views/assets.xml',
         'views/res_config_settings_views.xml',
-        'views/website_slides_templates_homepage.xml',
-        'views/website_slides_templates.xml',
-        'views/website_slides_embed_templates.xml',
         'views/slide_slide_views.xml',
         'views/slide_channel_partner_views.xml',
         'views/slide_channel_views.xml',
         'views/slide_channel_tag_views.xml',
-        'views/slide_channel_invite_views.xml',
         'views/website_slides_menu_views.xml',
+        'views/website_slides_templates_homepage.xml',
+        'views/website_slides_templates_course.xml',
+        'views/website_slides_templates_lesson.xml',
+        'views/website_slides_templates_lesson_embed.xml',
         'views/website_slides_templates_profile.xml',
+        'views/website_slides_templates_utils.xml',
+        'wizard/slide_channel_invite_views.xml',
         'data/ir_data.xml',
         'data/gamification_data.xml',
         'data/mail_data.xml',
diff --git a/addons/website_slides/controllers/__init__.py b/addons/website_slides/controllers/__init__.py
index acf000fd92cc..5f1516578614 100644
--- a/addons/website_slides/controllers/__init__.py
+++ b/addons/website_slides/controllers/__init__.py
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
 
 from . import mail
 from . import main
diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index 50cea64c0781..f02484629949 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -53,8 +53,8 @@ class WebsiteSlides(WebsiteProfile):
         return True
 
     def _get_slide_detail(self, slide):
-        most_viewed_slides = slide.get_most_viewed_slides(self._slides_per_list)
-        related_slides = slide.get_related_slides(self._slides_per_list)
+        most_viewed_slides = slide._get_most_viewed_slides(self._slides_per_list)
+        related_slides = slide._get_related_slides(self._slides_per_list)
         values = {
             'slide': slide,
             'most_viewed_slides': most_viewed_slides,
@@ -521,7 +521,7 @@ class WebsiteSlides(WebsiteProfile):
     @http.route(['/slides/slide/send_share_email'], type='json', auth='user', website=True)
     def slide_send_share_email(self, slide_id, email):
         slide = request.env['slide.slide'].browse(int(slide_id))
-        result = slide.send_share_email(email)
+        result = slide._send_share_email(email)
         return result
 
     # --------------------------------------------------
diff --git a/addons/website_slides/models/__init__.py b/addons/website_slides/models/__init__.py
index 2768668e3e41..9a55188c7aed 100644
--- a/addons/website_slides/models/__init__.py
+++ b/addons/website_slides/models/__init__.py
@@ -1,11 +1,11 @@
 # -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
 
 from . import gamification_challenge
 from . import slide_slide
 from . import slide_question
 from . import slide_channel
 from . import slide_channel_tag
-from . import slide_channel_invite
 from . import res_config_settings
 from . import website
 from . import res_users
diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py
index 766fde193a0f..edb496a14e8d 100644
--- a/addons/website_slides/models/slide_channel.py
+++ b/addons/website_slides/models/slide_channel.py
@@ -259,41 +259,6 @@ class Channel(models.Model):
             if channel.id:  # avoid to perform a slug on a not yet saved record in case of an onchange.
                 channel.website_url = '%s/slides/%s' % (base_url, slug(channel))
 
-    @api.multi
-    def action_redirect_to_members(self):
-        action = self.env.ref('website_slides.slide_channel_partner_action').read()[0]
-        action['view_mode'] = 'tree'
-        action['domain'] = [('channel_id', 'in', self.ids)]
-        if len(self) == 1:
-            action['context'] = {'default_channel_id': self.id}
-
-        return action
-
-    @api.multi
-    def action_channel_invite(self):
-        self.ensure_one()
-
-        if self.enroll != 'invite':
-            raise UserError(_("You cannot send invitations for channels that are not set as 'invite'."))
-
-        template = self.env.ref('website_slides.mail_template_slide_channel_invite', raise_if_not_found=False)
-
-        local_context = dict(
-            self.env.context,
-            default_channel_id=self.id,
-            default_use_template=bool(template),
-            default_template_id=template and template.id or False,
-            notif_layout='mail.mail_notification_light',
-        )
-        return {
-            'type': 'ir.actions.act_window',
-            'view_type': 'form',
-            'view_mode': 'form',
-            'res_model': 'slide.channel.invite',
-            'target': 'new',
-            'context': local_context,
-        }
-
     # ---------------------------------------------------------
     # ORM Overrides
     # ---------------------------------------------------------
@@ -364,6 +329,41 @@ class Channel(models.Model):
     # Business / Actions
     # ---------------------------------------------------------
 
+    @api.multi
+    def action_redirect_to_members(self):
+        action = self.env.ref('website_slides.slide_channel_partner_action').read()[0]
+        action['view_mode'] = 'tree'
+        action['domain'] = [('channel_id', 'in', self.ids)]
+        if len(self) == 1:
+            action['context'] = {'default_channel_id': self.id}
+
+        return action
+
+    @api.multi
+    def action_channel_invite(self):
+        self.ensure_one()
+
+        if self.visibility != 'invite':
+            raise UserError(_("You cannot send invitations for channels that are not set as 'invite'."))
+
+        template = self.env.ref('website_slides.mail_template_slide_channel_invite', raise_if_not_found=False)
+
+        local_context = dict(
+            self.env.context,
+            default_channel_id=self.id,
+            default_use_template=bool(template),
+            default_template_id=template and template.id or False,
+            notif_layout='mail.mail_notification_light',
+        )
+        return {
+            'type': 'ir.actions.act_window',
+            'view_type': 'form',
+            'view_mode': 'form',
+            'res_model': 'slide.channel.invite',
+            'target': 'new',
+            'context': local_context,
+        }
+
     def action_add_member(self, **member_values):
         """ Adds the logged in user in the channel members.
         (see '_action_add_members' for more info)
@@ -413,11 +413,6 @@ class Channel(models.Model):
         for channel in self:
             channel._action_add_members(channel.mapped('enroll_group_ids.users.partner_id'))
 
-    def list_all(self):
-        return {
-            'channels': [{'id': channel.id, 'name': channel.name, 'website_url': channel.website_url} for channel in self.search([])]
-        }
-
     # ---------------------------------------------------------
     # Rating Mixin API
     # ---------------------------------------------------------
diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py
index fe022f83b31c..24e043be6e30 100644
--- a/addons/website_slides/models/slide_slide.py
+++ b/addons/website_slides/models/slide_slide.py
@@ -77,17 +77,6 @@ class SlideTag(models.Model):
 
 
 class Slide(models.Model):
-    """ This model represents actual presentations. Those must be one of four
-    types:
-
-     - Presentation
-     - Document
-     - Infographic
-     - Video
-     - Webpage
-
-    Slide has various statistics like view count, embed count, like, dislikes """
-
     _name = 'slide.slide'
     _inherit = ['mail.thread', 'website.seo.metadata', 'website.published.mixin', 'rating.mixin']
     _description = 'Slides'
@@ -99,10 +88,6 @@ class Slide(models.Model):
     }
     _order = 'category_sequence asc, sequence asc'
 
-    _sql_constraints = [
-        ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.")
-    ]
-
     def _default_access_token(self):
         return str(uuid.uuid4())
 
@@ -161,13 +146,17 @@ class Slide(models.Model):
     likes = fields.Integer('Likes', compute='_compute_user_info', store=True)
     dislikes = fields.Integer('Dislikes', compute='_compute_user_info', store=True)
     user_vote = fields.Integer('User vote', compute='_compute_user_info')
-    embed_code = fields.Text('Embed Code', readonly=True, compute='_get_embed_code')
+    embed_code = fields.Text('Embed Code', readonly=True, compute='_compute_embed_code')
     # views
     embedcount_ids = fields.One2many('slide.embed', 'slide_id', string="Embed Count")
     slide_views = fields.Integer('# of Website Views', store=True, compute="_compute_slide_views")
     public_views = fields.Integer('# of Public Views')
     total_views = fields.Integer("Total # Views", default="0", compute='_compute_total', store=True)
 
+    _sql_constraints = [
+        ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.")
+    ]
+
     @api.depends('slide_views', 'public_views')
     def _compute_total(self):
         for record in self:
@@ -216,7 +205,8 @@ class Slide(models.Model):
                 self.env['slide.slide.partner']
             )
 
-    def _get_embed_code(self):
+    @api.depends('document_id', 'slide_type', 'mime_type')
+    def _compute_embed_code(self):
         base_url = request and request.httprequest.url_root or self.env['ir.config_parameter'].sudo().get_param('web.base.url')
         if base_url[-1] == '/':
             base_url = base_url[:-1]
@@ -235,7 +225,7 @@ class Slide(models.Model):
                 record.embed_code = False
 
     @api.onchange('url')
-    def on_change_url(self):
+    def _on_change_url(self):
         self.ensure_one()
         if self.url:
             res = self._parse_document_url(self.url)
@@ -250,6 +240,7 @@ class Slide(models.Model):
     @api.multi
     @api.depends('name')
     def _compute_website_url(self):
+        # TDE FIXME: clena this link.tracker strange stuff
         super(Slide, self)._compute_website_url()
         base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
         for slide in self:
@@ -321,6 +312,10 @@ class Slide(models.Model):
             self._post_publication()
         return res
 
+    # ---------------------------------------------------------
+    # Mail/Rating
+    # ---------------------------------------------------------
+
     @api.multi
     def get_access_action(self, access_uid=None):
         """ Instead of the classic form view, redirect to website if it is published. """
@@ -335,10 +330,6 @@ class Slide(models.Model):
             }
         return super(Slide, self).get_access_action(access_uid)
 
-    # ---------------------------------------------------------
-    # Business Methods
-    # ---------------------------------------------------------
-
     @api.multi
     def _notify_get_groups(self, message, groups):
         """ Add access button to everyone if the document is active. """
@@ -350,7 +341,12 @@ class Slide(models.Model):
 
         return groups
 
-    def get_related_slides(self, limit=20):
+    # ---------------------------------------------------------
+    # Business Methods
+    # ---------------------------------------------------------
+
+    def _get_related_slides(self, limit=20):
+        # TDE FIXME: should build a smarter domain
         domain = request.website.website_domain()
         domain += [('website_published', '=', True), ('id', '!=', self.id)]
         if self.category_id:
@@ -358,7 +354,8 @@ class Slide(models.Model):
         for record in self.search(domain, limit=limit):
             yield record
 
-    def get_most_viewed_slides(self, limit=20):
+    def _get_most_viewed_slides(self, limit=20):
+        # TDE FIXME: should build a smarter domain
         domain = request.website.website_domain()
         domain += [('website_published', '=', True), ('id', '!=', self.id)]
         for record in self.search(domain, limit=limit, order='total_views desc'):
@@ -387,10 +384,13 @@ class Slide(models.Model):
             self.write({'access_token': self._default_access_token()})
         return self._sign_token(partner_id)
 
-    @api.one
-    def send_share_email(self, email):
+    def _send_share_email(self, email):
+        # TDE FIXME: template to check
+        mail_ids = []
         base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
-        return self.channel_id.share_template_id.with_context(email=email, base_url=base_url).send_mail(self.id, notif_layout='mail.mail_notification_light')
+        for record in self:
+            mail_ids.append(self.channel_id.share_template_id.with_context(email=email, base_url=base_url).send_mail(record.id, notif_layout='mail.mail_notification_light'))
+        return mail_ids
 
     def action_like(self):
         self.check_access_rights('read')
diff --git a/addons/website_slides/views/website_slides_templates_course.xml b/addons/website_slides/views/website_slides_templates_course.xml
new file mode 100644
index 000000000000..5df196a2e1b4
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_course.xml
@@ -0,0 +1,420 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Channels sub-template: header -->
+<template id="course_nav" name="Course Navigation Header">
+    <div class="o_wslides_course_nav">
+        <div class="container">
+            <div class="row align-items-center justify-content-between">
+                <!-- nav -->
+                <nav aria-label="breadcrumb" class="col-6">
+                    <ol class="breadcrumb">
+                        <li class="breadcrumb-item">
+                            <a href="/slides">Home</a>
+                        </li>
+                        <li t-att-class="'breadcrumb-item %s' % ('active' if not search_category and not search_tag and not search_slide_type else '')">
+                            <a t-att-href="'/slides/%s' % slug(channel)"><span t-esc="channel.name"/></a>
+                        </li>
+                        <li class="breadcrumb-item active" t-att-aria-current="'page' and search_category" t-if="search_category">
+                            <a t-att-href="'/slides/%s/category/%s' % (slug(channel), slug(search_category))"><span t-esc="search_category.name"/></a>
+                        </li>
+                        <li class="breadcrumb-item active" t-att-aria-current="'page' and search_tag" t-if="search_tag">
+                            <a t-att-href="'/slides/%s/tag/%s' % (slug(channel), slug(search_tag))"><span t-esc="search_tag.name"/></a>
+                        </li>
+                        <li class="breadcrumb-item active" t-att-aria-current="'page' and search_slide_type" t-if="search_slide_type">
+                            <a t-att-href="'/slides/%s?slide_type=%s' % (slug(channel), search_slide_type)"><span t-esc="slide_types[search_slide_type]"/></a>
+                        </li>
+                    </ol>
+                </nav>
+                <div class="col-6 d-flex flex-row align-items-center">
+                    <!-- karma / profile -->
+                    <a t-if="not is_public_user" t-att-href="'/profile/user/%s?channel_id=%s' % (user.id, channel.id)" class="font-weight-bold mr-3">
+                        <i class="fa fa-diamond" /> <t t-esc="user_id.karma"/>
+                    </a>
+                    <!-- search -->
+                    <form t-attf-action="/slides/#{slug(channel)}" role="search" method="get">
+                        <div class="input-group">
+                            <input type="text" class="form-control" name="search" t-attf-placeholder="Search in #{channel.name}" t-att-value="search"/>
+                            <span class="input-group-append">
+                                <button class="btn btn-primary" type="submit" aria-label="Search" title="Search">
+                                    <i class="fa fa-search"></i>
+                                </button>
+                            </span>
+                        </div>
+                    </form>
+                    <!-- sort / filter -->
+                    <small class="dropdown float-right ml-3">
+                        <h6 class="m-0">
+                            <button class="btn btn-primary dropdown-toggle" type="button" id="slidesChannelDropdownSort"
+                                data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                                <t t-if="sorting == 'most_voted'">Most Voted</t>
+                                <t t-elif="sorting == 'most_viewed'">Most Viewed</t>
+                                <t t-else="">Newest</t>
+                            </button>
+                            <div class="dropdown-menu" aria-labelledby="slidesChannelDropdownSort" role="menu">
+                                <div role="separator" class="dropdown-header">Sort by</div>
+                                <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', 'slide_type', sorting='latest'))"
+                                    t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'latest' else '')">Newest</a>
+                                <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', 'slide_type', sorting='most_voted'))"
+                                    t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_voted' else '')">Most Voted</a>
+                                <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', 'slide_type', sorting='most_viewed'))"
+                                    t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_viewed' else '')">Most Viewed</a>
+                            </div>
+                        </h6>
+                    </small>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<!-- Channel main template -->
+<template id='course_main' name="Course Main">
+    <t t-set="head">
+        <t t-call-assets="web.pdf_js_lib" t-css="false"/>
+        <script type="text/javascript" src="/website_slides/static/lib/pdfslidesviewer/PDFSlidesViewer.js"></script>
+    </t>
+    <t t-call="website.layout">
+        <div class="wrap o_wslides_wrap">
+            <t t-set="main_object" t-value="channel"/>
+            <t t-call="website_slides.course_nav"/>
+
+            <div class="row o_wslides_course_header">
+                <div class="col-lg-12 o_wslides_container o_wslides_course_header_container">
+                    <div class="row align-items-end">
+                        <div class="col o_wslides_course_header_aside main_image">
+                          <div t-field="channel.image" widget="image" t-options="{'widget': 'image'}"/>
+                        </div>
+                        <div class="col-8 o_wslides_course_header_content">
+                            <h3 class="row"><span class="font-weight-bold col" t-field="channel.name"/></h3>
+                            <div class="row">
+                                <div class="col-12 o_wslides_course_description" t-field="channel.description"/>
+                                <div class="col-6 mt8 mb64">
+                                    <t t-call="website_rating.rating_stars_static_popup_composer">
+                                        <t t-set="rating_avg" t-value="rating_avg"/>
+                                        <t t-set="rating_total" t-value="rating_count"/>
+                                        <t t-set="object" t-value="channel"/>
+                                        <t t-set="hash" t-value="message_post_hash"/>
+                                        <t t-set="pid" t-value="message_post_pid"/>
+                                        <t t-set="default_message_id" t-value="last_message_id"/>
+                                        <t t-set="default_message" t-value="last_message"/>
+                                        <t t-set="default_rating_value" t-value="last_rating_value"/>
+                                        <t t-set="force_submit_url" t-value="'/slides/mail/update_comment' if last_message_id else False"/>
+                                    </t>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="row o_wslides_course_content">
+                <div class="col-lg-12 o_wslides_container o_wslides_content_container">
+                    <div class="row justify-content-end o_wslides_course_content_nav">
+                        <div class="col-8">
+                            <ul class="nav nav-tabs o_wslides_nav_tabs" role="tablist" id="profile_extra_info_tablist">
+                                <li class="nav-item o_wslides_nav_tabs_item_home">
+                                    <a t-att-href="'/slides/%s%s?%s' % (slug(channel), '/%s' % slug(category) if category else '', keep_query('debug'))"
+                                        t-att-class="'nav-link o_wslides_navlink %s' % ('' if search_slide_type else 'active')">
+                                        <i class="fa fa-home"/> Home</a>
+                                </li>
+                                <li class="nav-item">
+                                    <a t-att-href="'/slides/%s' % (slug(channel))"
+                                        t-att-class="'nav-link o_wslides_navlink'">Review</a>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="row o_wslides_course_content_main">
+                        <!-- Channel presentation, aka general information + CTAs -->
+                        <div class="col-4 o_wslides_course_content_aside">
+                            <div class="row justify-content-center mt8 o_wslides_join_channel">
+                                <a t-if="not channel.is_member and channel.enroll == 'public'" role="button"
+                                    class="col-10 btn btn-primary o_wslides_join_channel_link"
+                                    title="Start Course" aria-label="Start Course Channel"
+                                    t-att-href="'#'"
+                                    t-att-data-channel-id="channel.id">
+                                    <span class="cta-title text_small_caps">
+                                        <t t-if="channel.channel_type == 'documentation'">Start Course</t>
+                                        <t t-else="">Join Course</t>
+                                    </span>
+                                </a>
+                                <t t-if="not channel.is_member and channel.enroll == 'invite'">
+                                    <a role="button" class="col-10 btn btn-light" t-att-href="'#'">
+                                        <span class="cta-title text_small_caps">Private Course</span>
+                                    </a>
+                                    <div t-if="channel.enroll_msg" t-field="channel.enroll_msg"/>
+                                    <span t-if="not channel.enroll_msg">Contact website administrator.</span>
+                                </t>
+                                <span t-if="channel.is_member" class="col-10 btn btn-primary">
+                                    <i class="fa fa-chevron-right"></i>
+                                    <span class="cta-title text_small_caps">Already member</span>
+                                </span>
+                            </div>
+                            <div class="row mt8">
+                                <span class="col-5">Last Update</span>
+                                <span class="col"><t t-esc="channel.slide_last_update" t-options="{'widget': 'date'}"/></span>
+                            </div>
+                            <div class="row mt8">
+                                <span class="col-5">Members</span>
+                                <span class="col" t-esc="channel.members_count"/>
+                            </div>
+                            <div class="row mt8"><div class="col"><hr/></div></div>
+                            <t t-set="slide_type_keys" t-value="slide_types.keys()"/>
+                            <t t-foreach="slide_type_keys" t-as="slide_type_key">
+                                <div class="row mt8 align-items-center">
+                                    <span class="col-5">
+                                        <t t-if="search_category">
+                                            <a t-att-href="'/slides/%s/category/%s?%s' % (slug(channel), slug(search_category), keep_query('debug', slide_type=slide_type_key))"
+                                                t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
+                                                <t t-esc="slide_types[slide_type_key]"/>
+                                            </a>
+                                        </t>
+                                        <t t-else="">
+                                            <a t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', slide_type=slide_type_key))"
+                                                t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
+                                                <t t-esc="slide_types[slide_type_key]"/>
+                                            </a>
+                                        </t>
+                                    </span>
+                                    <span class="col">
+                                        <t t-if="search_category">
+                                            <span class="badge badge-pill badge-info" t-esc="search_category['nbr_%ss' % slide_type_key]"/>
+                                        </t>
+                                        <t t-else="">
+                                            <span class="badge badge-pill badge-info" t-esc="channel['nbr_%ss' % slide_type_key]"/>
+                                        </t>
+                                    </span>
+                                </div>
+                            </t>
+                            <div class="row mt8"><div class="col"><hr/></div></div>
+                            <div class="row justify-content-center mt8">
+                                <button role="button" class="btn btn-primary col-10" title="Share Channel"
+                                    aria-label="Share Channel"
+                                    data-toggle="modal" data-target="#slideChannelShareModal">
+                                    <i class="fa fa-share-square"></i> Share
+                                </button>
+                                <div class="modal fade" id="slideChannelShareModal" tabindex="-1" role="dialog" aria-labelledby="slideChannelShareModalLabel" aria-hidden="true">
+                                    <div class="modal-dialog" role="document">
+                                        <div class="modal-content">
+                                            <div class="modal-header">
+                                                <h5 class="modal-title" id="slideChannelShareModalLabel">
+                                                    Share
+                                                </h5>
+                                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                                                    <span>&amp;times;</span>
+                                                </button>
+                                            </div>
+                                            <div class="modal-body">
+                                                <h5>Share on Social Networks</h5>
+                                                <t t-call="website_slides.slides_share">
+                                                    <t t-set="record" t-value="channel"/>
+                                                </t>
+                                                <h5 class="mt16">Share Link</h5>
+                                                <input type="text" class="form-control" readonly="readonly" onclick="this.select();"
+                                                    t-att-value="channel.website_url"/>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
+                            </div>
+                            <div t-if="channel.can_upload" class="row justify-content-center mt8 mb8">
+                                <a role="button" class="btn btn-primary oe_slide_js_upload col-10" title="Upload Presentation"
+                                    aria-label="Upload Presentation" href="#"
+                                    t-att-data-channel-id="channel.id"
+                                    t-att-data-can-upload="channel.can_upload"
+                                    t-att-data-can-publish="channel.can_publish">
+                                    <i class="fa fa-cloud-upload"></i> Upload
+                                </a>
+                            </div>
+                        </div>
+                        <!-- training mode ==============================================-->
+                        <div t-if="channel.channel_type == 'training'" style="width:70%;" class="d-flex align-items-center ml-4 justify-content-center">
+                            <div class="course-content oe_js_course_slides_list" style="width: 100%">
+                                <ul>
+                                    <t t-set="i" t-value="1"/>
+                                    <t t-set="j" t-value="0"/>
+                                    <t t-foreach="channel.category_ids" t-as="category">
+                                        <li t-attf-class="#{'section-draggable' if user == user_id else ''}" t-attf-category_id="#{category.id}">
+                                            <div t-attf-category_id="#{category.id}" class="course-section text-muted font-weight-bold pt-0 pb-0 pl-2 pr-2 d-flex justify-content-between align-items-center">
+                                                <div style="width:50%;" class="d-flex align-items-center">
+                                                    <i t-if="channel.user_id == user" class="fa fa-arrows mr-3 text-muted"></i>
+                                                    <div class="mr-2">Section <span class="section-index" t-esc="i"/>:</div>
+                                                    <span t-field="category.name"/>
+                                                </div>
+                                                <!-- <a t-if="channel.user_id == user" title="Add content to this section" class="mr-2 p-0 oe_slide_js_add_slide"  href="#" t-attf-channel_id="#{channel.id}" t-attf-category_id="#{category.id}">+</a> -->
+                                                <a  class="mr-2 oe_slide_js_upload"
+                                                    role="button"
+                                                    aria-label="Upload Presentation"
+                                                    href="#"
+                                                    style="font-size: 1.5rem;text-decoration: none;"
+                                                    t-att-data-channel-id="channel.id"
+                                                    t-att-data-category-id="category.id"
+                                                    t-att-data-can-upload="channel.can_upload"
+                                                    t-att-data-can-publish="channel.can_publish">+</a>
+                                                <t t-set="i" t-value="i+1"/>
+                                            </div>
+                                            <ul t-attf-category_id="#{category.id}" >
+                                                <t t-foreach="category.slide_ids" t-as="slide">
+                                                    <li t-att-index="j" t-attf-slide_id="#{slide.id}" t-attf-category_id="#{category.id}" t-attf-class="#{'content-slide slide-draggable d-flex justify-content-between align-items-center p-2' if channel.user_id == user else 'content-slide d-flex justify-content-between align-items-center p-2'}">
+                                                        <div class="content-slide-infos ml-2">
+                                                            <i t-if="channel.user_id == user" class="fa fa-arrows mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'document'" class="fa fa-file-pdf-o mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'infographic'" class="fa fa-file-picture-o mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'video'" class="fa fa-play-circle mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'link'" class="fa fa-file-code-o mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'webpage'" class="fa fa-file-text mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'quiz'" class="fa fa-question-circle mr-2 text-muted"></i>
+                                                            <i t-if="slide.slide_type == 'certification'" class="fa fa-trophy mr-2 text-muted"></i>
+                                                            <a class="link-to-slide" t-attf-href="/slides/slide/#{slug(slide)}"><span t-field="slide.name"/></a>
+                                                        </div>
+                                                        <div class="content-slide-controls mr-2">
+                                                            <i t-if="not slide.id in user_progress or not user_progress[slide.id].completed" class="check-done fa fa-check-circle text-muted mr-1"></i>
+                                                            <i t-if="slide.id in user_progress and user_progress[slide.id].completed" class="check-done text-primary fa fa-check-circle mr-1"></i>
+                                                            <a t-if="channel.user_id == user and not slide.slide_type == 'webpage'" t-attf-href="/web#id=#{slide.id}&amp;action=#{slide_action}&amp;model=slide.slide&amp;view_type=form"><i class="fa fa-pencil text-muted mr-1"></i></a>
+                                                            <a t-if="channel.user_id == user and slide.slide_type == 'webpage'" t-attf-href="/slides/slide/#{slug(slide)}?enable_editor=1"><i class="fa fa-pencil text-muted mr-1"></i></a>
+                                                            <i t-if="channel.user_id == user" t-attf-slide_id="#{slide.id}" class="fa fa-trash text-muted oe_slide_js_delete_slide"></i>
+                                                        </div>
+                                                    </li>
+                                                    <t t-set="j" t-value="j+1"/>
+                                                </t>
+                                            </ul>
+                                        </li>
+                                    </t>
+                                </ul>
+                                <div t-if="channel.user_id == user" class="content-actions">
+                                    <a  class="mr-2 oe_slide_js_upload"
+                                        role="button"
+                                        aria-label="Upload Presentation"
+                                        href="#"
+                                        t-att-data-channel-id="channel.id"
+                                        t-att-data-can-upload="channel.can_upload"
+                                        t-att-data-can-publish="channel.can_publish">Add Content</a>
+                                    <a class="oe_slide_js_add_section" t-attf-channel_id="#{channel.id}" href="#">Add Section</a>
+                                </div>
+                            </div>
+                        </div>
+                        <!-- Channel content, aka slides (lessons in documentation mode) -->
+                        <div t-if="channel.channel_type == 'documentation'" class="col-8 mt24 ml32 o_wslides_channel_content_promoted">
+                            <div class="row mt16 align-items-center">
+                                <div class="col">
+                                    <h3><i class="fa fa-plus-square"/> Featured lesson</h3>
+                                    <hr/>
+                                </div>
+                            </div>
+                            <div class="row" t-if="slide_promoted">
+                                <div class="col-4">
+                                    <img class="img img-fluid" style=""
+                                        t-att-src="'/slides/slide/%s/get_image?field=image_large' % slide_promoted.id"
+                                        t-att-alt="slide_promoted.name"/>
+                                </div>
+                                <div class="col-8">
+                                    <div class="row">
+                                        <h3 class="col-6" t-att-title="slide_promoted.name">
+                                            <t t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher">
+                                                <a t-attf-href="/slides/slide/#{slug(slide_promoted)}" class="font-weight-bold text-muted" t-field="slide_promoted.name"/>
+                                            </t>
+                                            <t t-else="">
+                                                <span class="font-weight-bold text-muted" t-field="slide_promoted.name"/>
+                                            </t>
+                                        </h3>
+                                        <div class="col-12" t-field="slide_promoted.description"/>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <!-- Channel content, aka slides (lessons in documentation mode) -->
+                        <div t-if="channel.channel_type == 'documentation'" class="col-12">
+                            <div class="tab-content mt16" id="slideChannelContent">
+                                <div class="tab-pane active" role="tabpanel" aria-labelledby="profile-tab" id="slideChannelContentAbout">
+                                    <t t-foreach="category_data" t-as="category">
+                                        <div class="row mt16 align-items-center">
+                                            <div class="col">
+                                                <a t-att-href="'/slides/%s/category/%s' % (slug(channel), category['id'])" class="float-right">
+                                                    View all
+                                                </a>
+                                                <h3><i class="fa fa-plus-square"/> <t t-esc="category['name']"/></h3>
+                                                <hr/>
+                                            </div>
+                                        </div>
+                                        <t t-call="website_slides.slides_grid_view">
+                                            <t t-set="slides" t-value="category['slides']"/>
+                                        </t>
+                                    </t>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </t>
+</template>
+
+<!-- Embedded template: display a list of slides in a grid view -->
+<template id='slides_grid_view' name="Slides (Grid View)">
+    <div class="row o_wslides_row mt8">
+        <div class="col-lg-3 col-md-6 col-12" t-foreach="slides" t-as="slide">
+            <div class="card o_wslides_lesson_card">
+                <img class="card-img-top img-fuild" style="max-height: 160px;"
+                    t-att-src="'/slides/slide/%s/get_image?field=image_large' % slide.id"
+                    t-att-alt="slide.name"/>
+                <div class="card-body">
+                    <h5 class="card-title" t-att-title="slide.name">
+                        <t t-if="slide.is_preview or channel.is_member or is_slides_publisher">
+                            <a t-attf-href="/slides/slide/#{slug(slide)}" t-esc="slide.name"/>
+                        </t>
+                        <t t-else="">
+                            <span class="text-muted" t-esc="slide.name"/>
+                        </t>
+                    </h5>
+                    <h6 class="card-subtitle mb-2 text-muted">
+                        <t t-if="user.has_group('website.group_website_publisher')">
+                            <i class="fa fa-globe float-right o_wslides_slide_manage_publish"></i>
+                            <i class="fa fa-pencil float-right o_wslides_slide_manage_edit"></i>
+                            <i class="fa fa-trash float-right o_wslides_slide_manage_unlink"></i>
+                        </t>
+                        <t t-if="slide.is_preview">
+                            <span class="badge badge-info">Free preview</span>
+                        </t>
+                        <t t-if="not slide.is_published and user.has_group('website.group_website_publisher')">
+                            <span class="badge badge-danger">Unpublished</span>
+                        </t>
+                    </h6>
+                    <div class="card-text">
+                        <div class="text-muted oe_no_empty" t-field="slide.description"/>
+                        <div t-if="slide.tag_ids">
+                            <t t-foreach="slide.tag_ids" t-as="tag">
+                                <a t-att-href="'/slides/%s/tag/%s' % (slug(slide.channel_id), slug(tag))" class="badge badge-secondary">
+                                    <t t-esc="tag.name"/>
+                                </a>
+                            </t>
+                        </div>
+                    </div>
+                </div>
+                <div class="card-footer">
+                    <!-- CHECKME: like only if logged -->
+                    <div class="float-right text-right o_wslides_like">
+                        <span class="o_wslides_like_up" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
+                            <i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"></i>
+                            <span t-esc="slide.likes"/>
+                        </span>
+                        <span class="o_wslides_like_down" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
+                            <i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"></i>
+                            <span t-esc="slide.dislikes"/>
+                        </span>
+                    </div>
+                    <small class="text-muted">
+                        <t t-call="website_slides.slides_misc_float_time">
+                            <t t-set="value" t-value="slide.completion_time"/>
+                        </t>
+<!--                         <t t-esc="slide.total_views"/> Views
+                        <timeago class="timeago" t-att-datetime="slide.create_date"></timeago> -->
+                    </small>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_templates.xml b/addons/website_slides/views/website_slides_templates_lesson.xml
similarity index 57%
rename from addons/website_slides/views/website_slides_templates.xml
rename to addons/website_slides/views/website_slides_templates_lesson.xml
index 7f0bc0d95536..3b3600b6e470 100644
--- a/addons/website_slides/views/website_slides_templates.xml
+++ b/addons/website_slides/views/website_slides_templates_lesson.xml
@@ -1,454 +1,7 @@
 <?xml version="1.0" ?>
-<odoo>
-<data>
-
-<!-- Tools template: share on social networkds -->
-<template id='slides_share' name="Slides Media Share">
-    <div>
-        <a t-attf-href="https://www.facebook.com/sharer/sharer.php?u=#{record.website_url}" class="o_slides_social_share" social-key="facebook" aria-label="Share on Facebook" title="Share on Facebook"><i class="fa fa-facebook-square fa-2x"/></a>
-        <a t-attf-href="https://twitter.com/intent/tweet?text=#{record.name}&amp;url=#{record.website_url}" class="o_slides_social_share"  social-key="twitter" aria-label="Share on Twitter" title="Share on Twitter"><i class="fa fa-twitter fa-2x"/></a>
-        <a t-attf-href="http://www.linkedin.com/shareArticle?mini=true&amp;url=#{record.website_url}&amp;title=#{record.name}&amp;" social-key="linkedin" class="o_slides_social_share" aria-label="Share on LinkedIn" title="Share on LinkedIn"><i class="fa fa-linkedin fa-2x"/></a>
-    </div>
-</template>
-
-<!-- Channels: no channel found -->
-<template id="channel_not_found" name="Private Presentation">
-    <t t-call="website.layout">
-        <div class="container">
-            <div class="oe_structure">
-                <t t-if="search_term">
-                    <h2>No channel found when searching "<i><t t-esc="search_term"/></i>".</h2>
-                </t>
-                <t t-else="">
-                    <h2>No channel created or published yet.</h2>
-                </t>
-            </div>
-        </div>
-    </t>
-</template>
-
-<!-- Channels sub-template: header -->
-<template id="course_nav" name="Course Navigation Header">
-    <div class="o_wslides_course_nav">
-        <div class="container">
-            <div class="row align-items-center justify-content-between">
-                <!-- nav -->
-                <nav aria-label="breadcrumb" class="col-6">
-                    <ol class="breadcrumb">
-                        <li class="breadcrumb-item">
-                            <a href="/slides">Home</a>
-                        </li>
-                        <li t-att-class="'breadcrumb-item %s' % ('active' if not search_category and not search_tag and not search_slide_type else '')">
-                            <a t-att-href="'/slides/%s' % slug(channel)"><span t-esc="channel.name"/></a>
-                        </li>
-                        <li class="breadcrumb-item active" t-att-aria-current="'page' and search_category" t-if="search_category">
-                            <a t-att-href="'/slides/%s/category/%s' % (slug(channel), slug(search_category))"><span t-esc="search_category.name"/></a>
-                        </li>
-                        <li class="breadcrumb-item active" t-att-aria-current="'page' and search_tag" t-if="search_tag">
-                            <a t-att-href="'/slides/%s/tag/%s' % (slug(channel), slug(search_tag))"><span t-esc="search_tag.name"/></a>
-                        </li>
-                        <li class="breadcrumb-item active" t-att-aria-current="'page' and search_slide_type" t-if="search_slide_type">
-                            <a t-att-href="'/slides/%s?slide_type=%s' % (slug(channel), search_slide_type)"><span t-esc="slide_types[search_slide_type]"/></a>
-                        </li>
-                    </ol>
-                </nav>
-                <div class="col-6 d-flex flex-row align-items-center">
-                    <!-- karma / profile -->
-                    <a t-if="not is_public_user" t-att-href="'/profile/user/%s?channel_id=%s' % (user.id, channel.id)" class="font-weight-bold mr-3">
-                        <i class="fa fa-diamond" /> <t t-esc="user_id.karma"/>
-                    </a>
-                    <!-- search -->
-                    <form t-attf-action="/slides/#{slug(channel)}" role="search" method="get">
-                        <div class="input-group">
-                            <input type="text" class="form-control" name="search" t-attf-placeholder="Search in #{channel.name}" t-att-value="search"/>
-                            <span class="input-group-append">
-                                <button class="btn btn-primary" type="submit" aria-label="Search" title="Search">
-                                    <i class="fa fa-search"></i>
-                                </button>
-                            </span>
-                        </div>
-                    </form>
-                    <!-- sort / filter -->
-                    <small class="dropdown float-right ml-3">
-                        <h6 class="m-0">
-                            <button class="btn btn-primary dropdown-toggle" type="button" id="slidesChannelDropdownSort"
-                                data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                                <t t-if="sorting == 'most_voted'">Most Voted</t>
-                                <t t-elif="sorting == 'most_viewed'">Most Viewed</t>
-                                <t t-else="">Newest</t>
-                            </button>
-                            <div class="dropdown-menu" aria-labelledby="slidesChannelDropdownSort" role="menu">
-                                <div role="separator" class="dropdown-header">Sort by</div>
-                                <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', 'slide_type', sorting='latest'))"
-                                    t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'latest' else '')">Newest</a>
-                                <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', 'slide_type', sorting='most_voted'))"
-                                    t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_voted' else '')">Most Voted</a>
-                                <a role="menuitem" t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', 'slide_type', sorting='most_viewed'))"
-                                    t-att-class="'dropdown-item %s' % ('active' if sorting and sorting == 'most_viewed' else '')">Most Viewed</a>
-                            </div>
-                        </h6>
-                    </small>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<!-- Channel main template -->
-<template id='course_main' name="Course Main">
-    <t t-set="head">
-        <t t-call-assets="web.pdf_js_lib" t-css="false"/>
-        <script type="text/javascript" src="/website_slides/static/lib/pdfslidesviewer/PDFSlidesViewer.js"></script>
-    </t>
-    <t t-call="website.layout">
-        <div class="wrap o_wslides_wrap">
-            <t t-set="main_object" t-value="channel"/>
-            <t t-call="website_slides.course_nav"/>
-
-            <div class="row o_wslides_course_header">
-                <div class="col-lg-12 o_wslides_container o_wslides_course_header_container">
-                    <div class="row align-items-end">
-                        <div class="col o_wslides_course_header_aside main_image">
-                          <div t-field="channel.image" widget="image" t-options="{'widget': 'image'}"/>
-                        </div>
-                        <div class="col-8 o_wslides_course_header_content">
-                            <h3 class="row"><span class="font-weight-bold col" t-field="channel.name"/></h3>
-                            <div class="row">
-                                <div class="col-12 o_wslides_course_description" t-field="channel.description"/>
-                                <div class="col-6 mt8 mb64">
-                                    <t t-call="website_rating.rating_stars_static_popup_composer">
-                                        <t t-set="rating_avg" t-value="rating_avg"/>
-                                        <t t-set="rating_total" t-value="rating_count"/>
-                                        <t t-set="object" t-value="channel"/>
-                                        <t t-set="hash" t-value="message_post_hash"/>
-                                        <t t-set="pid" t-value="message_post_pid"/>
-                                        <t t-set="default_message_id" t-value="last_message_id"/>
-                                        <t t-set="default_message" t-value="last_message"/>
-                                        <t t-set="default_rating_value" t-value="last_rating_value"/>
-                                        <t t-set="force_submit_url" t-value="'/slides/mail/update_comment' if last_message_id else False"/>
-                                    </t>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="row o_wslides_course_content">
-                <div class="col-lg-12 o_wslides_container o_wslides_content_container">
-                    <div class="row justify-content-end o_wslides_course_content_nav">
-                        <div class="col-8">
-                            <ul class="nav nav-tabs o_wslides_nav_tabs" role="tablist" id="profile_extra_info_tablist">
-                                <li class="nav-item o_wslides_nav_tabs_item_home">
-                                    <a t-att-href="'/slides/%s%s?%s' % (slug(channel), '/%s' % slug(category) if category else '', keep_query('debug'))"
-                                        t-att-class="'nav-link o_wslides_navlink %s' % ('' if search_slide_type else 'active')">
-                                        <i class="fa fa-home"/> Home</a>
-                                </li>
-                                <li class="nav-item">
-                                    <a t-att-href="'/slides/%s' % (slug(channel))"
-                                        t-att-class="'nav-link o_wslides_navlink'">Review</a>
-                                </li>
-                            </ul>
-                        </div>
-                    </div>
-                    <div class="row o_wslides_course_content_main">
-                        <!-- Channel presentation, aka general information + CTAs -->
-                        <div class="col-4 o_wslides_course_content_aside">
-                            <div class="row justify-content-center mt8 o_wslides_join_channel">
-                                <a t-if="not channel.is_member and channel.enroll == 'public'" role="button"
-                                    class="col-10 btn btn-primary o_wslides_join_channel_link"
-                                    title="Start Course" aria-label="Start Course Channel"
-                                    t-att-href="'#'"
-                                    t-att-data-channel-id="channel.id">
-                                    <span class="cta-title text_small_caps">
-                                        <t t-if="channel.channel_type == 'documentation'">Start Course</t>
-                                        <t t-else="">Join Course</t>
-                                    </span>
-                                </a>
-                                <t t-if="not channel.is_member and channel.enroll == 'invite'">
-                                    <a role="button" class="col-10 btn btn-light" t-att-href="'#'">
-                                        <span class="cta-title text_small_caps">Private Course</span>
-                                    </a>
-                                    <div t-if="channel.enroll_msg" t-field="channel.enroll_msg"/>
-                                    <span t-if="not channel.enroll_msg">Contact website administrator.</span>
-                                </t>
-                                <span t-if="channel.is_member" class="col-10 btn btn-primary">
-                                    <i class="fa fa-chevron-right"></i>
-                                    <span class="cta-title text_small_caps">Already member</span>
-                                </span>
-                            </div>
-                            <div class="row mt8">
-                                <span class="col-5">Last Update</span>
-                                <span class="col"><t t-esc="channel.slide_last_update" t-options="{'widget': 'date'}"/></span>
-                            </div>
-                            <div class="row mt8">
-                                <span class="col-5">Members</span>
-                                <span class="col" t-esc="channel.members_count"/>
-                            </div>
-                            <div class="row mt8"><div class="col"><hr/></div></div>
-                            <t t-set="slide_type_keys" t-value="slide_types.keys()"/>
-                            <t t-foreach="slide_type_keys" t-as="slide_type_key">
-                                <div class="row mt8 align-items-center">
-                                    <span class="col-5">
-                                        <t t-if="search_category">
-                                            <a t-att-href="'/slides/%s/category/%s?%s' % (slug(channel), slug(search_category), keep_query('debug', slide_type=slide_type_key))"
-                                                t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
-                                                <t t-esc="slide_types[slide_type_key]"/>
-                                            </a>
-                                        </t>
-                                        <t t-else="">
-                                            <a t-att-href="'/slides/%s?%s' % (slug(channel), keep_query('debug', slide_type=slide_type_key))"
-                                                t-att-class="'%s' % ('active' if search_slide_type == slide_type_key else '')">
-                                                <t t-esc="slide_types[slide_type_key]"/>
-                                            </a>
-                                        </t>
-                                    </span>
-                                    <span class="col">
-                                        <t t-if="search_category">
-                                            <span class="badge badge-pill badge-info" t-esc="search_category['nbr_%ss' % slide_type_key]"/>
-                                        </t>
-                                        <t t-else="">
-                                            <span class="badge badge-pill badge-info" t-esc="channel['nbr_%ss' % slide_type_key]"/>
-                                        </t>
-                                    </span>
-                                </div>
-                            </t>
-                            <div class="row mt8"><div class="col"><hr/></div></div>
-                            <div class="row justify-content-center mt8">
-                                <button role="button" class="btn btn-primary col-10" title="Share Channel"
-                                    aria-label="Share Channel"
-                                    data-toggle="modal" data-target="#slideChannelShareModal">
-                                    <i class="fa fa-share-square"></i> Share
-                                </button>
-                                <div class="modal fade" id="slideChannelShareModal" tabindex="-1" role="dialog" aria-labelledby="slideChannelShareModalLabel" aria-hidden="true">
-                                    <div class="modal-dialog" role="document">
-                                        <div class="modal-content">
-                                            <div class="modal-header">
-                                                <h5 class="modal-title" id="slideChannelShareModalLabel">
-                                                    Share
-                                                </h5>
-                                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-                                                    <span>&amp;times;</span>
-                                                </button>
-                                            </div>
-                                            <div class="modal-body">
-                                                <h5>Share on Social Networks</h5>
-                                                <t t-call="website_slides.slides_share">
-                                                    <t t-set="record" t-value="channel"/>
-                                                </t>
-                                                <h5 class="mt16">Share Link</h5>
-                                                <input type="text" class="form-control" readonly="readonly" onclick="this.select();"
-                                                    t-att-value="channel.website_url"/>
-                                            </div>
-                                        </div>
-                                    </div>
-                                </div>
-
-                            </div>
-                            <div t-if="channel.can_upload" class="row justify-content-center mt8 mb8">
-                                <a role="button" class="btn btn-primary oe_slide_js_upload col-10" title="Upload Presentation"
-                                    aria-label="Upload Presentation" href="#"
-                                    t-att-data-channel-id="channel.id"
-                                    t-att-data-can-upload="channel.can_upload"
-                                    t-att-data-can-publish="channel.can_publish">
-                                    <i class="fa fa-cloud-upload"></i> Upload
-                                </a>
-                            </div>
-                        </div>
-                        <!-- training mode ==============================================-->
-                        <div t-if="channel.channel_type == 'training'" style="width:70%;" class="d-flex align-items-center ml-4 justify-content-center">
-                            <div class="course-content oe_js_course_slides_list" style="width: 100%">
-                                <ul>
-                                    <t t-set="i" t-value="1"/>
-                                    <t t-set="j" t-value="0"/>
-                                    <t t-foreach="channel.category_ids" t-as="category">
-                                        <li t-attf-class="#{'section-draggable' if user == user_id else ''}" t-attf-category_id="#{category.id}">
-                                            <div t-attf-category_id="#{category.id}" class="course-section text-muted font-weight-bold pt-0 pb-0 pl-2 pr-2 d-flex justify-content-between align-items-center">
-                                                <div style="width:50%;" class="d-flex align-items-center">
-                                                    <i t-if="channel.user_id == user" class="fa fa-arrows mr-3 text-muted"></i>
-                                                    <div class="mr-2">Section <span class="section-index" t-esc="i"/>:</div>
-                                                    <span t-field="category.name"/>
-                                                </div>
-                                                <!-- <a t-if="channel.user_id == user" title="Add content to this section" class="mr-2 p-0 oe_slide_js_add_slide"  href="#" t-attf-channel_id="#{channel.id}" t-attf-category_id="#{category.id}">+</a> -->
-                                                <a  class="mr-2 oe_slide_js_upload"
-                                                    role="button"
-                                                    aria-label="Upload Presentation"
-                                                    href="#"
-                                                    style="font-size: 1.5rem;text-decoration: none;"
-                                                    t-att-data-channel-id="channel.id"
-                                                    t-att-data-category-id="category.id"
-                                                    t-att-data-can-upload="channel.can_upload"
-                                                    t-att-data-can-publish="channel.can_publish">+</a>
-                                                <t t-set="i" t-value="i+1"/>
-                                            </div>
-                                            <ul t-attf-category_id="#{category.id}" >
-                                                <t t-foreach="category.slide_ids" t-as="slide">
-                                                    <li t-att-index="j" t-attf-slide_id="#{slide.id}" t-attf-category_id="#{category.id}" t-attf-class="#{'content-slide slide-draggable d-flex justify-content-between align-items-center p-2' if channel.user_id == user else 'content-slide d-flex justify-content-between align-items-center p-2'}">
-                                                        <div class="content-slide-infos ml-2">
-                                                            <i t-if="channel.user_id == user" class="fa fa-arrows mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'document'" class="fa fa-file-pdf-o mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'infographic'" class="fa fa-file-picture-o mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'video'" class="fa fa-play-circle mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'link'" class="fa fa-file-code-o mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'webpage'" class="fa fa-file-text mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'quiz'" class="fa fa-question-circle mr-2 text-muted"></i>
-                                                            <i t-if="slide.slide_type == 'certification'" class="fa fa-trophy mr-2 text-muted"></i>
-                                                            <a class="link-to-slide" t-attf-href="/slides/slide/#{slug(slide)}"><span t-field="slide.name"/></a>
-                                                        </div>
-                                                        <div class="content-slide-controls mr-2">
-                                                            <i t-if="not slide.id in user_progress or not user_progress[slide.id].completed" class="check-done fa fa-check-circle text-muted mr-1"></i>
-                                                            <i t-if="slide.id in user_progress and user_progress[slide.id].completed" class="check-done text-primary fa fa-check-circle mr-1"></i>
-                                                            <a t-if="channel.user_id == user and not slide.slide_type == 'webpage'" t-attf-href="/web#id=#{slide.id}&amp;action=#{slide_action}&amp;model=slide.slide&amp;view_type=form"><i class="fa fa-pencil text-muted mr-1"></i></a>
-                                                            <a t-if="channel.user_id == user and slide.slide_type == 'webpage'" t-attf-href="/slides/slide/#{slug(slide)}?enable_editor=1"><i class="fa fa-pencil text-muted mr-1"></i></a>
-                                                            <i t-if="channel.user_id == user" t-attf-slide_id="#{slide.id}" class="fa fa-trash text-muted oe_slide_js_delete_slide"></i>
-                                                        </div>
-                                                    </li>
-                                                    <t t-set="j" t-value="j+1"/>
-                                                </t>
-                                            </ul>
-                                        </li>
-                                    </t>
-                                </ul>
-                                <div t-if="channel.user_id == user" class="content-actions">
-                                    <a  class="mr-2 oe_slide_js_upload"
-                                        role="button"
-                                        aria-label="Upload Presentation"
-                                        href="#"
-                                        t-att-data-channel-id="channel.id"
-                                        t-att-data-can-upload="channel.can_upload"
-                                        t-att-data-can-publish="channel.can_publish">Add Content</a>
-                                    <a class="oe_slide_js_add_section" t-attf-channel_id="#{channel.id}" href="#">Add Section</a>
-                                </div>
-                            </div>
-                        </div>
-                        <!-- Channel content, aka slides (lessons in documentation mode) -->
-                        <div t-if="channel.channel_type == 'documentation'" class="col-8 mt24 ml32 o_wslides_channel_content_promoted">
-                            <div class="row mt16 align-items-center">
-                                <div class="col">
-                                    <h3><i class="fa fa-plus-square"/> Featured lesson</h3>
-                                    <hr/>
-                                </div>
-                            </div>
-                            <div class="row" t-if="slide_promoted">
-                                <div class="col-4">
-                                    <img class="img img-fluid" style=""
-                                        t-att-src="'/slides/slide/%s/get_image?field=image_large' % slide_promoted.id"
-                                        t-att-alt="slide_promoted.name"/>
-                                </div>
-                                <div class="col-8">
-                                    <div class="row">
-                                        <h3 class="col-6" t-att-title="slide_promoted.name">
-                                            <t t-if="slide_promoted.is_preview or channel.is_member or is_slides_publisher">
-                                                <a t-attf-href="/slides/slide/#{slug(slide_promoted)}" class="font-weight-bold text-muted" t-field="slide_promoted.name"/>
-                                            </t>
-                                            <t t-else="">
-                                                <span class="font-weight-bold text-muted" t-field="slide_promoted.name"/>
-                                            </t>
-                                        </h3>
-                                        <div class="col-12" t-field="slide_promoted.description"/>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                        <!-- Channel content, aka slides (lessons in documentation mode) -->
-                        <div t-if="channel.channel_type == 'documentation'" class="col-12">
-                            <div class="tab-content mt16" id="slideChannelContent">
-                                <div class="tab-pane active" role="tabpanel" aria-labelledby="profile-tab" id="slideChannelContentAbout">
-                                    <t t-foreach="category_data" t-as="category">
-                                        <div class="row mt16 align-items-center">
-                                            <div class="col">
-                                                <a t-att-href="'/slides/%s/category/%s' % (slug(channel), category['id'])" class="float-right">
-                                                    View all
-                                                </a>
-                                                <h3><i class="fa fa-plus-square"/> <t t-esc="category['name']"/></h3>
-                                                <hr/>
-                                            </div>
-                                        </div>
-                                        <t t-call="website_slides.slides_grid_view">
-                                            <t t-set="slides" t-value="category['slides']"/>
-                                        </t>
-                                    </t>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </t>
-</template>
-
-<!-- Embedded template: display a list of slides in a grid view -->
-<template id='slides_grid_view' name="Slides (Grid View)">
-    <div class="row o_wslides_row mt8">
-        <div class="col-lg-3 col-md-6 col-12" t-foreach="slides" t-as="slide">
-            <div class="card o_wslides_lesson_card">
-                <img class="card-img-top img-fuild" style="max-height: 160px;"
-                    t-att-src="'/slides/slide/%s/get_image?field=image_large' % slide.id"
-                    t-att-alt="slide.name"/>
-                <div class="card-body">
-                    <h5 class="card-title" t-att-title="slide.name">
-                        <t t-if="slide.is_preview or channel.is_member or is_slides_publisher">
-                            <a t-attf-href="/slides/slide/#{slug(slide)}" t-esc="slide.name"/>
-                        </t>
-                        <t t-else="">
-                            <span class="text-muted" t-esc="slide.name"/>
-                        </t>
-                    </h5>
-                    <h6 class="card-subtitle mb-2 text-muted">
-                        <t t-if="user.has_group('website.group_website_publisher')">
-                            <i class="fa fa-globe float-right o_wslides_slide_manage_publish"></i>
-                            <i class="fa fa-pencil float-right o_wslides_slide_manage_edit"></i>
-                            <i class="fa fa-trash float-right o_wslides_slide_manage_unlink"></i>
-                        </t>
-                        <t t-if="slide.is_preview">
-                            <span class="badge badge-info">Free preview</span>
-                        </t>
-                        <t t-if="not slide.is_published and user.has_group('website.group_website_publisher')">
-                            <span class="badge badge-danger">Unpublished</span>
-                        </t>
-                    </h6>
-                    <div class="card-text">
-                        <div class="text-muted oe_no_empty" t-field="slide.description"/>
-                        <div t-if="slide.tag_ids">
-                            <t t-foreach="slide.tag_ids" t-as="tag">
-                                <a t-att-href="'/slides/%s/tag/%s' % (slug(slide.channel_id), slug(tag))" class="badge badge-secondary">
-                                    <t t-esc="tag.name"/>
-                                </a>
-                            </t>
-                        </div>
-                    </div>
-                </div>
-                <div class="card-footer">
-                    <!-- CHECKME: like only if logged -->
-                    <div class="float-right text-right o_wslides_like">
-                        <span class="o_wslides_like_up" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
-                            <i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"></i>
-                            <span t-esc="slide.likes"/>
-                        </span>
-                        <span class="o_wslides_like_down" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
-                            <i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"></i>
-                            <span t-esc="slide.dislikes"/>
-                        </span>
-                    </div>
-                    <small class="text-muted">
-                        <t t-call="website_slides.slides_misc_float_time">
-                            <t t-set="value" t-value="slide.completion_time"/>
-                        </t>
-<!--                         <t t-esc="slide.total_views"/> Views
-                        <timeago class="timeago" t-att-datetime="slide.create_date"></timeago> -->
-                    </small>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
+<odoo><data>
 
 <!-- Slide: main template: detailed view -->
-<template id="slide_edit_options" inherit_id="website.user_navbar" name="Edit Slide Options">
-    <xpath expr="//li[@id='edit-page-menu']" position="after">
-        <t t-if="main_object._name == 'slide.slide'" t-set="action" t-value="'website_slides.action_slides_slides'" />
-    </xpath>
-</template>
 <template id="slide_detail_view" name="Slide Detailed View">
     <t t-call="website.layout">
         <t t-set="main_object" t-value="slide"/>
@@ -1004,19 +557,6 @@
     </li>
 </template>
 
-
-<!-- Slide sub-template: share: social media -->
-<template id='slide_social_media' name="Share on Social Networks">
-    <h4 class="mt0">Share on Social Networks</h4>
-    <t t-call="website_slides.slides_share">
-        <t t-set="record" t-value="slide"/>
-    </t>
-    <h4 class="mt-3">Share Link</h4>
-    <input type="text" class="form-control" t-att-value="slide.website_url" readonly="readonly" onClick="this.select();"/>
-    <span class="form-text">Use permanent link to share in social media</span>
-</template>
-
-
 <!-- Slide sub-template: share: send by email -->
 <template id='slide_social_email' name="Share by Email">
     <h4 class="mt-3">Share with a friend</h4>
@@ -1057,15 +597,4 @@
     </div>
 </template>
 
-<!-- User Navbar -->
-<template id="user_navbar_inherit_website_slides" inherit_id="website.user_navbar">
-    <xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_slides']" position="attributes">
-        <attribute name="name"/>
-        <attribute name="t-att-data-module-id"/>
-        <attribute name="t-att-data-module-shortdesc"/>
-        <attribute name="groups">website.group_website_designer</attribute>
-    </xpath>
-</template>
-
-</data>
-</odoo>
+</data></odoo>
diff --git a/addons/website_slides/views/website_slides_embed_templates.xml b/addons/website_slides/views/website_slides_templates_lesson_embed.xml
similarity index 100%
rename from addons/website_slides/views/website_slides_embed_templates.xml
rename to addons/website_slides/views/website_slides_templates_lesson_embed.xml
diff --git a/addons/website_slides/views/website_slides_templates_utils.xml b/addons/website_slides/views/website_slides_templates_utils.xml
new file mode 100644
index 000000000000..57d5c2fced5d
--- /dev/null
+++ b/addons/website_slides/views/website_slides_templates_utils.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" ?>
+<odoo><data>
+
+<!-- Share on social networks -->
+<template id='slides_share' name="Slides Media Share">
+    <div>
+        <a t-attf-href="https://www.facebook.com/sharer/sharer.php?u=#{record.website_url}" class="o_slides_social_share" social-key="facebook" aria-label="Share on Facebook" title="Share on Facebook"><i class="fa fa-facebook-square fa-2x"/></a>
+        <a t-attf-href="https://twitter.com/intent/tweet?text=#{record.name}&amp;url=#{record.website_url}" class="o_slides_social_share"  social-key="twitter" aria-label="Share on Twitter" title="Share on Twitter"><i class="fa fa-twitter fa-2x"/></a>
+        <a t-attf-href="http://www.linkedin.com/shareArticle?mini=true&amp;url=#{record.website_url}&amp;title=#{record.name}&amp;" social-key="linkedin" class="o_slides_social_share" aria-label="Share on LinkedIn" title="Share on LinkedIn"><i class="fa fa-linkedin fa-2x"/></a>
+    </div>
+</template>
+
+<!-- Share: social media -->
+<template id='slide_social_media' name="Share on Social Networks">
+    <h4 class="mt0">Share on Social Networks</h4>
+    <t t-call="website_slides.slides_share">
+        <t t-set="record" t-value="slide"/>
+    </t>
+    <h4 class="mt-3">Share Link</h4>
+    <input type="text" class="form-control" t-att-value="slide.website_url" readonly="readonly" onClick="this.select();"/>
+    <span class="form-text">Use permanent link to share in social media</span>
+</template>
+
+<!-- Website edit page -->
+<template id="slide_edit_options" inherit_id="website.user_navbar" name="Edit Slide Options">
+    <xpath expr="//li[@id='edit-page-menu']" position="after">
+        <t t-if="main_object._name == 'slide.slide'" t-set="action" t-value="'website_slides.action_slides_slides'" />
+    </xpath>
+</template>
+
+<!-- User Navbar -->
+<template id="user_navbar_inherit_website_slides" inherit_id="website.user_navbar">
+    <xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_slides']" position="attributes">
+        <attribute name="name"/>
+        <attribute name="t-att-data-module-id"/>
+        <attribute name="t-att-data-module-shortdesc"/>
+        <attribute name="groups">website.group_website_designer</attribute>
+    </xpath>
+</template>
+
+</data></odoo>
diff --git a/addons/website_slides/wizard/__init__.py b/addons/website_slides/wizard/__init__.py
new file mode 100644
index 000000000000..4020988908bf
--- /dev/null
+++ b/addons/website_slides/wizard/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import slide_channel_invite
diff --git a/addons/website_slides/models/slide_channel_invite.py b/addons/website_slides/wizard/slide_channel_invite.py
similarity index 100%
rename from addons/website_slides/models/slide_channel_invite.py
rename to addons/website_slides/wizard/slide_channel_invite.py
diff --git a/addons/website_slides/views/slide_channel_invite_views.xml b/addons/website_slides/wizard/slide_channel_invite_views.xml
similarity index 100%
rename from addons/website_slides/views/slide_channel_invite_views.xml
rename to addons/website_slides/wizard/slide_channel_invite_views.xml
-- 
GitLab