return request.website.render("website_forum.faq", values)
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True)
- def tag_read(self, **post):
- tags = request.env['forum.tag'].search_read([], ['name'])
- data = [tag['name'] for tag in tags]
- def tag_read(self, q='', l=25, t='texttext', **post):
- data = request.registry['forum.tag'].search_read(
- request.cr,
- request.uid,
++ def tag_read(self, q='', l=25, **post):
++ data = request.env['forum.tag'].search_read(
+ domain=[('name', '=ilike', (q or '') + "%")],
+ fields=['id', 'name'],
+ limit=int(l),
- context=request.context
+ )
- if t == 'texttext':
- # old tag with texttext - Retro for V8 - #TODO Remove in master
- data = [tag['name'] for tag in data]
return simplejson.dumps(data)
@http.route(['/forum/<model("forum.forum"):forum>/tag'], type='http', auth="public", website=True)
# Post
# --------------------------------------------------
--
- @http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/new', type='http', auth="public", methods=['POST'], website=True)
- def post_new(self, forum, post, **kwargs):
+ @http.route(['/forum/<model("forum.forum"):forum>/ask'], type='http', auth="public", website=True)
+ def forum_post(self, forum, post_type=None, **post):
if not request.session.uid:
return login_redirect()
- cr, uid, context = request.cr, request.uid, request.context
- user = request.registry['res.users'].browse(cr, SUPERUSER_ID, uid, context=context)
+ user = request.env.user
+ if not post_type in ['question', 'link', 'discussion']: # fixme: make dynamic
+ return werkzeug.utils.redirect('/forum/%s' % slug(forum))
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), uid))
- request.registry['forum.post'].create(
- request.cr, request.uid, {
- 'forum_id': forum.id,
- 'parent_id': post.id,
- 'content': kwargs.get('content'),
- }, context=request.context)
- return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(post)))
+ 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_forum_values(forum=forum, searches={}, header={'ask_hide': True})
+ return request.website.render("website_forum.new_%s" % post_type, values)
+
+ @http.route(['/forum/<model("forum.forum"):forum>/new',
+ '/forum/<model("forum.forum"):forum>/<model("forum.post"):post_parent>/reply'],
+ type='http', auth="public", methods=['POST'], website=True)
+ def post_create(self, forum, post_parent=None, post_type=None, **post):
+ cr, uid, context = request.cr, request.uid, request.context
+ if not request.session.uid:
+ return login_redirect()
+
- post_tag_ids = []
- Tag = request.env['forum.tag']
- if post.get('post_tags', False) and post.get('post_tags').strip('[]'):
- tags = post.get('post_tags').strip('[]').replace('"', '').split(",")
- for tag in tags:
- tag_rec = Tag.search([('name', '=', tag)])
- if tag_rec:
- post_tag_ids.append((4, tag_rec.id))
- else:
- post_tag_ids.append((0, 0, {'name': tag, 'forum_id': forum.id}))
-
++ post_tag_ids = forum.tag_to_write_vals(post.get('post_tags', False))
+ new_question = request.env['forum.post'].create({
+ 'forum_id': forum.id,
+ 'name': post.get('post_name', ''),
+ 'content': post.get('content', False),
+ 'content_link': post.get('content_link', False),
+ 'parent_id': post_parent and post_parent.id or False,
+ 'tag_ids': post_tag_ids,
+ 'post_type': post_parent and post_parent.post_type or post_type, # tde check in selection field
+ })
+ return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), post_parent and slug(post_parent) or new_question.id))
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/comment', type='http', auth="public", methods=['POST'], website=True)
def post_comment(self, forum, post, **kwargs):
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/edit', type='http', auth="user", website=True)
def post_edit(self, forum, post, **kwargs):
- tags = ""
- for tag_name in post.tag_ids:
- tags += tag_name.name + ","
- tag_version = kwargs.get('tag_type', 'texttext')
- if tag_version == "texttext": # old version - retro v8 - #TODO Remove in master
- tags = ""
- for tag_name in post.tag_ids:
- tags += tag_name.name + ","
- elif tag_version == "select2": # new version
- tags = [dict(id=tag.id, name=tag.name) for tag in post.tag_ids]
- tags = simplejson.dumps(tags)
++ tags = [dict(id=tag.id, name=tag.name) for tag in post.tag_ids]
++ tags = simplejson.dumps(tags)
values = self._prepare_forum_values(forum=forum)
-
values.update({
'tags': tags,
'post': post,
})
return request.website.render("website_forum.edit_post", values)
- @http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/edition', type='http', auth="user", website=True)
- def post_edit_retro(self, forum, post, **kwargs):
- # This function is only there for retrocompatibility between old template using texttext and template using select2
- # It should be removed into master #TODO JKE: remove in master all condition with tag_type
- kwargs.update(tag_type="select2")
- return self.post_edit(forum, post, **kwargs)
-
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/save', type='http', auth="user", methods=['POST'], website=True)
def post_save(self, forum, post, **kwargs):
- post_tags = []
- if kwargs.get('post_tag') and kwargs.get('post_tag').strip('[]'):
- Tag = request.env['forum.tag']
- tags = kwargs.get('post_tag').strip('[]').replace('"', '').split(",")
- for tag in tags:
- tag_rec = Tag.search([('name', '=', tag)])
- if tag_rec:
- post_tags += tag_rec.ids
- else:
- new_tag = Tag.create({'name': tag, 'forum_id': forum.id})
- post_tags.append(new_tag.id)
- cr, uid, context = request.cr, request.uid, request.context
- question_tags = []
- User = request.registry['res.users']
- Tag = request.registry['forum.tag']
- tag_version = kwargs.get('tag_type', 'texttext')
- if tag_version == "texttext": # old version - retro v8 - #TODO Remove in master
- if kwargs.get('question_tag') and kwargs.get('question_tag').strip('[]'):
- tags = kwargs.get('question_tag').strip('[]').replace('"', '').split(",")
- for tag in tags:
- tag_ids = Tag.search(cr, uid, [('name', '=', tag)], context=context)
- if tag_ids:
- question_tags += tag_ids
- else:
- new_tag = Tag.create(cr, uid, {'name': tag, 'forum_id': forum.id}, context=context)
- question_tags.append(new_tag)
- elif tag_version == "select2": # new version
- for tag in filter(None, kwargs.get('question_tag', '').split(',')):
- if tag.startswith('_'): # it's a new tag
- # check if user have Karma needed to create need tag
- user = User.browse(cr, SUPERUSER_ID, uid, context=context)
- if user.exists() and user.karma >= forum.karma_retag:
- # check that not arleady created meanwhile and maybe excluded by the limit on the search
- tag_ids = Tag.search(cr, uid, [('name', '=', tag[1:])], context=context)
- if tag_ids:
- new_tag = tag_ids
- else:
- new_tag = Tag.create(cr, uid, {'name': tag[1:], 'forum_id': forum.id}, context=context)
- question_tags.append(new_tag)
- else:
- question_tags += [int(tag)]
-
++ post_tags = forum.tag_to_write_vals(kwargs.get('post_tag', ''))
vals = {
- 'tag_ids': [(6, 0, post_tags)],
- 'tag_ids': [(6, 0, question_tags)],
- 'name': kwargs.get('question_name'),
++ 'tag_ids': post_tags,
+ 'name': kwargs.get('post_name'),
'content': kwargs.get('content'),
}
- request.registry['forum.post'].write(cr, uid, [post.id], vals, context=context)
+ post.write(vals)
question = post.parent_id if post.parent_id else post
return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
elif rec['vote'] == '-1':
down_votes = rec['vote_count']
- #Votes which given by users on others questions and answers.
- post_votes = Vote.search(cr, uid, [('user_id', '=', user.id)], context=context)
- vote_ids = Vote.browse(cr, uid, post_votes, context=context)
+ # Votes which given by users on others questions and answers.
+ vote_ids = Vote.search([('user_id', '=', user.id)])
- #activity by user.
- model, comment = Data.get_object_reference(cr, uid, 'mail', 'mt_comment')
- activity_ids = Activity.search(cr, uid, [('res_id', 'in', user_question_ids+user_answer_ids), ('model', '=', 'forum.post'), ('subtype_id', '!=', comment)], order='date DESC', limit=100, context=context)
- activities = Activity.browse(cr, uid, activity_ids, context=context)
+ # 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:
<record id="action_open_forum" model="ir.actions.act_url">
<field name="name">Forum</field>
<field name="target">self</field>
- <field name="url" eval="'/forum/'+str(ref('website_forum.forum_help'))+'/#tutorial.forum=true'"/>
- <!-- TODO in master : remove the tutorial or create one tutorial forum -->
- <field name="url" eval="'/forum/'+str(ref('website_forum.forum_help'))+'/#tutorial.forum=true'"/>
++ <field name="url" eval="'/forum/'+str(ref('website_forum.forum_help'))"/>
</record>
<record id="base.open_menu" model="ir.actions.todo">
<field name="action_id" ref="action_open_forum"/>
_logger = logging.getLogger(__name__)
++
class KarmaError(Forbidden):
""" Karma-related error, used for forum and posts. """
pass
return f.read()
return False
- _defaults = {
- 'description': 'This community is for professionals and enthusiasts of our products and services.',
- 'faq': _get_default_faq,
- 'karma_gen_question_new': 0, # set to null for anti spam protection
- 'karma_gen_question_upvote': 5,
- 'karma_gen_question_downvote': -2,
- 'karma_gen_answer_upvote': 10,
- 'karma_gen_answer_downvote': -2,
- 'karma_gen_answer_accept': 2,
- 'karma_gen_answer_accepted': 15,
- 'karma_gen_answer_flagged': -100,
- 'karma_ask': 3, # set to not null for anti spam protection
- 'karma_answer': 3, # set to not null for anti spam protection
- 'karma_edit_own': 1,
- 'karma_edit_all': 300,
- 'karma_close_own': 100,
- 'karma_close_all': 500,
- 'karma_unlink_own': 500,
- 'karma_unlink_all': 1000,
- 'karma_upvote': 5,
- 'karma_downvote': 50,
- 'karma_answer_accept_own': 20,
- 'karma_answer_accept_all': 500,
- 'karma_editor_link_files': 20,
- 'karma_editor_clickable_link': 20,
- 'karma_comment_own': 3,
- 'karma_comment_all': 5,
- 'karma_comment_convert_own': 50,
- 'karma_comment_convert_all': 500,
- 'karma_comment_unlink_own': 50,
- 'karma_comment_unlink_all': 500,
- 'karma_retag': 75,
- 'karma_flag': 500,
- }
-
- def create(self, cr, uid, values, context=None):
- if context is None:
- context = {}
- create_context = dict(context, mail_create_nolog=True)
- return super(Forum, self).create(cr, uid, values, context=create_context)
-
-
-class Post(osv.Model):
+ # description and use
+ name = fields.Char('Forum Name', required=True, translate=True)
+ faq = fields.Html('Guidelines', default=_get_default_faq, translate=True)
+ description = fields.Html(
+ 'Description',
+ default='<p> This community is for professionals and enthusiasts of our products and services.'
+ 'Share and discuss the best content and new marketing ideas,'
+ 'build your professional profile and become a better marketer together.</p>')
+ default_order = fields.Selection([
+ ('create_date desc', 'Newest'),
+ ('write_date desc', 'Last Updated'),
+ ('vote_count desc', 'Most Voted'),
+ ('relevancy desc', 'Relevancy'),
+ ('child_count desc', 'Answered')],
+ string='Default Order', required=True, default='write_date desc')
+ relevancy_post_vote = fields.Float('First Relevancy Parameter', default=0.8)
+ relevancy_time_decay = fields.Float('Second Relevancy Parameter', default=1.8)
+ default_post_type = fields.Selection([
+ ('question', 'Question'),
+ ('discussion', 'Discussion'),
+ ('link', 'Link')],
+ string='Default Post', required=True, default='question')
+ allow_question = fields.Boolean('Questions', help="Users can answer only once per question. Contributors can edit answers and mark the right ones.", default=True)
+ allow_discussion = fields.Boolean('Discussions', default=False)
+ allow_link = fields.Boolean('Links', help="When clicking on the post, it redirects to an external link", default=False)
+ # karma generation
+ karma_gen_question_new = fields.Integer(string='Asking a question', default=2)
+ karma_gen_question_upvote = fields.Integer(string='Question upvoted', default=5)
+ karma_gen_question_downvote = fields.Integer(string='Question downvoted', default=-2)
+ karma_gen_answer_upvote = fields.Integer(string='Answer upvoted', default=10)
+ karma_gen_answer_downvote = fields.Integer(string='Answer downvoted', default=-2)
+ karma_gen_answer_accept = fields.Integer(string='Accepting an answer', default=2)
+ karma_gen_answer_accepted = fields.Integer(string='Answer accepted', default=15)
+ karma_gen_answer_flagged = fields.Integer(string='Answer flagged', default=-100)
+ # karma-based actions
+ karma_ask = fields.Integer(string='Ask a new question', default=3)
+ karma_answer = fields.Integer(string='Answer a question', default=3)
+ karma_edit_own = fields.Integer(string='Edit its own posts', default=1)
+ karma_edit_all = fields.Integer(string='Edit all posts', default=300)
+ karma_close_own = fields.Integer(string='Close its own posts', default=100)
+ karma_close_all = fields.Integer(string='Close all posts', default=500)
+ karma_unlink_own = fields.Integer(string='Delete its own posts', default=500)
+ karma_unlink_all = fields.Integer(string='Delete all posts', default=1000)
+ karma_upvote = fields.Integer(string='Upvote', default=5)
+ karma_downvote = fields.Integer(string='Downvote', default=50)
+ karma_answer_accept_own = fields.Integer(string='Accept an answer on its own questions', default=20)
+ karma_answer_accept_all = fields.Integer(string='Accept an answers to all questions', default=500)
+ karma_editor_link_files = fields.Integer(string='Linking files (Editor)', default=20)
+ karma_editor_clickable_link = fields.Integer(string='Add clickable links (Editor)', default=20)
+ karma_comment_own = fields.Integer(string='Comment its own posts', default=1)
+ karma_comment_all = fields.Integer(string='Comment all posts', default=1)
+ karma_comment_convert_own = fields.Integer(string='Convert its own answers to comments and vice versa', default=50)
+ karma_comment_convert_all = fields.Integer(string='Convert all answers to answers and vice versa', default=500)
+ karma_comment_unlink_own = fields.Integer(string='Unlink its own comments', default=50)
+ karma_comment_unlink_all = fields.Integer(string='Unlinnk all comments', default=500)
+ karma_retag = fields.Integer(string='Change question tags', default=75)
+ karma_flag = fields.Integer(string='Flag a post as offensive', default=500)
+
+ @api.model
+ def create(self, values):
+ return super(Forum, self.with_context(mail_create_nolog=True)).create(values)
+
++ @api.model
++ def tag_to_write_vals(self, tags=''):
++ User = self.env['res.users']
++ Tag = self.env['forum.tag']
++ post_tags = []
++ for tag in filter(None, tags.split(',')):
++ if tag.startswith('_'): # it's a new tag
++ # check that not arleady created meanwhile or maybe excluded by the limit on the search
++ tag_ids = Tag.search([('name', '=', tag[1:])])
++ if tag_ids:
++ post_tags.append((4, int(tag_ids[0])))
++ else:
++ # check if user have Karma needed to create need tag
++ user = User.sudo().browse(self._uid)
++ if user.exists() and user.karma >= self.karma_retag:
++ post_tags.append((0, 0, {'name': tag[1:], 'forum_id': self.id}))
++ else:
++ post_tags.append((4, int(tag)))
++ return post_tags
++
+
+class Post(models.Model):
_name = 'forum.post'
_description = 'Forum Post'
_inherit = ['mail.thread', 'website.seo.metadata']
+++ /dev/null
--(function () {
-- 'use strict';
--
-- var website = openerp.website;
-- var _t = openerp._t;
--
- // website.EditorBar.include({
- // start: function () {
- // this.registerTour(new website.Tour.Forum(this));
- // return this._super();
- // },
- // });
-
- // website.Tour.Forum = website.Tour.extend({
- // id: 'question',
- // name: "Create a question",
- // testPath: '/forum(/[0-9]+/register)?',
- // init: function (editor) {
- // var self = this;
- // self.steps = [
- // {
- // title: _t("Create a question"),
- // content: _t("Let's go through the first steps to create a new question."),
- // popover: { next: _("Start Tutorial"), end: _("Skip It") },
- // },
- // ];
- // return this._super();
- // }
- // });
-
- }());
- openerp.Tour.register({
- id: 'forum',
- name: '',
- steps : [{}],
- });
-
-}());
$(document).ready(function () {
if ($('.website_forum').length){
++ $("[data-toggle='popover']").popover();
++
$('.karma_required').on('click', function (ev) {
var karma = $(ev.currentTarget).data('karma');
if (karma) {
openerp.jsonRpc("/forum/validate_email/close", 'call', {});
});
+
+ $('.js_close_intro').on('click', function (ev) {
+ ev.preventDefault();
+ document.cookie = "no_introduction_message = false";
+ return true;
+ });
+
+ $('.link_url').on('change', function (ev) {
+ ev.preventDefault();
+ var $link = $(ev.currentTarget);
+ if ($link.attr("value").search("^http(s?)://.*")) {
+ var $warning = $('<div class="alert alert-danger alert-dismissable" style="position:absolute; margin-top: -180px; margin-left: 90px;">'+
+ '<button type="button" class="close notification_close" data-dismiss="alert" aria-hidden="true">×</button>'+
+ 'Please enter valid URl.'+
+ '</div>');
+ $link.parent().append($warning);
+ $link.parent().find("button#btn_post_your_article")[0].disabled = true;
+ $link.parent().find("input[name='content']")[0].value = '';
+ } else {
+ openerp.jsonRpc("/forum/get_url_title", 'call', {'url': $link.attr("value")}).then(function (data) {
+ $link.parent().find("input[name='content']")[0].value = data;
+ $('button').prop('disabled', false);
+ $('input').prop('readonly', false);
+ });
+ }
+ });
+
- if($('input.load_tags').length){
- var tags = $("input.load_tags").val();
- $("input.load_tags").val("");
- set_tags(tags);
- };
-
- function htmlEntities(str) {
- return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
- }
-
- function set_tags(tags) {
- $("input.load_tags").textext({
- plugins: 'tags focus autocomplete ajax',
- ext: {
- autocomplete: {
- onSetSuggestions : function(e, data) {
- var self = this,
- val = self.val(),
- suggestions = self._suggestions = data.result;
- if(data.showHideDropdown !== false)
- self.trigger(suggestions === null || suggestions.length === 0 && val.length === 0 ? "hideDropdown" : "showDropdown");
- },
- renderSuggestions: function(suggestions) {
- var self = this,
- val = self.val();
- self.clearItems();
- $.each(suggestions || [], function(index, item) {
- self.addSuggestion(htmlEntities(item));
- });
- var lowerCasesuggestions = $.map(suggestions, function(n,i){return n.toLowerCase();});
- if(jQuery.inArray(val.toLowerCase(), lowerCasesuggestions) ==-1) {
- self.addSuggestion("Create '" + htmlEntities(val) + "'");
- }
- },
- },
- tags: {
- onEnterKeyPress: function(e) {
- var self = this,
- val = self.val(),
- tag = self.itemManager().stringToItem(val);
-
- if(self.isTagAllowed(tag)) {
- tag = tag.replace(/Create\ '|\'|'/g,'');
- self.addTags([ tag ]);
- // refocus the textarea just in case it lost the focus
- self.core().focusInput();
- }
- },
+ $('input.js_select2').select2({
+ tags: true,
+ tokenSeparators: [",", " ", "_"],
+ maximumInputLength: 35,
+ minimumInputLength: 2,
+ maximumSelectionSize: 5,
+ lastsearch: [],
+ createSearchChoice: function (term) {
+ if ($(lastsearch).filter(function () { return this.text.localeCompare(term) === 0;}).length === 0) {
+ //check Karma
+ if (parseInt($("#karma").val()) >= parseInt($("#karma_retag").val())) {
+ return {
+ id: "_" + $.trim(term),
+ text: $.trim(term) + ' *',
+ isNew: true,
+ };
}
+
+ }
+ },
+ formatResult: function(term) {
+ if (term.isNew) {
+ return '<span class="label label-primary">New</span> ' + _.escape(term.text);
+ }
+ else {
+ return _.escape(term.text);
+ }
+ },
+ ajax: {
+ url: '/forum/get_tags',
+ dataType: 'json',
+ data: function(term, page) {
+ return {
+ q: term,
- t: 'select2',
+ l: 50
+ };
},
- tagsItems: tags.split(","),
- //Note: The following list of keyboard keys is added. All entries are default except {32 : 'whitespace!'}.
- keys: {8: 'backspace', 9: 'tab', 13: 'enter!', 27: 'escape!', 37: 'left', 38: 'up!', 39: 'right',
- 40: 'down!', 46: 'delete', 108: 'numpadEnter', 32: 'whitespace'},
- ajax: {
- url: '/forum/get_tags',
- dataType: 'json',
- cacheResults: true
+ results: function(data, page) {
+ var ret = [];
+ _.each(data, function(x) {
+ ret.push({ id: x.id, text: x.name, isNew: false });
+ });
+ lastsearch = ret;
+ return { results: ret };
}
- });
+ },
- $("input.load_tags").on('isTagAllowed', function(e, data) {
- if (_.indexOf($(this).textext()[0].tags()._formData, data.tag) != -1) {
- data.result = false;
- }
- });
- }
+ // Take default tags from the input value
+ initSelection: function (element, callback) {
+ var data = [];
+ _.each(JSON.parse(element.val()), function(x) {
+ data.push({ id: x.id, text: x.name, isNew: false });
+ });
+ element.val('');
+ callback(data);
+ },
+ });
- //TODO Remove in master
- if($('input.load_tags').length){
- var tags = $("input.load_tags").val();
- $("input.load_tags").val("");
- set_tags(tags);
- };
-
- function set_tags(tags) {
- $("input.load_tags").textext({
- plugins: 'tags focus autocomplete ajax',
- tagsItems: tags.split(","),
- //Note: The following list of keyboard keys is added. All entries are default except {32 : 'whitespace!'}.
- keys: {8: 'backspace', 9: 'tab', 13: 'enter!', 27: 'escape!', 37: 'left', 38: 'up!', 39: 'right',
- 40: 'down!', 46: 'delete', 108: 'numpadEnter', 32: 'whitespace!'},
- ajax: {
- url: '/forum/get_tags',
- dataType: 'json',
- cacheResults: true
- }
- });
- // Adds: create tags on space + blur
- $("input.load_tags").on('whitespaceKeyDown blur', function () {
- $(this).textext()[0].tags().addTags([ $(this).val() ]);
- $(this).val("");
- });
- $("input.load_tags").on('isTagAllowed', function(e, data) {
- if (_.indexOf($(this).textext()[0].tags()._formData, data.tag) != -1) {
- data.result = false;
+ if ($('textarea.load_editor').length) {
+ $('textarea.load_editor').each(function () {
+ if (this['id']) {
+ CKEDITOR.replace(this['id']).on('instanceReady', CKEDITORLoadComplete);
}
});
}
}
});
--
-
function IsKarmaValid(eventNumber,minKarma){
"use strict";
if(parseInt($("#karma").val()) >= minKarma){
<openerp>
<data>
+<!-- Editor custom -->
+<template id="assets_editor" inherit_id="website.assets_editor" name="Forum Editor Assets" groups="base.group_user">
+ <xpath expr="." position="inside">
- <script type="text/javascript" src="/website_forum/static/src/js/website.tour.forum.js"/>
+ <script type="text/javascript" src="/website_forum/static/src/js/website_forum.editor.js"/>
+ </xpath>
+</template>
+
+<!-- Front-end custom css / js + ckeditor lib and customization -->
+<template id="assets_frontend" inherit_id="website.assets_frontend" name="Forum Assets">
+ <xpath expr="." position="inside">
+ <link rel='stylesheet' href="/web/static/lib/jquery.textext/jquery.textext.css"/>
+ <link rel='stylesheet' href='/website_forum/static/src/css/website_forum.css'/>
+ <script type="text/javascript" src="/website_forum/static/src/js/website_forum.js"/>
+ <script type="text/javascript" src="/web/static/lib/jquery.textext/jquery.textext.js"/>
+ <script type="text/javascript">
+ var CKEDITOR_BASEPATH = '/web/static/lib/ckeditor/';
+ </script>
+ <script type="text/javascript" src="/web/static/lib/ckeditor/ckeditor.js"></script>
+ <script type="text/javascript">
+ CKEDITOR.config.toolbar = [['Bold','Italic','Underline','Strike'],['NumberedList','BulletedList', 'Blockquote']
+ ,['Outdent','Indent','Link','Unlink','Image'],] ;
+ </script>
+
+ </xpath>
+</template>
+
<!-- Layout add nav and footer -->
<template id="header_footer_custom" inherit_id="website.footer_default"
name="Footer Questions Link">
</t>
</template>
+<!-- Edition: Post Article -->
+<template id="new_link">
+ <t t-call="website_forum.header">
+ <h1 class="mt0">Submit a Link</h1>
+ <p class="mb32">
+ Share an awesome link. Your post will appear in the 'Newest' top-menu.
+ If the community vote on your post, it will get traction by being promoted
+ in the homepage.
+ </p><p>
+ We keep a high level of quality in showcased posts, only 20% of the submited
+ posts will be featured.
+ </p>
+ <form t-attf-action="/forum/#{ slug(forum) }/new?post_type=link" method="post" role="form" class="tag_text form-horizontal">
+ <input type="hidden" name="karma" t-attf-value="#{user.karma}" id="karma"/>
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="content_link">URL to Share</label>
+ <div class="col-sm-8">
+ <input type="text" name="post_name" required="True" t-attf-value="#{post_name}"
+ class="form-control mb16 link_url" placeholder="e.g. https://www.odoo.com"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="post_name">Post Title</label>
+ <div class="col-sm-8">
+ <input type="text" name="content" readonly="True" required="True" t-attf-value="#{content}"
+ class="form-control"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="post_tags">Tags</label>
+ <div class="col-sm-8">
+ <input type="text" name="post_tags" readonly="True" class="form-control load_tags"/>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="col-sm-offset-2 col-sm-8">
+ <button class="btn btn-primary" disabled="True" id="btn_post_your_article">Post Your Article</button>
+ </div>
+ </div>
+ </form>
+ </t>
+</template>
+
+<!-- Edition: Post your Discussion Topic -->
+<template id="new_discussion">
+ <t t-call="website_forum.header">
+ <h1 class="mt0">Post Your Discussion Topic</h1>
+ <p>
+ <b>Share</b> Start Something Awesome
+ </p>
+ <form t-attf-action="/forum/#{slug(forum)}/new?post_type=discussion" method="post" role="form" class="tag_text">
+ <input type="text" name="post_name" required="True" t-attf-value="#{post_name}"
+ class="form-control mb16" placeholder="Your Discussion Title..."/>
+ <input type="hidden" name="karma" t-attf-value="#{user.karma}" id="karma"/>
+ <textarea name="content" id="content" required="True" class="form-control load_editor">
+ <t t-esc="question_content"/>
+ </textarea>
+ <br/>
+ <input type="text" name="post_tags" placeholder="Tags" class="form-control load_tags"/>
- <br/>
++ <br/><br/>
+ <button class="btn btn-primary">Post Your Topic</button>
+ </form>
+ </t>
+</template>
+
<!-- Edition: ask your question -->
-<template id="ask_question">
+<template id="new_question">
<t t-call="website_forum.header">
- <t t-set="head">
- <script type="text/javascript">
- window.onload = function() {
- $("[data-toggle='popover']").popover();
- };
- </script>
- </t>
- <h1 class="mt0">Ask your Question</h1>
+ <h1 class="mt0">Ask Your Question</h1>
+ <p>
+ To improve your chance getting an answer:
+ </p>
<ul>
- <li> please, try to make your question interesting to others </li>
- <li> provide enough details and, if possible, give an example </li>
- <li> be clear and concise, avoid unnecessary introductions (Hi, ... Thanks...) </li>
+ <li>Set a clear, explicit and concise question title
+ (check
+ <a href="#" data-placement="top" data-toggle="popover" data-content="Inventory Date Problem, Task remaining hours, Can you help solve solve my tax computation problem in Canada?" title="Click to get bad question samples">bad examples</a>
+ and
+ <a href="#" data-placement="bottom" data-toggle="popover" data-content="How to create a physical inventory at an anterior date?, How is the 'remaining hours' field computed on tasks?, How to configure TPS and TVQ's canadian taxes?" title="Click to get good question titles">good examples</a>
+ ),
+ </li>
+ <li>Avoid unnecessary introductions (Hi,... Please... Thanks...),</li>
+ <li>Provide enough details and, if possible, give an example.</li>
</ul>
- <form t-attf-action="/forum/#{ slug(forum) }/question/new" method="post" role="form" class="tag_text">
- <input type="text" name="question_name" required="True" t-attf-value="#{question_name}"
- class="form-control" placeholder="Enter your Question"/>
- <h5 class="mt20">Please enter a descriptive question (should finish with a '?')</h5>
+ <form t-attf-action="/forum/#{slug(forum)}/new?post_type=question" method="post" role="form" class="tag_text">
+ <input type="text" name="post_name" required="True" t-attf-value="#{post_name}"
+ class="form-control mb16" placeholder="Your Question Title..."/>
<input type="hidden" name="karma" t-attf-value="#{user.karma}" id="karma"/>
- <input type="hidden" name="karma_retag" t-attf-value="#{forum.karma_retag}" id="karma_retag"/>
- <textarea name="content" required="True" class="form-control load_editor">
++
+ <textarea name="content" required="True" id="content" class="form-control load_editor">
<t t-esc="question_content"/>
</textarea>
<br/>
- <input type="text" name="post_tags" placeholder="Tags" class="form-control load_tags"/>
- <br/>
- <input type="hidden" name="tag_type" value="select2"/>
- <input type="hidden" name="question_tags" placeholder="Tags" class="form-control js_select2"/>
- <br/>
++ <input type="hidden" name="karma_retag" t-attf-value="#{forum.karma_retag}" id="karma_retag"/>
++ <input type="hidden" name="post_tags" placeholder="Tags" class="form-control js_select2"/>
++ <br/><br/>
<button t-attf-class="btn btn-primary #{(user.karma < forum.karma_ask) and 'karma_required' or ''}"
- id="btn_ask_your_question" t-att-data-karma="forum.karma_ask">Post Your Question</button>
+ t-att-data-karma="forum.karma_ask">Post Your Question</button>
</form>
- <script type="text/javascript">
- CKEDITOR.replace("content");
- </script>
</t>
</template>
<!-- Edition: edit a post -->
<template id="edit_post">
<t t-call="website_forum.header">
- <h3 t-if="not is_answer">Edit question</h3>
- <h3 t-if="is_answer">Edit answer</h3>
+ <h3 t-if="not is_answer">Edit <span t-field="post.post_type"/></h3>
+ <h3 t-if="is_answer">Edit reply</h3>
<form t-attf-action="/forum/#{slug(forum)}/post/#{slug(post)}/save" method="post" role="form" class="tag_text">
<div t-if="not is_answer">
- <input type="text" name="question_name" id="question_name" required="True"
- t-attf-value="#{post.name}" class="form-control" placeholder="Edit your Question"/>
- <h5 class="mt20">Please enter a descriptive question (should finish by a '?')</h5>
+ <input type="text" name="post_name" required="True"
+ t-attf-value="#{post.name}" class="form-control mb8" placeholder="Edit your Post"/>
+ <h5 t-if="post.post_type == 'question'" class="mt20">Please enter a descriptive question (should finish by a '?')</h5>
</div>
<input type="hidden" name="karma" t-attf-value="#{user.karma}" id="karma"/>
+ <input type="hidden" name="karma_retag" t-attf-value="#{forum.karma_retag}" id="karma_retag"/>
- <textarea name="content" required="True" class="form-control load_editor">
+ <textarea name="content" id="content" required="True" class="form-control load_editor">
<t t-esc="post.content"/>
</textarea>
<div t-if="not is_answer">
<br/>
- <input type="text" name="post_tag" class="form-control col-md-9 load_tags" placeholder="Tags" t-attf-value="#{tags}"/>
- <input type="hidden" name="tag_type" value="select2"/>
- <input type="hidden" name="question_tag" class="form-control col-md-9 js_select2" placeholder="Tags" t-attf-value="#{tags}"/>
++ <input type="text" name="post_tag" class="form-control col-md-9 js_select2" placeholder="Tags" t-attf-value="#{tags}"/>
<br/>
</div>
<button class="btn btn-primary btn-lg">Save</button>