From aaf37d8e87488f7fa627a447eac13d4e7e004f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Maes?= Date: Fri, 19 Dec 2014 15:56:07 +0100 Subject: [PATCH] [IMP] website_blog : allow multi tags and date filter, clean all the routes, remove group_comment from website_mail (only user and portal can post comment on blog.post, but the form is visible for all), modify the redirect controller to the login form when posting comment, and remove the description field of blog.blog --- addons/website/views/website_templates.xml | 6 +- addons/website_blog/controllers/main.py | 118 ++++++++++-------- .../website_blog/data/website_blog_data.xml | 1 - addons/website_blog/models/website_blog.py | 4 +- .../static/src/js/website_blog.editor.js | 4 +- .../src/js/website_blog.inline.discussion.js | 18 +-- .../tests/test_website_blog_flow.py | 1 - .../views/website_blog_templates.xml | 45 ++++--- .../website_blog/views/website_blog_views.xml | 5 +- addons/website_mail/__openerp__.py | 1 - addons/website_mail/security/website_mail.xml | 15 --- 11 files changed, 115 insertions(+), 103 deletions(-) delete mode 100644 addons/website_mail/security/website_mail.xml diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 7c9935d2130..ea2467cf808 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -364,10 +364,8 @@ diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index 163dbb4b0bd..0885eb5a427 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -1,12 +1,14 @@ # -*- coding: utf-8 -*- import datetime +import urllib import werkzeug from openerp import tools from openerp.addons.web import http from openerp.addons.web.http import request from openerp.addons.website.models.website import slug +from openerp.osv import osv from openerp.osv.orm import browse_record from openerp.tools.translate import _ from openerp import SUPERUSER_ID @@ -47,8 +49,9 @@ class WebsiteBlog(http.Controller): _blog_post_per_page = 20 _post_comment_per_page = 10 - def nav_list(self, domain=[]): + def nav_list(self, blog=None): blog_post_obj = request.registry['blog.post'] + domain = blog and [('blog_id', '=', blog.id)] or [] groups = blog_post_obj.read_group( request.cr, request.uid, domain, ['name', 'create_date'], groupby="create_date", orderby="create_date desc", context=request.context) @@ -85,8 +88,8 @@ class WebsiteBlog(http.Controller): @http.route([ '/blog/', '/blog//page/', - '/blog//tag/', - '/blog//tag//page/', + '/blog//tag/', + '/blog//tag//page/', ], type='http', auth="public", website=True) def blog(self, blog=None, tag=None, page=1, **opt): """ Prepare all values to display the blog. @@ -96,7 +99,8 @@ class WebsiteBlog(http.Controller): - 'blog': current blog - 'blogs': all blogs for navigation - 'pager': pager of posts - - 'tag': current tag + - 'active_tag_ids' : list of active tag ids, + - 'tags_list' : function to built the comma-separated tag list ids (for the url), - 'tags': all tags, for navigation - 'nav_list': a dict [year][month] for archives navigation - 'date': date_begin optional parameter, used in archives navigation @@ -111,18 +115,17 @@ class WebsiteBlog(http.Controller): blog_ids = blog_obj.search(cr, uid, [], order="create_date asc", context=context) blogs = blog_obj.browse(cr, uid, blog_ids, context=context) + # build the domain for blog post to display domain = [] + active_tag_ids = tag and map(int, tag.split(',')) or [] + if active_tag_ids: + domain += [('tag_ids', 'in', active_tag_ids)] if blog: domain += [('blog_id', '=', blog.id)] - if tag: - domain += [('tag_ids', 'in', tag.id)] - blogs_by_month = self.nav_list(domain) - if date_begin and date_end: domain += [("create_date", ">=", date_begin), ("create_date", "<=", date_end)] blog_url = QueryURL('', ['blog', 'tag'], blog=blog, tag=tag, date_begin=date_begin, date_end=date_end) - post_url = QueryURL('', ['blogpost'], tag_id=tag and tag.id or None, date_begin=date_begin, date_end=date_end) blog_post_ids = blog_post_obj.search(cr, uid, domain, order="create_date desc", context=context) blog_posts = blog_post_obj.browse(cr, uid, blog_post_ids, context=context) @@ -137,18 +140,28 @@ class WebsiteBlog(http.Controller): pager_end = page * self._blog_post_per_page blog_posts = blog_posts[pager_begin:pager_end] - tags = blog.all_tags()[blog.id] + all_tags = blog.all_tags()[blog.id] + + # function to create the string list of tag ids, and toggle a given one. + # used in the 'Tags Cloud' template. + def tags_list(tag_ids, current_tag): + tag_ids = list(tag_ids) # required to avoid using the same list + if current_tag in tag_ids: + tag_ids.remove(current_tag) + else: + tag_ids.append(current_tag) + return ','.join(map(str, tag_ids)) values = { 'blog': blog, 'blogs': blogs, - 'tags': tags, - 'tag': tag, + 'tags': all_tags, + 'active_tag_ids': active_tag_ids, + 'tags_list' : tags_list, 'blog_posts': blog_posts, 'pager': pager, - 'nav_list': blogs_by_month, - 'blog_url': blog_url, - 'post_url': post_url, + 'nav_list': self.nav_list(blog), + 'blog_url': blog_url, 'date': date_begin, } response = request.website.render("website_blog.blog_post_short", values) @@ -192,7 +205,6 @@ class WebsiteBlog(http.Controller): tag = None if tag_id: tag = request.registry['blog.tag'].browse(request.cr, request.uid, int(tag_id), context=request.context) - post_url = QueryURL('', ['blogpost'], blogpost=blog_post, tag_id=tag_id, date_begin=date_begin, date_end=date_end) blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end) if not blog_post.blog_id.id == blog.id: @@ -219,11 +231,10 @@ class WebsiteBlog(http.Controller): 'blog': blog, 'blog_post': blog_post, 'main_object': blog_post, - 'nav_list': self.nav_list([('blog_id', '=', blog.id)]), - 'enable_editor': enable_editor, + 'nav_list': self.nav_list(blog), + 'enable_editor': enable_editor, 'next_post': next_post, 'date': date_begin, - 'post_url': post_url, 'blog_url': blog_url, 'pager': pager, 'comments': comments, @@ -240,38 +251,44 @@ class WebsiteBlog(http.Controller): },context=context) return response - def _blog_post_message(self, user, blog_post_id=0, **post): + def _blog_post_message(self, uid, blog_post_id, message_content, **post): cr, uid, context = request.cr, request.uid, request.context - blog_post = request.registry['blog.post'] - partner_obj = request.registry['res.partner'] + BlogPost = request.registry['blog.post'] + User = request.registry['res.users'] + # for now, only portal and user can post comment on blog post. + if uid == request.website.user_id.id: + raise osv.except_osv(_('Error!'), _('Public user cannot post comments on blog post.')) + # get the partner of the current user + user = User.browse(cr, uid, uid, context=context) + partner_id = user.partner_id.id - if uid != request.website.user_id.id: - partner_ids = [user.partner_id.id] - else: - partner_ids = blog_post._find_partner_from_emails( - cr, SUPERUSER_ID, 0, [post.get('email')], context=context) - if not partner_ids or not partner_ids[0]: - partner_ids = [partner_obj.create(cr, SUPERUSER_ID, {'name': post.get('name'), 'email': post.get('email')}, context=context)] - - message_id = blog_post.message_post( - cr, SUPERUSER_ID, int(blog_post_id), - body=post.get('comment'), + message_id = BlogPost.message_post( + cr, uid, int(blog_post_id), + body=message_content, type='comment', subtype='mt_comment', - author_id=partner_ids[0], + author_id=partner_id, path=post.get('path', False), context=context) return message_id - @http.route(['/blogpost/comment'], type='http', auth="public", methods=['POST'], website=True) - def blog_post_comment(self, blog_post_id=0, **post): + @http.route(['/blog/post_comment'], type='http', auth="public", methods=['GET','POST'], website=True) + def blog_post_comment(self, blog_post_id=0, **kw): cr, uid, context = request.cr, request.uid, request.context - if post.get('comment'): - user = request.registry['res.users'].browse(cr, uid, uid, context=context) - blog_post = request.registry['blog.post'] - blog_post.check_access_rights(cr, uid, 'read') - self._blog_post_message(user, blog_post_id, **post) - return werkzeug.utils.redirect(request.httprequest.referrer + "#comments") + redirect_url = request.httprequest.referrer + "#comments" + if kw.get('comment'): + if not request.session.uid: # if not logged, redirect to the login form, keeping the url to post the comment + kw['comment'] = kw.get('comment').encode('utf8') # avoid crash from urlencode if accent + url = '/blog/post_comment/?blog_post_id=%s&%s' % (blog_post_id, urllib.urlencode(kw)) + redirect_url = '/web/login?redirect=%s' % urllib.quote(url) + else: + blog_post_id = int(blog_post_id) + blog_post = request.registry['blog.post'] + post = blog_post.browse(cr, uid, blog_post_id, context=context) + self._blog_post_message(uid, blog_post_id, kw.get('comment'), **kw) + redirect_url = "/blog/%s/post/%s#comments" % (slug(post.blog_id), slug(post)) + return werkzeug.utils.redirect(redirect_url) + def _get_discussion_detail(self, ids, publish=False, **post): cr, uid, context = request.cr, request.uid, request.context @@ -291,15 +308,14 @@ class WebsiteBlog(http.Controller): }) return values - @http.route(['/blogpost/post_discussion'], type='json', auth="public", website=True) + @http.route(['/blog/post_discussion'], type='json', auth="public", website=True) def post_discussion(self, blog_post_id, **post): cr, uid, context = request.cr, request.uid, request.context publish = request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher') - user = request.registry['res.users'].browse(cr, uid, uid, context=context) - id = self._blog_post_message(user, blog_post_id, **post) + id = self._blog_post_message(uid, blog_post_id, post.get('comment'), **post) return self._get_discussion_detail([id], publish, **post) - @http.route('/blogpost/new', type='http', auth="public", website=True) + @http.route('/blog//post/new', type='http', auth="public", website=True) def blog_post_create(self, blog_id, **post): cr, uid, context = request.cr, request.uid, request.context new_blog_post_id = request.registry['blog.post'].create(cr, uid, { @@ -312,7 +328,7 @@ class WebsiteBlog(http.Controller): new_blog_post = request.registry['blog.post'].browse(cr, uid, new_blog_post_id, context=context) return werkzeug.utils.redirect("/blog/%s/post/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post))) - @http.route('/blogpost/duplicate', type='http', auth="public", website=True) + @http.route('/blog/post_duplicate', type='http', auth="public", website=True) def blog_post_copy(self, blog_post_id, **post): """ Duplicate a blog. @@ -322,12 +338,12 @@ class WebsiteBlog(http.Controller): """ cr, uid, context = request.cr, request.uid, request.context create_context = dict(context, mail_create_nosubscribe=True) - nid = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context) + nid = request.registry['blog.post'].copy(cr, uid, int(blog_post_id), {}, context=create_context) new_blog_post = request.registry['blog.post'].browse(cr, uid, nid, context=context) post = request.registry['blog.post'].browse(cr, uid, nid, context) return werkzeug.utils.redirect("/blog/%s/post/%s?enable_editor=1" % (slug(post.blog_id), slug(new_blog_post))) - @http.route('/blogpost/get_discussion/', type='json', auth="public", website=True) + @http.route('/blog/post_get_discussion/', type='json', auth="public", website=True) def discussion(self, post_id=0, path=None, count=False, **post): cr, uid, context = request.cr, request.uid, request.context mail_obj = request.registry.get('mail.message') @@ -341,7 +357,7 @@ class WebsiteBlog(http.Controller): return ids return self._get_discussion_detail(ids, publish, **post) - @http.route('/blogpost/get_discussions/', type='json', auth="public", website=True) + @http.route('/blog/post_get_discussions/', type='json', auth="public", website=True) def discussions(self, post_id=0, paths=None, count=False, **post): ret = [] for path in paths: @@ -349,7 +365,7 @@ class WebsiteBlog(http.Controller): ret.append({"path": path, "val": result}) return ret - @http.route('/blogpost/change_background', type='json', auth="public", website=True) + @http.route('/blog/post_change_background', type='json', auth="public", website=True) def change_bg(self, post_id=0, image=None, **post): if not post_id: return False diff --git a/addons/website_blog/data/website_blog_data.xml b/addons/website_blog/data/website_blog_data.xml index c291ee50690..a4bc8778bec 100644 --- a/addons/website_blog/data/website_blog_data.xml +++ b/addons/website_blog/data/website_blog_data.xml @@ -4,7 +4,6 @@ Our News Sharing our evolution with passion - Presentation of new Odoo features diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 70cd18b5278..defd0774149 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -20,7 +20,6 @@ class Blog(osv.Model): _columns = { 'name': fields.char('Blog Name', required=True), 'subtitle': fields.char('Blog Subtitle'), - 'description': fields.text('Description'), } def all_tags(self, cr, uid, ids, min_limit=1, context=None): @@ -69,6 +68,9 @@ class BlogPost(osv.Model): _inherit = ['mail.thread', 'website.seo.metadata'] _order = 'id DESC' + _mail_post_access = 'read' + + def _compute_ranking(self, cr, uid, ids, name, arg, context=None): res = {} for blog_post in self.browse(cr, uid, ids, context=context): diff --git a/addons/website_blog/static/src/js/website_blog.editor.js b/addons/website_blog/static/src/js/website_blog.editor.js index 3101488ab77..dbc91e3564f 100644 --- a/addons/website_blog/static/src/js/website_blog.editor.js +++ b/addons/website_blog/static/src/js/website_blog.editor.js @@ -15,7 +15,7 @@ $(document).ready(function() { .call('name_search', [], { context: website.get_context() }); }, }).then(function (cat_id) { - document.location = '/blogpost/new?blog_id=' + cat_id; + document.location = '/blog/' + cat_id + '/post/new'; }); }, }); @@ -32,7 +32,7 @@ $(document).ready(function() { save : function() { var res = this._super(); if ($('.cover').length) { - openerp.jsonRpc("/blogpost/change_background", 'call', { + openerp.jsonRpc("/blog/post_change_background", 'call', { 'post_id' : $('#blog_post_name').attr('data-oe-id'), 'image' : $('.cover').css('background-image').replace(/url\(|\)|"|'/g,''), }); diff --git a/addons/website_blog/static/src/js/website_blog.inline.discussion.js b/addons/website_blog/static/src/js/website_blog.inline.discussion.js index 9dc0c141984..2c68f14b02e 100644 --- a/addons/website_blog/static/src/js/website_blog.inline.discussion.js +++ b/addons/website_blog/static/src/js/website_blog.inline.discussion.js @@ -1,8 +1,8 @@ // Inspired from https://github.com/tsi/inlineDisqussions (function () { - + 'use strict'; - + var website = openerp.website, qweb = openerp.qweb; @@ -51,7 +51,7 @@ }, prepare_data : function(identifier, comment_count) { var self = this; - return openerp.jsonRpc("/blogpost/get_discussion/", 'call', { + return openerp.jsonRpc("/blog/post_get_discussion/", 'call', { 'post_id': self.settings.post_id, 'path': identifier, 'count': comment_count, //if true only get length of total comment, display on discussion thread. @@ -59,7 +59,7 @@ }, prepare_multi_data : function(identifiers, comment_count) { var self = this; - return openerp.jsonRpc("/blogpost/get_discussions/", 'call', { + return openerp.jsonRpc("/blog/post_get_discussions/", 'call', { 'post_id': self.settings.post_id, 'paths': identifiers, 'count': comment_count, //if true only get length of total comment, display on discussion thread. @@ -136,7 +136,7 @@ comment += qweb.render("website.blog_discussion.comment", {'res': res}); }); $('.discussion_history').html('
    '+comment+'
