summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorDavid Beguin <dbe@odoo.com>2019-01-24 15:07:11 +0000
committerDavid Beguin <dbe@odoo.com>2019-02-14 08:30:29 +0000
commit336a90e530062b02f3dc66880b0076171758d66e (patch)
tree5eaf358f5527af22ad287aa4b123c4fbebbd063c /addons
parentff870099c588e56e8f041f1d928edd779b1b719c (diff)
[REF] website_forum : use website_profile templates and adds forum specific information
Adds forum specific information into the website_profile template page. Removes everything linked to profile that is already in website_profile module to avoid duplicates. As there can be more than one forum, the profile page shows everything linked to every forum, except if the forum id is given in url arguments. The old route (forum/forum-1/user/user_id) have been kept for backward compatibility reasons. Adds the 'Go to forum' button in the 'new rank reached' mail to encourage the users to continue to be active on the forum as well, to gain more karma point and improve there rank. Image rpc calls have been reviewed for profile page part to use only the standard way to get image -> web/image/model_name/id/image_size Task ID : 1922159 PR #30988
Diffstat (limited to 'addons')
-rw-r--r--addons/website_forum/__manifest__.py1
-rw-r--r--addons/website_forum/controllers/main.py196
-rw-r--r--addons/website_forum/models/forum.py2
-rw-r--r--addons/website_forum/models/res_users.py8
-rw-r--r--addons/website_forum/static/src/scss/website_forum.scss3
-rw-r--r--addons/website_forum/views/website_forum.xml583
-rw-r--r--addons/website_forum/views/website_forum_profile.xml145
7 files changed, 340 insertions, 598 deletions
diff --git a/addons/website_forum/__manifest__.py b/addons/website_forum/__manifest__.py
index 4a9131205d9..02a5fa87fa2 100644
--- a/addons/website_forum/__manifest__.py
+++ b/addons/website_forum/__manifest__.py
@@ -21,6 +21,7 @@ Ask questions, get answers, no distractions
'views/forum.xml',
'views/res_users_views.xml',
'views/website_forum.xml',
+ 'views/website_forum_profile.xml',
'views/ir_qweb.xml',
'security/ir.model.access.csv',
'data/badges_question.xml',
diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py
index 0bc02133bbe..ea85c1de782 100644
--- a/addons/website_forum/controllers/main.py
+++ b/addons/website_forum/controllers/main.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import base64
import json
import lxml
import requests
@@ -10,40 +9,30 @@ import werkzeug.wrappers
from datetime import datetime
-from odoo import http, modules, SUPERUSER_ID, tools, _
+from odoo import http, tools, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.website.models.ir_http import sitemap_qs2dom
+from odoo.addons.website_profile.controllers.main import WebsiteProfile
from odoo.http import request
-class WebsiteForum(http.Controller):
+class WebsiteForum(WebsiteProfile):
_post_per_page = 10
_user_per_page = 30
- def _get_notifications(self):
- badge_subtype = request.env.ref('gamification.mt_badge_granted')
- if badge_subtype:
- msg = request.env['mail.message'].search([('subtype_id', '=', badge_subtype.id), ('needaction', '=', True)])
- else:
- msg = list()
- return msg
-
- def _prepare_forum_values(self, forum=None, **kwargs):
- values = {
- 'user': request.env.user,
- 'is_public_user': request.env.user.id == request.website.user_id.id,
- 'notifications': self._get_notifications(),
+ def _prepare_user_values(self, **kwargs):
+ values = super(WebsiteForum, self)._prepare_user_values(**kwargs)
+ values['forum_welcome_message'] = request.httprequest.cookies.get('forum_welcome_message', False)
+ values.update({
'header': kwargs.get('header', dict()),
'searches': kwargs.get('searches', dict()),
- 'forum_welcome_message': request.httprequest.cookies.get('forum_welcome_message', False),
'validation_email_sent': request.session.get('validation_email_sent', False),
'validation_email_done': request.session.get('validation_email_done', False),
- }
- if forum:
- values['forum'] = forum
+ })
+ if kwargs.get('forum'):
+ values['forum'] = kwargs.get('forum')
elif kwargs.get('forum_id'):
values['forum'] = request.env['forum.forum'].browse(kwargs.pop('forum_id'))
- values.update(kwargs)
return values
# User and validation
@@ -165,7 +154,7 @@ class WebsiteForum(http.Controller):
question_ids = Post.search(domain, limit=self._post_per_page, offset=pager['offset'], order=sorting)
- values = self._prepare_forum_values(forum=forum, searches=post, header={'ask_hide': not forum.active})
+ values = self._prepare_user_values(forum=forum, searches=post, header={'ask_hide': not forum.active})
values.update({
'main_object': tag or forum,
'question_ids': question_ids,
@@ -180,7 +169,7 @@ class WebsiteForum(http.Controller):
@http.route(['''/forum/<model("forum.forum", "[('website_id', 'in', (False, current_website_id))]"):forum>/faq'''], type='http', auth="public", website=True)
def forum_faq(self, forum, **post):
- values = self._prepare_forum_values(forum=forum, searches=dict(), header={'is_guidelines': True}, **post)
+ values = self._prepare_user_values(forum=forum, searches=dict(), header={'is_guidelines': True}, **post)
return request.render("website_forum.faq", values)
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True, sitemap=False)
@@ -210,7 +199,7 @@ class WebsiteForum(http.Controller):
order_by = 'posts_count DESC'
tags = request.env['forum.tag'].search(domain, limit=None, order=order_by)
# prepare values and render template
- values = self._prepare_forum_values(forum=forum, searches={'tags': True}, **post)
+ values = self._prepare_user_values(forum=forum, searches={'tags': True}, **post)
values.update({
'tags': tags,
@@ -256,7 +245,7 @@ class WebsiteForum(http.Controller):
redirect_url = "/forum/%s/question/%s" % (slug(forum), slug(question.parent_id))
return werkzeug.utils.redirect(redirect_url, 301)
filters = 'question'
- values = self._prepare_forum_values(forum=forum, searches=post)
+ values = self._prepare_user_values(forum=forum, searches=post)
values.update({
'main_object': question,
'question': question,
@@ -284,7 +273,7 @@ class WebsiteForum(http.Controller):
def question_ask_for_close(self, forum, question, **post):
reasons = request.env['forum.post.reason'].search([('reason_type', '=', 'basic')])
- values = self._prepare_forum_values(**post)
+ values = self._prepare_user_values(**post)
values.update({
'question': question,
'forum': forum,
@@ -327,7 +316,7 @@ class WebsiteForum(http.Controller):
user = request.env.user
if not user.email or not tools.single_email_re.match(user.email):
return werkzeug.utils.redirect("/forum/%s/user/%s/edit?email_required=1" % (slug(forum), request.session.uid))
- values = self._prepare_forum_values(forum=forum, searches={}, header={'ask_hide': True})
+ values = self._prepare_user_values(forum=forum, searches={}, header={'ask_hide': True})
return request.render("website_forum.new_question", values)
@http.route(['/forum/<model("forum.forum"):forum>/new',
@@ -390,7 +379,7 @@ class WebsiteForum(http.Controller):
def post_edit(self, forum, post, **kwargs):
tags = [dict(id=tag.id, name=tag.name) for tag in post.tag_ids]
tags = json.dumps(tags)
- values = self._prepare_forum_values(forum=forum)
+ values = self._prepare_user_values(forum=forum)
values.update({
'tags': tags,
'post': post,
@@ -458,7 +447,7 @@ class WebsiteForum(http.Controller):
domain = [('forum_id', '=', forum.id), ('state', '=', 'pending')]
posts_to_validate_ids = Post.search(domain)
- values = self._prepare_forum_values(forum=forum)
+ values = self._prepare_user_values(forum=forum)
values.update({
'posts_ids': posts_to_validate_ids,
'queue_type': 'validation',
@@ -478,7 +467,7 @@ class WebsiteForum(http.Controller):
domain += [('name', 'ilike', kwargs.get('spam_post'))]
flagged_posts_ids = Post.search(domain, order='write_date DESC')
- values = self._prepare_forum_values(forum=forum)
+ values = self._prepare_user_values(forum=forum)
values.update({
'posts_ids': flagged_posts_ids,
'queue_type': 'flagged',
@@ -497,7 +486,7 @@ class WebsiteForum(http.Controller):
domain = [('forum_id', '=', forum.id), ('state', '=', 'offensive'), ('active', '=', False)]
offensive_posts_ids = Post.search(domain, order='write_date DESC')
- values = self._prepare_forum_values(forum=forum)
+ values = self._prepare_user_values(forum=forum)
values.update({
'posts_ids': offensive_posts_ids,
'queue_type': 'offensive',
@@ -530,7 +519,7 @@ class WebsiteForum(http.Controller):
def post_ask_for_mark_as_offensive(self, forum, post, **kwargs):
offensive_reasons = request.env['forum.post.reason'].search([('reason_type', '=', 'offensive')])
- values = self._prepare_forum_values(forum=forum)
+ values = self._prepare_user_values(forum=forum)
values.update({
'question': post,
'forum': forum,
@@ -551,7 +540,6 @@ class WebsiteForum(http.Controller):
# User
# --------------------------------------------------
-
@http.route(['''/forum/<model("forum.forum", "[('website_id', 'in', (False, current_website_id))]"):forum>/users''',
'''/forum/<model("forum.forum"):forum>/users/page/<int:page>'''],
type='http', auth="public", website=True)
@@ -568,11 +556,11 @@ class WebsiteForum(http.Controller):
users = User.sudo().search(dom, limit=step, offset=pager['offset'], order='karma DESC')
searches['users'] = 'True'
- values = self._prepare_forum_values(forum=forum, searches=searches)
+ values = self._prepare_user_values(forum=forum, searches=searches)
values .update({
'users': users,
'main_object': forum,
- 'notifications': self._get_notifications(),
+ 'notifications': self._get_badge_granted_messages(),
'pager': pager,
})
@@ -586,77 +574,69 @@ class WebsiteForum(http.Controller):
return werkzeug.utils.redirect("/forum/%s/user/%d" % (slug(forum), partner.user_ids[0].id))
return werkzeug.utils.redirect("/forum/%s" % slug(forum))
- @http.route(['/forum/user/<int:user_id>/avatar'], type='http', auth="public", website=True, sitemap=False)
- def user_avatar(self, user_id=0, **post):
- status, headers, content = request.env['ir.http'].sudo().binary_content(
- model='res.users', id=user_id, field='image_medium', default_mimetype='image/png')
-
- if not content:
- img_path = modules.get_module_resource('web', 'static/src/img', 'placeholder.png')
- with open(img_path, 'rb') as f:
- image = f.read()
- content = base64.b64encode(image)
- if status == 304:
- return werkzeug.wrappers.Response(status=304)
- image_base64 = base64.b64decode(content)
- headers.append(('Content-Length', len(image_base64)))
- response = request.make_response(image_base64, headers)
- response.status = str(status)
- return response
-
+ # Profile
+ # -----------------------------------
@http.route(['/forum/<model("forum.forum"):forum>/user/<int:user_id>'], type='http', auth="public", website=True)
- def open_user(self, forum, user_id=0, **post):
- User = request.env['res.users']
+ def view_user_forum_profile(self, forum, user_id, **post):
+ return werkzeug.utils.redirect('/profile/user/' + str(user_id) + '?forum_id=' + str(forum.id))
+
+ def _prepare_user_profile_values(self, user, **post):
+ values = super(WebsiteForum, self)._prepare_user_profile_values(user, **post)
+ if not post.get('no_forum'):
+ if post.get('forum'):
+ forums = post['forum']
+ elif post.get('forum_id'):
+ forums = request.env['forum.forum'].browse(int(post['forum_id']))
+ values.update({'edit_button_url_param': 'forum_id=' + str(post['forum_id'])})
+ else:
+ forums = request.env['forum.forum'].search([])
+
+ values.update(self._prepare_user_values(forum=forums[0] if len(forums) == 1 else True, **post))
+ if forums:
+ values.update(self._prepare_open_forum_user(user, forums))
+ return values
+
+ def _prepare_open_forum_user(self, user, forums, **kwargs):
Post = request.env['forum.post']
Vote = request.env['forum.post.vote']
Activity = request.env['mail.message']
Followers = request.env['mail.followers']
Data = request.env["ir.model.data"]
- user = User.sudo().search([('id', '=', user_id)])
- current_user = request.env.user.sudo()
-
- # Users with high karma can see users with karma <= 0 for
- # moderation purposes, IFF they have posted something (see below)
- if (not user or (user.karma < 1 and current_user.karma < forum.karma_unlink_all)):
- return werkzeug.utils.redirect("/forum/%s" % slug(forum))
- values = self._prepare_forum_values(forum=forum, **post)
-
# questions and answers by user
user_question_ids = Post.search([
('parent_id', '=', False),
- ('forum_id', '=', forum.id), ('create_uid', '=', user.id)],
+ ('forum_id', 'in', forums.ids), ('create_uid', '=', user.id)],
order='create_date desc')
count_user_questions = len(user_question_ids)
-
- if (user_id != request.session.uid and not
- (user.website_published or
- (count_user_questions and current_user.karma > forum.karma_unlink_all))):
- return request.render("website_forum.private_profile", values, status=404)
+ min_karma_unlink = min(forums.mapped('karma_unlink_all'))
# limit length of visible posts by default for performance reasons, except for the high
# karma users (not many of them, and they need it to properly moderate the forum)
post_display_limit = None
- if current_user.karma < forum.karma_unlink_all:
+ if request.env.user.karma < min_karma_unlink:
post_display_limit = 20
user_questions = user_question_ids[:post_display_limit]
user_answer_ids = Post.search([
('parent_id', '!=', False),
- ('forum_id', '=', forum.id), ('create_uid', '=', user.id)],
+ ('forum_id', 'in', forums.ids), ('create_uid', '=', user.id)],
order='create_date desc')
count_user_answers = len(user_answer_ids)
user_answers = user_answer_ids[:post_display_limit]
# showing questions which user following
- post_ids = [follower.res_id for follower in Followers.sudo().search([('res_model', '=', 'forum.post'), ('partner_id', '=', user.partner_id.id)])]
- followed = Post.search([('id', 'in', post_ids), ('forum_id', '=', forum.id), ('parent_id', '=', False)])
+ post_ids = [follower.res_id for follower in Followers.sudo().search(
+ [('res_model', '=', 'forum.post'), ('partner_id', '=', user.partner_id.id)])]
+ followed = Post.search([('id', 'in', post_ids), ('forum_id', 'in', forums.ids), ('parent_id', '=', False)])
# showing Favourite questions of user.
- favourite = Post.search([('favourite_ids', '=', user.id), ('forum_id', '=', forum.id), ('parent_id', '=', False)])
+ favourite = Post.search(
+ [('favourite_ids', '=', user.id), ('forum_id', 'in', forums.ids), ('parent_id', '=', False)])
# votes which given on users questions and answers.
- data = Vote.read_group([('forum_id', '=', forum.id), ('recipient_id', '=', user.id)], ["vote"], groupby=["vote"])
+ data = Vote.read_group([('forum_id', 'in', forums.ids), ('recipient_id', '=', user.id)], ["vote"],
+ groupby=["vote"])
up_votes, down_votes = 0, 0
for rec in data:
if rec['vote'] == '1':
@@ -669,8 +649,10 @@ class WebsiteForum(http.Controller):
# activity by user.
model, comment = Data.get_object_reference('mail', 'mt_comment')
- activities = Activity.search([('res_id', 'in', (user_question_ids + user_answer_ids).ids), ('model', '=', 'forum.post'), ('subtype_id', '!=', comment)],
- order='date DESC', limit=100)
+ activities = Activity.search(
+ [('res_id', 'in', (user_question_ids + user_answer_ids).ids), ('model', '=', 'forum.post'),
+ ('subtype_id', '!=', comment)],
+ order='date DESC', limit=100)
posts = {}
for act in activities:
@@ -680,15 +662,15 @@ class WebsiteForum(http.Controller):
# TDE CLEANME MASTER: couldn't it be rewritten using a 'menu' key instead of one key for each menu ?
if user == request.env.user:
- post['my_profile'] = True
+ kwargs['my_profile'] = True
else:
- post['users'] = True
+ kwargs['users'] = True
- values.update({
+ values = {
'uid': request.env.user.id,
'user': user,
'main_object': user,
- 'searches': post,
+ 'searches': kwargs,
'questions': user_questions,
'count_questions': count_user_questions,
'answers': user_answers,
@@ -700,55 +682,11 @@ class WebsiteForum(http.Controller):
'activities': activities,
'posts': posts,
'vote_post': vote_ids,
- })
- return request.render("website_forum.user_detail_full", values)
-
- @http.route('/forum/<model("forum.forum"):forum>/user/<model("res.users"):user>/edit', type='http', auth="user", website=True)
- def edit_profile(self, forum, user, **kwargs):
- countries = request.env['res.country'].search([])
- values = self._prepare_forum_values(forum=forum, searches=kwargs)
- values.update({
- 'email_required': kwargs.get('email_required'),
- 'countries': countries,
- 'notifications': self._get_notifications(),
- })
- return request.render("website_forum.edit_profile", values)
-
- @http.route('/forum/<model("forum.forum"):forum>/user/<model("res.users"):user>/save', type='http', auth="user", methods=['POST'], website=True)
- def save_edited_profile(self, forum, user, **kwargs):
- values = {
- 'name': kwargs.get('name'),
- 'website': kwargs.get('website'),
- 'email': kwargs.get('email'),
- 'city': kwargs.get('city'),
- 'country_id': int(kwargs.get('country')) if kwargs.get('country') else False,
- 'website_description': kwargs.get('description'),
+ 'is_profile_page': True,
+ 'badge_category': 'forum',
}
- if 'clear_image' in kwargs:
- values['image'] = False
- elif kwargs.get('ufile'):
- image = kwargs.get('ufile').read()
- values['image'] = base64.b64encode(image)
-
- if request.uid == user.id: # the controller allows to edit only its own privacy settings; use partner management for other cases
- values['website_published'] = kwargs.get('website_published') == 'True'
- user.write(values)
- return werkzeug.utils.redirect("/forum/%s/user/%d" % (slug(forum), user.id))
-
- # Badges
- # --------------------------------------------------
-
- @http.route('''/forum/<model("forum.forum", "[('website_id', 'in', (False, current_website_id))]"):forum>/badge''', type='http', auth="public", website=True)
- def badges(self, forum, **searches):
- Badge = request.env['gamification.badge']
- badges = Badge.sudo().search([('challenge_ids.category', '=', 'forum')])
- badges = sorted(badges, key=lambda b: b.stat_count_distinct, reverse=True)
- values = self._prepare_forum_values(forum=forum, searches={'badges': True})
- values.update({
- 'badges': badges,
- })
- return request.render("website_forum.badge", values)
+ return values
# Messaging
# --------------------------------------------------
diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py
index f515f022961..68d48b8534f 100644
--- a/addons/website_forum/models/forum.py
+++ b/addons/website_forum/models/forum.py
@@ -397,7 +397,7 @@ class Post(models.Model):
res = super(Post, self)._default_website_meta()
res['default_opengraph']['og:title'] = res['default_twitter']['twitter:title'] = self.name
res['default_opengraph']['og:description'] = res['default_twitter']['twitter:description'] = self.plain_content
- res['default_opengraph']['og:image'] = res['default_twitter']['twitter:image'] = "/forum/user/%s/avatar" % (self.create_uid.id)
+ res['default_opengraph']['og:image'] = res['default_twitter']['twitter:image'] = "/web/image/res.users/%s/image" % (self.create_uid.id)
res['default_twitter']['twitter:card'] = 'summary'
return res
diff --git a/addons/website_forum/models/res_users.py b/addons/website_forum/models/res_users.py
index 7482d4a4a9d..b374e5f72ca 100644
--- a/addons/website_forum/models/res_users.py
+++ b/addons/website_forum/models/res_users.py
@@ -86,3 +86,11 @@ class Users(models.Model):
@api.multi
def open_website_url(self):
return self.mapped('partner_id').open_website_url()
+
+ def get_gamification_redirection_data(self):
+ res = super(Users, self).get_gamification_redirection_data()
+ res.append({
+ 'url': '/forum',
+ 'label': 'See our Forum'
+ })
+ return res
diff --git a/addons/website_forum/static/src/scss/website_forum.scss b/addons/website_forum/static/src/scss/website_forum.scss
index 85aaa69317c..8d645e26030 100644
--- a/addons/website_forum/static/src/scss/website_forum.scss
+++ b/addons/website_forum/static/src/scss/website_forum.scss
@@ -169,9 +169,6 @@ $bronze: #eea91e;
border-left: 3px solid;
}
-.o_wforum_people_photo_container {
- width: 33%;
-}
.o_profile_main {
overflow: hidden;
}
diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml
index 43d2a11442f..0b67c78076d 100644
--- a/addons/website_forum/views/website_forum.xml
+++ b/addons/website_forum/views/website_forum.xml
@@ -46,8 +46,111 @@
<div t-field="forum.welcome_message"/>
</div>
- <div class="container mt16 mb32 o_wforum_navbar_container">
- <div class="navbar navbar-expand-md navbar-light">
+ <div class="container mt16 mb32 ">
+ <t t-call="website_forum.forum_nav_header"></t>
+ </div>
+
+ <div id="wrap" t-attf-class="container #{website_forum_action}">
+ <div class="row">
+ <div class="col o_left_forum_container mb16 mt16">
+ <div t-foreach="notifications or []" t-as="notification" class="alert alert-success alert-dismissable" role="status">
+ <button type="button" class="close notification_close" t-att-id="notification.id" data-dismiss="alert" aria-label="Close">&amp;times;</button>
+ <div t-field="notification.body"/>
+ <a t-attf-href="/forum/#{ slug(forum) }/user/#{ user.id }#badges" class="fa fa-arrow-right">View Your Badges</a>
+ </div>
+ <div t-if="not validation_email_sent and not is_public_user and user.karma == 0" class="alert alert-danger alert-dismissable" role="alert">
+ <button type="button" class="close validation_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
+ <div>
+ <p>
+ It appears your email has not been verified.
+ <a class="send_validation_email" href="#" t-att-forum-id="forum.id">Click here to send a verification email allowing you to participate to the forum.</a>
+ </p>
+ </div>
+ </div>
+ <div t-if="validation_email_done" class="alert alert-success alert-dismissable" role="status">
+ <button type="button" class="close validated_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
+ <div>
+ <p>Congratulations! Your email has just been validated. You may now participate to our forums.</p>
+ </div>
+ </div>
+ <t t-raw="0"/>
+ </div>
+ <t t-if="not is_profile_page">
+ <div class="col-lg-3" id="right-column">
+ <a role="button" type="button" class="btn btn-primary btn-lg btn-block mb-3" t-attf-href="/forum/#{slug(forum)}/ask">Ask a Question</a>
+ <div class="card bg-secondary" t-if="question">
+ <h6 class="card-header"><b>Writer</b></h6>
+ <div class="card-body o_card_people">
+ <img class="o_wforum_people_photo_container float-left mr-3" t-attf-src="/web/image/res.users/#{question.create_uid.id}/image_medium"/>
+ <b><i class="fa fa-diamond text-secondary"/> <t t-esc="question.create_uid.sudo().karma"/></b>
+ <h6>
+ <b><a t-attf-href="/forum/#{slug(forum)}/user/#{question.create_uid.sudo().id}" t-field="question.create_uid" t-options='{"widget": "contact", "fields": ["name", "country_id"]}'/></b>
+ </h6>
+ </div>
+ </div>
+ <div class="card my-3 bg-secondary" t-if="question and not len(question.tag_ids)&lt;=0">
+ <h6 class="card-header">
+ <b>
+ <t t-if="len(question.tag_ids)&lt;=1">
+ Tag
+ </t>
+ <t t-else="">
+ Tags
+ </t>
+ </b>
+ </h6>
+ <div class="card-body">
+ <t t-foreach="question.tag_ids" t-as="tag">
+ <a t-attf-href="/forum/#{ slug(forum) }/tag/#{ tag.id }/questions" class="badge badge-primary" t-field="tag.name"/>
+ </t>
+ </div>
+ </div>
+ <div class="card my-3 bg-secondary" t-if="question">
+ <h6 class="card-header"><b>Keep Informed</b></h6>
+ <div class="card-body o_subscribe_post">
+ <t t-call="website_mail.follow">
+ <t t-set="object" t-value="question"/>
+ <t t-set="div_class" t-value="'mx-auto'"/>
+ </t>
+ <div class="text-center mt-3">
+ <strong><t t-raw="len(question.message_follower_ids)"/> follower(s)</strong>
+ </div>
+ </div>
+ </div>
+ <div class="card my-3 bg-secondary" id="about_forum">
+ <h6 class="card-header"><b>About This Community</b></h6>
+ <div class="card-body">
+ <span t-field="forum.description"/>
+ <a t-if="not header.get('is_guidelines')" t-attf-href="/forum/#{slug(forum)}/faq" class="btn btn-primary mt-3">Read Guidelines</a>
+ <a t-if="header.get('is_guidelines')" t-attf-href="/forum/#{slug(forum)}" class="btn btn-primary mt-3"> Back to <span t-field="forum.name"/></a>
+ </div>
+ </div>
+ <div class="card my-3 bg-secondary" id="moderation_tools" t-if="user.karma>=forum.karma_moderate">
+ <h6 class="card-header"><b>Moderation Tools</b></h6>
+ <div class="card-body">
+ <a t-attf-href="/forum/#{slug(forum)}/validation_queue" class="text-dark"><i class="fa fa-check-square-o mr-2 text-primary"/><strong><t t-esc="forum.count_posts_waiting_validation"/></strong> waiting for validation</a>
+ <hr style="margin-top:4px;margin-bottom:0;padding-bottom:4px;" />
+ <a t-attf-href="/forum/#{slug(forum)}/flagged_queue" class="text-dark"><i class="fa fa-flag mr-2 text-primary"/><strong id="count_flagged_posts"><t t-esc="forum.count_flagged_posts"/></strong> post<t t-if="forum.count_flagged_posts&gt;1">s</t> flagged</a>
+ </div>
+ </div>
+ </div>
+ </t>
+ </div>
+ </div>
+ <div class="oe_structure" id="oe_structure_website_forum_header_1"/>
+ </t>
+ <t t-else="" t-call="website_forum.layout">
+ <t t-set="head">
+ <meta name="robots" content="noindex, nofollow" />
+ </t>
+ <div class="text-center text-muted">
+ <p class="css_editable_hidden"><h2>This forum has been archived.</h2></p>
+ </div>
+ </t>
+</template>
+
+<template id="forum_nav_header">
+ <div class="navbar navbar-expand-md navbar-light">
<a class="navbar-brand" t-attf-href="/forum/#{slug(forum)}">
<span t-field="forum.name"/>
</a>
@@ -73,7 +176,7 @@
t-attf-class="nav-link #{searches.get('tags') and 'active' or ''}">Tags</a>
</li>
<li class="nav-item">
- <a t-attf-href="/forum/#{ slug(forum) }/badge"
+ <a t-attf-href="/profile/badge?category=forum"
t-attf-class="nav-link #{searches.get('badges') and 'active' or ''}">Badges</a>
</li>
<li class="nav-item" t-if="user.karma >= forum.karma_moderate">
@@ -83,7 +186,7 @@
</ul>
<ul class="navbar-nav ml-auto">
<li t-if="not is_public_user" class="nav-item">
- <a t-attf-href="/forum/#{ slug(forum) }/user/#{uid}" t-attf-class="text-dark font-weight-bold nav-link#{searches.get('my_profile') and ' active' or ''}">
+ <a t-attf-href="/profile/user/#{uid}?forum_id=#{forum.id}" t-attf-class="text-dark font-weight-bold nav-link#{searches.get('my_profile') and ' active' or ''}">
<i class="fa fa-diamond text-secondary" /> <t t-esc="user_id.karma"/>
</a>
</li>
@@ -102,103 +205,6 @@
</form>
</div>
</div>
- </div>
-
- <div id="wrap" t-attf-class="container #{website_forum_action}">
- <div class="row">
- <div class="col-lg-9 o_left_forum_container mb16">
- <div t-foreach="notifications or []" t-as="notification" class="alert alert-success alert-dismissable" role="status">
- <button type="button" class="close notification_close" t-att-id="notification.id" data-dismiss="alert" aria-label="Close">&amp;times;</button>
- <div t-field="notification.body"/>
- <a t-attf-href="/forum/#{ slug(forum) }/user/#{ user.id }#badges" class="fa fa-arrow-right">View Your Badges</a>
- </div>
- <div t-if="not validation_email_sent and not is_public_user and user.karma == 0" class="alert alert-danger alert-dismissable" role="alert">
- <button type="button" class="close validation_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
- <div>
- <p>
- It appears your email has not been verified.
- <a class="send_validation_email" href="#" t-att-forum-id="forum.id">Click here to send a verification email allowing you to participate to the forum.</a>
- </p>
- </div>
- </div>
- <div t-if="validation_email_done" class="alert alert-success alert-dismissable" role="status">
- <button type="button" class="close validated_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
- <div>
- <p>Congratulations! Your email has just been validated. You may now participate to our forums.</p>
- </div>
- </div>
- <t t-raw="0"/>
- </div>
- <div class="col-lg-3" id="right-column">
- <a role="button" type="button" class="btn btn-primary btn-lg btn-block mb-3" t-attf-href="/forum/#{slug(forum)}/ask">Ask a Question</a>
- <div class="card bg-secondary" t-if="question">
- <h6 class="card-header"><b>Writer</b></h6>
- <div class="card-body o_card_people">
- <img class="o_wforum_people_photo_container float-left mr-3" t-attf-src="/forum/user/#{question.create_uid.id}/avatar"/>
- <b><i class="fa fa-diamond text-secondary"/> <t t-esc="question.create_uid.sudo().karma"/></b>
- <h6>
- <b><a t-attf-href="/forum/#{slug(forum)}/user/#{question.create_uid.sudo().id}" t-field="question.create_uid" t-options='{"widget": "contact", "fields": ["name", "country_id"]}'/></b>
- </h6>
- </div>
- </div>
- <div class="card my-3 bg-secondary" t-if="question and not len(question.tag_ids)&lt;=0">
- <h6 class="card-header">
- <b>
- <t t-if="len(question.tag_ids)&lt;=1">
- Tag
- </t>
- <t t-else="">
- Tags
- </t>
- </b>
- </h6>
- <div class="card-body">
- <t t-foreach="question.tag_ids" t-as="tag">
- <a t-attf-href="/forum/#{ slug(forum) }/tag/#{ tag.id }/questions" class="badge badge-primary" t-field="tag.name"/>
- </t>
- </div>
- </div>
- <div class="card my-3 bg-secondary" t-if="question">
- <h6 class="card-header"><b>Keep Informed</b></h6>
- <div class="card-body o_subscribe_post">
- <t t-call="website_mail.follow">
- <t t-set="object" t-value="question"/>
- <t t-set="div_class" t-value="'mx-auto'"/>
- </t>
- <div class="text-center mt-3">
- <strong><t t-raw="len(question.message_follower_ids)"/> follower(s)</strong>
- </div>
- </div>
- </div>
- <div class="card my-3 bg-secondary" id="about_forum">
- <h6 class="card-header"><b>About This Community</b></h6>
- <div class="card-body">
- <span t-field="forum.description"/>
- <a t-if="not header.get('is_guidelines')" t-attf-href="/forum/#{slug(forum)}/faq" class="btn btn-primary mt-3">Read Guidelines</a>
- <a t-if="header.get('is_guidelines')" t-attf-href="/forum/#{slug(forum)}" class="btn btn-primary mt-3"> Back to <span t-field="forum.name"/></a>
- </div>
- </div>
- <div class="card my-3 bg-secondary" id="moderation_tools" t-if="user.karma>=forum.karma_moderate">
- <h6 class="card-header"><b>Moderation Tools</b></h6>
- <div class="card-body">
- <a t-attf-href="/forum/#{slug(forum)}/validation_queue" class="text-dark"><i class="fa fa-check-square-o mr-2 text-primary"/><strong><t t-esc="forum.count_posts_waiting_validation"/></strong> waiting for validation</a>
- <hr style="margin-top:4px;margin-bottom:0;padding-bottom:4px;" />
- <a t-attf-href="/forum/#{slug(forum)}/flagged_queue" class="text-dark"><i class="fa fa-flag mr-2 text-primary"/><strong id="count_flagged_posts"><t t-esc="forum.count_flagged_posts"/></strong> post<t t-if="forum.count_flagged_posts&gt;1">s</t> flagged</a>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="oe_structure" id="oe_structure_website_forum_header_1"/>
- </t>
- <t t-else="" t-call="website_forum.layout">
- <t t-set="head">
- <meta name="robots" content="noindex, nofollow" />
- </t>
- <div class="text-center text-muted">
- <p class="css_editable_hidden"><h2>This forum has been archived.</h2></p>
- </div>
- </t>
</template>
<!-- Template use to edit the welcome_message -->
@@ -218,14 +224,14 @@
<div class="row">
<div class="col-12">
<t t-foreach="question.tag_ids" t-as="question_tag">
- <a t-attf-href="/forum/#{ slug(forum) }/tag/#{slug(question_tag)}/questions">
+ <a t-attf-href="/forum/#{ slug(question_tag.forum_id) }/tag/#{slug(question_tag)}/questions">
<span t-attf-class="float-right mb-1 mr-1 badge #{tag and tag.name == question_tag.name and 'badge-primary' or 'badge-secondary'}" t-field="question_tag.name"/>
</a>
</t>
</div>
<div class="col">
<div class="question-name">
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(question) }">
+ <a t-attf-href="/forum/#{ slug(question.forum_id) }/question/#{ slug(question) }">
<h4 t-field="question.name" class="d-inline"/>
</a>
<span t-if="not question.active and question.state!='offensive'"><b> [Deleted]</b></span>
@@ -240,12 +246,12 @@
<span class="ml-4 mr-1 fa fa-calendar"></span><span t-field="question.write_date" t-options='{"format":"short"}'/>
<span class="ml-4 mr-1 fa fa-eye"></span><span t-field="question.views" /> <t t-if="question.views&lt;=1">View</t><t t-else="">Views</t>
<i class="ml-4 fa fa-comments text-primary"/>
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(question) }">
+ <a t-attf-href="/forum/#{ slug(question.forum_id) }/question/#{ slug(question) }">
<t t-esc="question.child_count"/>
<t t-if="question.child_count&lt;=1">Answer</t>
<t t-else="">Answers</t>
</a>
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(question) }">
+ <a t-attf-href="/forum/#{ slug(question.forum_id) }/question/#{ slug(question) }">
<span class="ml-4 mr-1 fa fa-star"></span><span t-field="question.favourite_count"/> <t t-if="question.views&lt;=1">Favorite</t><t t-else="">Favorites</t>
</a>
<t t-if="question.state == 'flagged'" class="text-black">
@@ -282,7 +288,7 @@
<div t-attf-class="#{len(answer.vote_ids) and 'oe_green' or 'oe_grey'}" t-esc="len(answer.vote_ids)"/>
</div>
<div class="question-name col">
- <a style="font-size: 15px;" t-attf-href="/forum/#{ slug(forum) }/question/#{ answer.parent_id.id }/#answer-#{ answer.id }" t-esc="answer.parent_id.name"/>
+ <a style="font-size: 15px;" t-attf-href="/forum/#{ slug(answer.forum_id) }/question/#{ answer.parent_id.id }/#answer-#{ answer.id }" t-esc="answer.parent_id.name"/>
<t t-if="len(answer.website_message_ids)&gt;0">
(<t t-esc="len(answer.website_message_ids)"/>
<t t-if="len(answer.website_message_ids)&gt;1"> Comments</t>
@@ -308,7 +314,7 @@
<template id="moderation_display_post_answer">
<div class="clearfix">
<div class="question-name">
- <a style="font-size: 15px;" t-attf-href="/forum/#{ slug(forum) }/question/#{ answer.parent_id.id }/#answer-#{ answer.id }" t-esc="answer.parent_id.name"/>
+ <a style="font-size: 15px;" t-attf-href="/forum/#{ slug(answer.forum_id) }/question/#{ answer.parent_id.id }/#answer-#{ answer.id }" t-esc="answer.parent_id.name"/>
<b>[Answer]</b>
<span t-if="not answer.active and answer.state=='offensive'"><b> [Offensive]</b></span>
<span t-if="not answer.active and answer.state=='offensive' and answer.closed_reason_id"><b> [<t t-esc="answer.closed_reason_id.name[0].upper() + answer.closed_reason_id.name[1:]"/>]</b></span>
@@ -872,7 +878,7 @@
<t t-call="website_forum.forum_user_tooltip"/>
</div>
<a t-att-href="user_profile_url" class="o_forum_user_info">
- <img class="float-left o_forum_avatar" t-attf-src="/forum/user/#{answer.create_uid.id}/avatar" alt="Avatar"/>
+ <img class="float-left o_forum_avatar" t-attf-src="/web/image/res.users/#{answer.create_uid.id}/image_medium" alt="Avatar"/>
</a>
<a t-att-href="user_profile_url"
t-field="answer.create_uid"
@@ -928,7 +934,7 @@
<div class="o_forum_user_bio text-left card">
<div class="card-body">
<a t-att-href="user_profile_url">
- <img class="float-left img rounded o_forum_avatar_big" t-attf-src="/forum/user/#{answer.create_uid.id}/avatar" alt="Avatar"/>
+ <img class="float-left img rounded o_forum_avatar_big" t-attf-src="/web/image/res.users/#{answer.create_uid.id}/image_medium" alt="Avatar"/>
</a>
<div class="o_forum_tooltip_header">
<h4 class="o_forum_tooltip_heading"><a t-att-href="user_profile_url"
@@ -1037,35 +1043,6 @@
</t>
</template>
-<template id="badge" name="Forum Badges">
- <t t-call="website_forum.header">
- <h1 class="o_page_header">
- Badges
- </h1>
- <p>
- Besides gaining reputation with your questions and answers,
- you receive badges for being especially helpful. Badges
- appear on your profile page, and your posts.
- </p>
- <table class="table mt32 mb64">
- <tr t-foreach="badges" t-as="badge">
- <td>
- <span class="badge badge-pill float-left">
- <span t-if="badge.level == 'gold'"><i class="fa fa-trophy badge-gold"/> <b t-field="badge.name" class="text-white bg-gold badge-pill"/></span>
- <span t-if="badge.level == 'silver'"><i class="fa fa-trophy badge-silver"/> <b t-field="badge.name" class="text-white bg-silver badge-pill"/></span>
- <span t-if="badge.level == 'bronze'"><i class="fa fa-trophy badge-bronze"/> <b t-field="badge.name" class="text-white bg-bronze badge-pill"/></span>
- </span>
- </td><td>
- <b t-esc="badge.stat_count_distinct"/>
- <i class="text-muted"> awarded users</i>
- </td><td>
- <span t-field="badge.description"/>
- </td>
- </tr>
- </table>
- </t>
-</template>
-
<template id="moderation_queue" name="Forum Moderation Queue">
<t t-call="website_forum.header">
<t t-set="website_forum_action" t-value="'o_wforum_moderation_queue'"/>
@@ -1114,7 +1091,7 @@
<input type="checkbox" t-att-value="user.id" class="custom-control-input" t-attf-id="user_#{user.id}"/>
<label class="custom-control-label" t-attf-for="user_#{user.id}">
<div class="col-11 d-inline-flex">
- <img class="d-inline img o_forum_avatar" t-attf-src="/forum/user/#{user.id}/avatar" alt="Avatar"/>
+ <img class="d-inline img o_forum_avatar" t-attf-src="/web/image/res.users/#{user.id}/image_medium" alt="Avatar"/>
<b t-esc="user.name" class="d-inline"></b>
</div>
</label>
@@ -1204,9 +1181,9 @@
<div t-foreach="users" t-as="u" class="col-xl-4 col-md-6 col-sm-12 mb-4">
<div class="card o_card_people h-100">
<div class="card-body">
- <img class="o_wforum_people_photo_container float-left mr-3" t-attf-src="/forum/user/#{u.id}/avatar"/>
+ <img class="o_wforum_people_photo_container float-left mr-3" t-attf-src="/web/image/res.users/#{u.id}/image_medium"/>
<b><i class="text-secondary mr-1 fa fa-diamond"/><t t-esc="u.karma"/></b>
- <h4 class="font-weight-bold o_card_people_name"><a t-attf-href="/forum/#{slug(forum)}/user/#{u.id}" t-field="u.name"/></h4>
+ <h4 class="font-weight-bold o_card_people_name"><a t-attf-href="/profile/user/#{u.id}?forum_id=#{forum.id}" t-field="u.name"/></h4>
<t t-if="u.country_id">
<span t-field="u.country_id.image" t-options='{"widget": "image", "class": "country_flag_people"}'/>
</t>
@@ -1233,330 +1210,6 @@
</t>
</template>
-<!--Private profile-->
-<template id="private_profile">
- <t t-call="website_forum.header">
- <t t-set="head">
- <t t-raw="head"/>
- <meta name="robots" content="noindex follow"/>
- </t>
- <h1 class="mt32">This profile is private!</h1>
- <p>
- <a t-attf-href="/forum/#{slug(forum)}">Return to the question list.</a>
- </p>
- </t>
-</template>
-
-<template id="edit_profile" name="Forum Edit Profile">
- <t t-call="website_forum.header">
- <h1 class="o_page_header">Edit Profile</h1>
- <div>
- <form t-attf-action="/forum/#{slug(forum)}/user/#{slug(user)}/save" method="post" role="form" class="js_website_submit_form row" enctype="multipart/form-data">
- <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
- <input type="file" class="d-none o_forum_file_upload" name="ufile" accept="image/*"/>
- <div class="col-3">
- <div class="card o_card_people">
- <div class="card-body">
- <img class="w-100 mb-3" t-attf-src="/forum/user/#{user.id}/avatar"/>
- <div class="text-center">
- <a href="#" class="o_forum_profile_pic_edit btn btn-primary" aria-label="Edit">
- <i class="fa fa-pencil fa-1g float-sm-none float-md-left" title="Edit"></i>
- </a>
- <a href="#" title="Clear" aria-label="Clear" class="btn border-primary">
- <i class="fa fa-trash-o float-sm-none float-md-right o_forum_profile_pic_clear"></i>
- </a>
- </div>
- <div class="form-group mt-3 mb-0 pt-2 border-top">
- <label class="text-primary" for="user_website_published" t-if="user.id == uid"><b>Public profile</b></label>
- <div class=" mb-0 float-right" t-if="user.id == uid">
- <input type="checkbox" class="mt8" name="website_published" id="user_website_published" value="True" t-if="not user.website_published"/>
- <input type="checkbox" class="mt8" name="website_published" id="user_website_published" value="True" checked="checked" t-if="user.website_published"/>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="col-9 mb-3">
- <div class="card">
- <div class="card-body">
- <div class="row">
- <input name="user_id" t-att-value="user.id" type="hidden"/>
- <div class="form-group col-12">
- <label class="text-primary mb-1 d-block" for="user_name"><b>Real name</b></label>
- <div>
- <input type="text" class="form-control" name="name" id="user_name" required="True" t-attf-value="#{user.name}"/>
- </div>
- </div>
-
- <div class="form-group col-6">
- <label class="mb-1 text-primary" for="user_website"><b>Website</b></label>
- <div>
- <input type="text" class="form-control" name="website" id="user_website" t-attf-value="#{user.partner_id.website or ''}"/>
- </div>
- </div>
- <div class="form-group col-6">
- <div t-if="email_required" class="alert alert-danger alert-dismissable oe_forum_email_required" role="alert">
- <button type="button" class="close" data-dismiss="alert">x</button>
- <p>Please enter a valid email address in order to receive notifications from answers or comments.</p>
- </div>
- <label class="mb-1 text-primary" for="user_email"><b>Email</b></label>
- <div>
- <input type="text" class="form-control" name="email" id="user_email" required="True" t-attf-value="#{user.partner_id.email}"/>
- </div>
- </div>
- <div class="form-group col-6">
- <label class="mb-1 text-primary" for="user_city"><b>City</b></label>
- <div>
- <input type="text" class="form-control" name="city" id="user_city" t-attf-value="#{user.partner_id.city or ''}"/>
- </div>
- </div>
- <div class="form-group col-6">
- <label class="mb-1 text-primary"><b>Country</b></label>
- <div>
- <select class="form-control" name="country">
- <option value="">Country...</option>
- <t t-foreach="countries or []" t-as="country">
- <option t-att-value="country.id" t-att-selected="country.id == user.partner_id.country_id.id"><t t-esc="country.name"/></option>
- </t>
- </select>
- </div>
- </div>
- <!--Note: using website_description fiels instead of using commnt firld of partner-->
- <div class="form-group col-12">
- <label class="mb-1 text-primary" for="description"><b>Biography</b></label>
- <textarea name="description" id="description" style="min-height: 120px" required="True"
- class="form-control load_editor"><t t-esc="user.partner_id.website_description"/></textarea>
- </div>
- <div class="col">
- <button type="submit" class="btn btn-primary btn">Update</button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </form>
- </div>
- </t>
-</template>
-
-<template id="user_detail_full">
- <t t-call="website_forum.header">
- <a class="float-right mt-3"
- t-if="request.env.user == user"
- t-attf-href="/forum/#{slug(forum)}/user/#{slug(user)}/edit">Edit<i class="fa fa-angle-right ml-2"/>
- </a>
- <h1 class="o_page_header">Profile</h1>
- <div class="o_profile_main row">
- <div class="col-md-4">
- <div class="card o_card_people">
- <div class="card-header">
- <img class="o_wforum_people_photo_container float-left mr-3" t-attf-src="/forum/user/#{user.id}/avatar"/>
- <h3 class="text-primary o_card_people_name"><b t-field="user.name"/></h3>
- </div>
- <div class="card-body">
- <b class="text-muted">Karma</b>
- <span class="float-right"><i class="fa fa-diamond text-secondary mr-2"/><b t-field="user.karma"/></span>
- <div class="border-top mt-2 pt-2">
- <b class="text-muted">Badges</b>
- <span class="float-right">
- <i class="fa fa-trophy badge-gold" role="img" aria-label="Gold badge" title="Gold badge"/>
- <b t-esc="user.gold_badge" class=""/>
- <i class="fa fa-trophy badge-silver ml16" role="img" aria-label="Silver badge" title="Silver badge"/>
- <b t-esc="user.silver_badge" class="" />
- <i class="fa fa-trophy badge-bronze ml16" role="img" aria-label="Bronze badge" title="Bronze badge"/>
- <b t-esc="user.bronze_badge" class="" />
- </span>
- </div>
- <div class="border-top mt-2 pt-2">
- <b class="text-muted">Votes</b>
- <span class="float-right">
- <i class="fa fa-thumbs-up text-success" role="img" aria-label="Positive votes" title="Positive votes"/>
- <b t-esc="up_votes"/>
- <i class="fa fa-thumbs-down text-danger ml-3" role="img" aria-label="Negative votes" title="Negative votes"/>
- <b t-esc="down_votes"/>
- </span>
- </div>
- </div>
- </div>
- </div>
- <div class="col-md-8">
- <b class="text-muted">Contribution</b>
- <div class="card mt-1 mb-4">
- <div class="card-body">
- <div class="row">
- <div class="col-4">
- <b class="text-primary">Member since</b>
- </div>
- <div class="col">
- <span t-field="user.create_date" t-options='{"format": "short"}'/>
- </div>
- </div>
- <div class="border-top pt-2 mt-2 ">
- <div class="row">
- <div class="col-4">
- <b class="text-primary">Last connection</b>
- </div>
- <div class="col">
- <span t-field="user.login_date" t-options='{"format": "short"}'/>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <b class="text-muted">Bio</b>
- <div class="card mt-1 mb-4">
- <div class="card-body">
- <div class="row">
- <div class="col-4">
- <b class="text-primary">Location</b>
- </div>
- <div class="col">
- <t t-if="user.country_id"> <span t-field="user.country_id.image" t-options='{"widget": "image", "class": "country_flag"}' class="mr-2"/></t>
- <span t-field="user.city"/>
- <span t-if="user.city and user.country_id">, </span>
- <span t-field="user.country_id"/>
- </div>
- </div>
- <div class="border-top pt-2 mt-2">
- <div class="row">
- <div class="col-4">
- <b class="text-primary">Website</b>
- </div>
- <div class="col">
- <a t-att-href="user.website" t-if="user.website">
- <span t-field="user.website"/>
- </a>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <b class="text-muted">Introduction</b>
- <div class="card mt-1 mb-4">
- <div class="card-body">
- <span t-field="user.partner_id.website_description" class="oe_no_empty"/>
- </div>
- </div>
- </div>
- </div>
-
- <ul class="nav nav-tabs" role="tablist">
- <li class="nav-item">
- <a role="tab" aria-controls="questions" href="#questions" class="nav-link active" data-toggle="tab"><t t-esc="count_questions"/> Questions</a>
- </li>
- <li class="nav-item">
- <a role="tab" aria-controls="answers" href="#answers" class="nav-link" data-toggle="tab"><t t-esc="count_answers"/> Answers</a>
- </li>
- <li t-if="uid == user.id" class="nav-item">
- <a role="tab" aria-controls="favourite_question" href="#favourite_question" class="nav-link" data-toggle="tab"><t t-esc="len(favourite)"/> Favourite Questions</a>
- </li>
- <li t-if="uid == user.id" class="nav-item">
- <a role="tab" aria-controls="followed_question" href="#followed_question" class="nav-link" data-toggle="tab"><t t-esc="len(followed)"/> Followed Questions</a>
- </li>
- <li t-if="uid == user.id" class="nav-item">
- <a role="tab" aria-controls="activity" href="#activity" class="nav-link" data-toggle="tab">Activity</a>
- </li>
- <li class="nav-item">
- <a role="tab" aria-controls="badges" href="#badges" class="nav-link" data-toggle="tab">Badges</a>
- </li>
- <li t-if="uid == user.id" class="nav-item">
- <a role="tab" aria-controls="votes" href="#votes" class="nav-link" data-toggle="tab">Votes</a>
- </li>
- </ul>
- <div class="tab-content mt16">
- <div role="tabpanel" class="tab-pane active" id="questions">
- <div class="mb16" t-foreach="questions" t-as="question">
- <t t-call="website_forum.display_post"/>
- </div>
- </div><div role="tabpanel" class="tab-pane" id="answers">
- <div t-foreach="answers" t-as="answer">
- <t t-call="website_forum.display_post_answer"/>
- </div>
- </div>
- <div role="tabpanel" class="tab-pane" id="karma">
- <h1>Karma</h1>
- </div>
- <div role="tabpanel" class="tab-pane" id="badges">
- <t t-call="website_forum.user_badges"/>
- </div>
- <div role="tabpanel" class="tab-pane" id="favourite_question" t-if="uid == user.id">
- <div t-foreach="favourite" t-as="question">
- <t t-call="website_forum.display_post"/>
- </div>
- </div>
- <div role="tabpanel" class="tab-pane" id="followed_question" t-if="uid == user.id">
- <div t-foreach="followed" t-as="question" class="mb16">
- <t t-call="website_forum.display_post"/>
- </div>
- </div>
- <div role="tabpanel" class="tab-pane" id="votes" t-if="uid == user.id">
- <t t-call="website_forum.user_votes"/>
- </div>
- <div role="tabpanel" class="tab-pane" id="activity" t-if="uid == user.id">
- <div t-foreach="activities" t-as="activity" class="card mb-2">
- <div class="card-body">
- <span t-esc="activity.subtype_id.name" class="badge badge-info mr-2 mt-1"/>
- <span t-field="activity.date" t-options='{"format": "short"}' class="mr-2"/>
- <t t-set="post" t-value="posts[activity.res_id]"/>
- <span t-if="post[1]">
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post[0]) }#answer-#{ str(post[1].id) }">
- <span t-esc="post[0].name"/>
- </a>
- </span>
- <span t-if="not post[1]">
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post[0]) }">
- <span t-esc="post[0].name"/>
- </a>
- </span>
- </div>
- </div>
- </div>
- </div>
- </t>
-</template>
-
-<template id="user_badges">
- <table class="table mt32 mb64">
- <tr t-foreach="user.badge_ids" t-as="badge">
- <td>
- <span class="badge badge-pill float-left">
- <span t-if="badge.level == 'gold'"><i class="fa fa-trophy badge-gold"/> <b t-field="badge.badge_id.name" class="text-white bg-gold badge-pill"/></span>
- <span t-if="badge.level == 'silver'"><i class="fa fa-trophy badge-silver"/> <b t-field="badge.badge_id.name" class="text-white bg-silver badge-pill"/></span>
- <span t-if="badge.level == 'bronze'"><i class="fa fa-trophy badge-bronze"/> <b t-field="badge.badge_id.name" class="text-white bg-bronze badge-pill"/></span>
- </span>
- </td><td>
- <b t-esc="badge.badge_id.stat_count_distinct"/>
- <i class="text-muted">awarded users</i>
- </td><td>
- <span t-field="badge.badge_id.description"/>
- </td>
- </tr>
- </table>
- <div class="mb16" t-if="not user.badge_ids">
- <b>No badge yet!</b><br/>
- <a t-attf-href="/forum/#{ slug(forum) }/badge" class="fa fa-arrow-right"> Check available badges</a>
- </div>
-</template>
-
-<template id="user_votes">
- <div t-foreach="vote_post" t-as="vote">
- <t t-esc="vote.post_id.create_date"/>
- <span t-if="vote.vote == '1'" class="fa fa-thumbs-up text-success" style="margin-left:30px" role="img" aria-label="Positive vote" title="Positive vote"/>
- <span t-if="vote.vote == '-1'" class="fa fa-thumbs-down text-warning" style="margin-left:30px" role="img" aria-label="Negative vote" title="Negative vote"/>
- <t t-if="vote.post_id.parent_id">
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ vote.post_id.parent_id.id }/#answer-#{ vote.post_id.id }" t-esc="vote.post_id.parent_id.name" style="margin-left:10px"/>
- </t>
- <t t-if="not vote.post_id.parent_id">
- <a t-attf-href="/forum/#{ slug(forum) }/question/#{ vote.post_id.id }" style=" color:black;margin-left:10px" t-esc="vote.post_id.name"/>
- </t>
- </div>
- <div class="mb16" t-if="not vote_post">
- <b>No vote given by you yet!</b>
- </div>
-</template>
-
<!-- User Navbar -->
<template id="user_navbar_inherit_website_forum" inherit_id="website.user_navbar">
<xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_forum']" position="attributes">
diff --git a/addons/website_forum/views/website_forum_profile.xml b/addons/website_forum/views/website_forum_profile.xml
new file mode 100644
index 00000000000..3cdac8b35c4
--- /dev/null
+++ b/addons/website_forum/views/website_forum_profile.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+ <!--Private profile-->
+ <template id="private_profile" inherit_id="website_profile.private_profile">
+ <xpath expr="//div[@id='private_profile_return_link_container']" position="inside">
+ <t t-if="request.params.get('forum_id')">
+ <a t-attf-href="/forum/forum-#{request.params.get('forum_id')}">Return to the forum.</a>
+ </t>
+ </xpath>
+ </template>
+
+ <template id="user_profile_content" inherit_id="website_profile.user_profile_content">
+ <xpath expr="//tr[@id='profile_abstract_info_company']" position="after">
+ <t t-if="forum and (up_votes or down_votes)">
+ <tr id="profile_abstract_info_company">
+ <th style="width: 30%"><b class="text-muted">Votes</b></th>
+ <th style="width: 70%">
+ <span>
+ <i class="fa fa-thumbs-up text-success" role="img" aria-label="Positive votes" title="Positive votes"/>
+ <b t-esc="up_votes"/>
+ <i class="fa fa-thumbs-down text-danger ml-3" role="img" aria-label="Negative votes" title="Negative votes"/>
+ <b t-esc="down_votes"/>
+ </span>
+ </th>
+ </tr>
+ </t>
+ </xpath>
+ <xpath expr="//ul[@id='profile_extra_info_tablist']" position="inside">
+ <t t-if="forum">
+ <li class="nav-item">
+ <a role="tab" aria-controls="questions" href="#questions" class="nav-link o_wprofile_navlink" data-toggle="tab"><t t-esc="count_questions"/> Questions</a>
+ </li>
+ <li class="nav-item">
+ <a role="tab" aria-controls="answers" href="#answers" class="nav-link o_wprofile_navlink" data-toggle="tab"><t t-esc="count_answers"/> Answers</a>
+ </li>
+ <li t-if="uid == user.id" class="nav-item">
+ <a role="tab" aria-controls="activity" href="#activity" class="nav-link o_wprofile_navlink" data-toggle="tab">Activity</a>
+ </li>
+ <li t-if="uid == user.id" class="nav-item">
+ <a role="tab" aria-controls="votes" href="#votes" class="nav-link o_wprofile_navlink" data-toggle="tab">Votes</a>
+ </li>
+ </t>
+ </xpath>
+ <xpath expr="//div[@id='profile_extra_info_tabcontent']" position="inside">
+ <t t-if="forum">
+ <div role="tabpanel" class="tab-pane" id="questions">
+ <div class="mb32">
+ <h4><i class="fa fa-question"/> Questions</h4>
+ <t t-if="questions">
+ <div class="mb16" t-foreach="questions" t-as="question">
+ <t t-call="website_forum.display_post"/>
+ </div>
+ </t>
+ <t t-else="">
+ <b>No question posted yet.</b>
+ </t>
+ </div>
+ <t t-if="favourite">
+ <div class="mb32">
+ <h4><i class="fa fa-star"/> Favourite Questions</h4>
+ <div t-foreach="favourite" t-as="question">
+ <t t-call="website_forum.display_post"/>
+ </div>
+ </div>
+ </t>
+ <t t-if="followed">
+ <div class="mb32">
+ <h4><i class="fa fa-eye"/> Followed Questions</h4>
+ <div t-foreach="followed" t-as="question" class="mb16">
+ <t t-call="website_forum.display_post"/>
+ </div>
+ </div>
+ </t>
+ </div>
+ <div role="tabpanel" class="tab-pane" id="answers">
+ <div class="mb32">
+ <h4><i class="fa fa-reply"/> Answers</h4>
+ <t t-if="answers">
+ <div t-foreach="answers" t-as="answer">
+ <t t-call="website_forum.display_post_answer"/>
+ </div>
+ </t>
+ <t t-else="">
+ <b>No answer posted yet.</b>
+ </t>
+ </div>
+ </div>
+ <div role="tabpanel" class="tab-pane" id="votes" t-if="uid == user.id">
+ <div class="mb32">
+ <h4><i class="fa fa-thumbs-up"/> Votes</h4>
+ <t t-call="website_forum.user_votes"/>
+ </div>
+ </div>
+ <div role="tabpanel" class="tab-pane" id="activity" t-if="uid == user.id">
+ <div class="mb32">
+ <h4><i class="fa fa-history"/> Activities</h4>
+ <t t-call="website_forum.display_activities"/>
+ </div>
+ </div>
+ </t>
+ </xpath>
+ </template>
+
+ <template id="display_activities" name="Forum Profile Activities">
+ <t t-if="activities">
+ <div t-foreach="activities" t-as="activity" class="card mb-2">
+ <div class="card-body">
+ <span t-esc="activity.subtype_id.name" class="badge badge-info mr-2 mt-1"/>
+ <span t-field="activity.date" t-options='{"format": "short"}' class="mr-2"/>
+ <t t-set="post" t-value="posts[activity.res_id]"/>
+ <span t-if="post[1]">
+ <a t-attf-href="/forum/#{ slug(post[0].forum_id) }/question/#{ slug(post[0]) }#answer-#{ str(post[1].id) }">
+ <span t-esc="post[0].name"/>
+ </a>
+ </span>
+ <span t-if="not post[1]">
+ <a t-attf-href="/forum/#{ slug(post[0].forum_id) }/question/#{ slug(post[0]) }">
+ <span t-esc="post[0].name"/>
+ </a>
+ </span>
+ </div>
+ </div>
+ </t>
+ <t t-else="">
+ <b>No activities yet!</b>
+ </t>
+ </template>
+
+ <template id="user_votes" name="Forum User Votes">
+ <div t-foreach="vote_post" t-as="vote">
+ <t t-esc="vote.post_id.create_date"/>
+ <span t-if="vote.vote == '1'" class="fa fa-thumbs-up text-success" style="margin-left:30px" role="img" aria-label="Positive vote" title="Positive vote"/>
+ <span t-if="vote.vote == '-1'" class="fa fa-thumbs-down text-warning" style="margin-left:30px" role="img" aria-label="Negative vote" title="Negative vote"/>
+ <t t-if="vote.post_id.parent_id">
+ <a t-attf-href="/forum/#{ slug(vote.post_id.forum_id) }/question/#{ vote.post_id.parent_id.id }/#answer-#{ vote.post_id.id }" t-esc="vote.post_id.parent_id.name" style="margin-left:10px"/>
+ </t>
+ <t t-if="not vote.post_id.parent_id">
+ <a t-attf-href="/forum/#{ slug(vote.post_id.forum_id) }/question/#{ vote.post_id.id }" style=" color:black;margin-left:10px" t-esc="vote.post_id.name"/>
+ </t>
+ </div>
+ <div class="mb16" t-if="not vote_post">
+ <b>No vote given by you yet!</b>
+ </div>
+ </template>
+</data></odoo>