[IMP] website_blog: path computation (unique key) for paragraphs in medium-like blogs
is now done server-side and stored directly in the html content, as post processing. The front-end attaches messages based on the attribute data-chatter-id, but do not compute the attribute itself anymore. Misc cleaning of code. bzr revid: tde@openerp.com-20140403112656-ane3ovhh70qdc8b4
This commit is contained in:
parent
eccbb272ee
commit
8f105b6624
|
@ -210,7 +210,6 @@ class WebsiteBlog(http.Controller):
|
|||
('id', 'not in', visited_ids),
|
||||
], order='ranking desc', limit=1, context=context)
|
||||
next_post = next_post_id and blog_post_obj.browse(cr, uid, next_post_id[0], context=context) or False
|
||||
print next_post
|
||||
|
||||
values = {
|
||||
'tags': tags,
|
||||
|
@ -259,7 +258,7 @@ class WebsiteBlog(http.Controller):
|
|||
type='comment',
|
||||
subtype='mt_comment',
|
||||
author_id=partner_ids[0],
|
||||
discussion=post.get('discussion'),
|
||||
path=post.get('path', False),
|
||||
context=dict(context, mail_create_nosubcribe=True))
|
||||
return message_id
|
||||
|
||||
|
@ -327,10 +326,10 @@ class WebsiteBlog(http.Controller):
|
|||
return werkzeug.utils.redirect("/blog/%s/post/%s/?enable_editor=1" % (post.blog_id.id, nid))
|
||||
|
||||
@http.route('/blogpost/get_discussion/', type='json', auth="public", website=True)
|
||||
def discussion(self, post_id=0, discussion=None, count=False, **post):
|
||||
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')
|
||||
domain = [('res_id', '=', int(post_id)) ,('model','=','blog.post'), ('discussion_key', '=', discussion)]
|
||||
domain = [('res_id', '=', int(post_id)), ('model', '=', 'blog.post'), ('path', '=', path)]
|
||||
#check current user belongs to website publisher group
|
||||
publish = request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher')
|
||||
if not publish:
|
||||
|
|
|
@ -7,6 +7,7 @@ class MailMessage(osv.Model):
|
|||
_inherit = 'mail.message'
|
||||
|
||||
_columns = {
|
||||
'discussion_key': fields.char('Discussion Key',
|
||||
help='Used in Blogs to display messages in a group based on their discussion key.'),
|
||||
'path': fields.char(
|
||||
'Discussion Path', select=1,
|
||||
help='Used to display messages in a paragraph-based chatter using a unique path;'),
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
from datetime import datetime
|
||||
import difflib
|
||||
import lxml
|
||||
import random
|
||||
|
||||
from openerp import tools
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
@ -66,7 +68,7 @@ class BlogPost(osv.Model):
|
|||
'website_message_ids': fields.one2many(
|
||||
'mail.message', 'res_id',
|
||||
domain=lambda self: [
|
||||
'&', '&', ('model', '=', self._name), ('type', '=', 'comment'), ('discussion_key', '=', False)
|
||||
'&', '&', ('model', '=', self._name), ('type', '=', 'comment'), ('path', '=', False)
|
||||
],
|
||||
string='Website Messages',
|
||||
help="Website communication history",
|
||||
|
@ -103,6 +105,59 @@ class BlogPost(osv.Model):
|
|||
'author_id': lambda self, cr, uid, ctx=None: self.pool['res.users'].browse(cr, uid, uid, context=ctx).partner_id.id,
|
||||
}
|
||||
|
||||
def html_tag_nodes(self, html, attribute=None, tags=None, context=None):
|
||||
""" Processing of html content to tag paragraphs and set them an unique
|
||||
ID.
|
||||
:return result: (html, mappin), where html is the updated html with ID
|
||||
and mapping is a list of (old_ID, new_ID), where old_ID
|
||||
is None is the paragraph is a new one. """
|
||||
mapping = []
|
||||
if not html:
|
||||
return html, mapping
|
||||
if tags is None:
|
||||
tags = ['p']
|
||||
if attribute is None:
|
||||
attribute = 'data-unique-id'
|
||||
counter = 0
|
||||
|
||||
# form a tree
|
||||
root = lxml.html.fragment_fromstring(html, create_parent='div')
|
||||
if not len(root) and root.text is None and root.tail is None:
|
||||
return html, mapping
|
||||
|
||||
# check all nodes, replace :
|
||||
# - img src -> check URL
|
||||
# - a href -> check URL
|
||||
for node in root.iter():
|
||||
if not node.tag in tags:
|
||||
continue
|
||||
ancestor_tags = [parent.tag for parent in node.iterancestors()]
|
||||
ancestor_tags.pop()
|
||||
new_attribute = '/'.join(reversed(ancestor_tags))
|
||||
old_attribute = node.get(attribute)
|
||||
node.set(attribute, new_attribute)
|
||||
mapping.append((old_attribute, counter))
|
||||
counter += 1
|
||||
|
||||
html = lxml.html.tostring(root, pretty_print=False, method='html')
|
||||
# this is ugly, but lxml/etree tostring want to put everything in a 'div' that breaks the editor -> remove that
|
||||
if html.startswith('<div>') and html.endswith('</div>'):
|
||||
html = html[5:-6]
|
||||
return html, mapping
|
||||
|
||||
def _postproces_content(self, cr, uid, id, content=None, context=None):
|
||||
if content is None:
|
||||
content = self.browse(cr, uid, id, context=context).content
|
||||
if content is False:
|
||||
return content
|
||||
content, mapping = self.html_tag_nodes(content, attribute='data-chatter-id', tags=['p'], context=context)
|
||||
for old_attribute, new_attribute in mapping:
|
||||
if not old_attribute:
|
||||
continue
|
||||
msg_ids = self.pool['mail.message'].search(cr, SUPERUSER_ID, [('path', '=', old_attribute)], context=context)
|
||||
self.pool['mail.message'].write(cr, SUPERUSER_ID, msg_ids, {'path': new_attribute}, context=context)
|
||||
return content
|
||||
|
||||
def create_history(self, cr, uid, ids, vals, context=None):
|
||||
for i in ids:
|
||||
history = self.pool.get('blog.post.history')
|
||||
|
@ -116,12 +171,16 @@ class BlogPost(osv.Model):
|
|||
def create(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'content' in vals:
|
||||
vals['content'] = self._postproces_content(cr, uid, None, vals['content'], context=context)
|
||||
create_context = dict(context, mail_create_nolog=True)
|
||||
post_id = super(BlogPost, self).create(cr, uid, vals, context=create_context)
|
||||
self.create_history(cr, uid, [post_id], vals, context)
|
||||
return post_id
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if 'content' in vals:
|
||||
vals['content'] = self._postproces_content(cr, uid, None, vals['content'], context=context)
|
||||
result = super(BlogPost, self).write(cr, uid, ids, vals, context)
|
||||
self.create_history(cr, uid, ids, vals, context)
|
||||
return result
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
var self = this ;
|
||||
self.discus_identifier;
|
||||
var defaults = {
|
||||
identifier: 'name',
|
||||
position: 'right',
|
||||
post_id: $('#blog_post_name').attr('data-blog-id'),
|
||||
content : false,
|
||||
|
@ -23,7 +22,7 @@
|
|||
do_render: function(data) {
|
||||
var self = this;
|
||||
if ($('#discussions_wrapper').length === 0 && self.settings.content.length > 0) {
|
||||
$('<div id="discussions_wrapper"></div>').appendTo($('#blog_content'));
|
||||
$('<div id="discussions_wrapper"></div>').insertAfter($('#blog_content'));
|
||||
}
|
||||
// Attach a discussion to each paragraph.
|
||||
$(self.settings.content).each(function(i) {
|
||||
|
@ -36,8 +35,8 @@
|
|||
}
|
||||
if(!$(event.target).hasClass('discussion-link') && !$(event.target).parents('.popover').length){
|
||||
if($('.move_discuss').length){
|
||||
$('.js_discuss').next().removeClass('move_discuss');
|
||||
$('.js_discuss').next().animate({
|
||||
$('[enable_chatter_discuss=True]').removeClass('move_discuss');
|
||||
$('[enable_chatter_discuss=True]').animate({
|
||||
'marginLeft': "+=40%"
|
||||
});
|
||||
$('#discussions_wrapper').animate({
|
||||
|
@ -47,30 +46,22 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
prepare_data : function(identifier,comment_count) {
|
||||
prepare_data : function(identifier, comment_count) {
|
||||
var self = this;
|
||||
return openerp.jsonRpc("/blogpost/get_discussion/", 'call', {
|
||||
'post_id': self.settings.post_id,
|
||||
'discussion':identifier,
|
||||
'count' : comment_count, //if true only get length of total comment, display on discussion thread.
|
||||
'path': identifier,
|
||||
'count': comment_count, //if true only get length of total comment, display on discussion thread.
|
||||
})
|
||||
},
|
||||
discussion_handler : function(i, node) {
|
||||
var self = this;
|
||||
var identifier;
|
||||
// You can force a specific identifier by adding an attribute to the paragraph.
|
||||
if (node.attr('data-discus-identifier')) {
|
||||
identifier = node.attr('data-discus-identifier');
|
||||
}
|
||||
else {
|
||||
while ($('[data-discus-identifier="' + self.settings.identifier + '-' + i + '"]').length > 0) {
|
||||
i++;
|
||||
}
|
||||
identifier = self.settings.identifier + '-' + i;
|
||||
}
|
||||
self.prepare_data(identifier,true).then(function(data){
|
||||
self.prepare_discuss_link(data,identifier,node)
|
||||
var identifier = node.attr('data-chatter-id');
|
||||
if (identifier) {
|
||||
self.prepare_data(identifier, true).then( function (data) {
|
||||
self.prepare_discuss_link(data, identifier, node);
|
||||
});
|
||||
}
|
||||
},
|
||||
prepare_discuss_link : function(data, identifier, node) {
|
||||
var self = this;
|
||||
|
@ -79,7 +70,7 @@
|
|||
.attr('data-discus-identifier', identifier)
|
||||
.attr('data-discus-position', self.settings.position)
|
||||
.text(data > 0 ? data : '+')
|
||||
.attr('data-contentwrapper','.mycontent')
|
||||
.attr('data-contentwrapper', '.mycontent')
|
||||
.wrap('<div class="discussion" />')
|
||||
.parent()
|
||||
.appendTo('#discussions_wrapper');
|
||||
|
@ -87,7 +78,8 @@
|
|||
'top': node.offset().top,
|
||||
'left': self.settings.position == 'right' ? node.outerWidth() + node.offset().left: node.offset().left - a.outerWidth()
|
||||
});
|
||||
node.attr('data-discus-identifier', identifier).mouseover(function() {
|
||||
// node.attr('data-discus-identifier', identifier)
|
||||
node.mouseover(function() {
|
||||
a.addClass("hovered");
|
||||
}).mouseout(function() {
|
||||
a.removeClass("hovered");
|
||||
|
@ -96,8 +88,8 @@
|
|||
a.delegate('a.discussion-link', "click", function(e) {
|
||||
e.preventDefault();
|
||||
if(!$('.move_discuss').length){
|
||||
$('.js_discuss').next().addClass('move_discuss');
|
||||
$('.js_discuss').next().animate({
|
||||
$('[enable_chatter_discuss=True]').addClass('move_discuss');
|
||||
$('[enable_chatter_discuss=True]').animate({
|
||||
'marginLeft': "-=40%"
|
||||
});
|
||||
$('#discussions_wrapper').animate({
|
||||
|
@ -185,7 +177,7 @@
|
|||
if(!val) return
|
||||
openerp.jsonRpc("/blogpost/post_discussion", 'call', {
|
||||
'blog_post_id': self.settings.post_id,
|
||||
'discussion': self.discus_identifier,
|
||||
'path': self.discus_identifier,
|
||||
'comment': val[0],
|
||||
'name' : val[1],
|
||||
'email': val[2],
|
||||
|
|
|
@ -24,8 +24,8 @@ $(document).ready(function() {
|
|||
});
|
||||
}
|
||||
|
||||
var content = $(".js_discuss").next().find('p');
|
||||
if(content){
|
||||
var content = $("div[enable_chatter_discuss='True']").find('p[data-chatter-id]');
|
||||
if (content) {
|
||||
openerp.jsonRpc("/blog/get_user/", 'call', {}).then(function(data){
|
||||
$('#discussions_wrapper').empty();
|
||||
new openerp.website.blog_discussion({'content' : content, 'public_user':data[0]});
|
||||
|
|
|
@ -318,8 +318,8 @@
|
|||
<!-- Options: Blog Post: user can add Inline Discussion -->
|
||||
<template id="opt_blog_post_inline_discussion" name="Allow comment in text"
|
||||
inherit_option_id="website_blog.blog_post_complete">
|
||||
<xpath expr="//div[@id='blog_content']" position="before">
|
||||
<div class="js_discuss"/>
|
||||
<xpath expr="//div[@id='blog_content']" position="attributes">
|
||||
<attribute name="enable_chatter_discuss">True</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
|
Loading…
Reference in New Issue