'); - self.create_popover(elt, identifier); + self.create_popover(elt, identifier); // Add 'active' class. $('a.discussion-link, a.main-discussion-link').removeClass('active').filter(source).addClass('active'); elt.popover('hide').filter(source).popover('show'); @@ -162,9 +162,9 @@ var author_name = $('.popover input#author_name').val(); var author_email = $('.popover input#author_email').val(); if(!comment || !author_name || !author_email){ - if (!author_name) + if (!author_name) $('div#author_name').addClass('has-error'); - else + else $('div#author_name').removeClass('has-error'); if (!author_email) $('div#author_email').addClass('has-error'); @@ -193,7 +193,7 @@ var self = this; var val = self.validate(self.settings.public_user) if(!val) return - openerp.jsonRpc("/blogpost/post_discussion", 'call', { + openerp.jsonRpc("/blog/post_discussion", 'call', { 'blog_post_id': self.settings.post_id, 'path': self.discus_identifier, 'comment': val[0], @@ -211,7 +211,7 @@ $('a[data-discus-identifier="'+ self.discus_identifier+'"]').popover('destroy'); $('a.discussion-link').removeClass('active'); } - + }); })(); diff --git a/addons/website_blog/tests/test_website_blog_flow.py b/addons/website_blog/tests/test_website_blog_flow.py index 05c2420e59a..0c2c0b43dfa 100644 --- a/addons/website_blog/tests/test_website_blog_flow.py +++ b/addons/website_blog/tests/test_website_blog_flow.py @@ -19,7 +19,6 @@ class TestWebsiteBlogFlow(TestWebsiteBlogCommon): # Create a new blog, subscribe the employee to the blog test_blog = self.env['blog.blog'].sudo(self.user_blogmanager).create({ 'name': 'New Blog', - 'description': 'Presentation of new Odoo features' }) self.assertIn( self.user_blogmanager.partner_id, test_blog.message_follower_ids, diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index 65064a6548e..f427c2dd504 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -102,13 +102,15 @@