[MERGE] new module: website_forum_doc + small fixes (close) in forum
authorFabien Pinckaers <fp@tinyerp.com>
Mon, 21 Apr 2014 20:57:39 +0000 (22:57 +0200)
committerFabien Pinckaers <fp@tinyerp.com>
Mon, 21 Apr 2014 20:57:39 +0000 (22:57 +0200)
bzr revid: fp@tinyerp.com-20140421205739-rki3bctinjy3amzy

19 files changed:
addons/website/static/src/css/editor.css
addons/website/static/src/css/editor.sass
addons/website_forum/controllers/main.py
addons/website_forum/models/forum.py
addons/website_forum/static/src/css/website_forum.css
addons/website_forum/static/src/css/website_forum.sass
addons/website_forum/static/src/js/website_forum.js
addons/website_forum/views/website_forum.xml
addons/website_forum_doc/__init__.py [new file with mode: 0644]
addons/website_forum_doc/__openerp__.py [new file with mode: 0644]
addons/website_forum_doc/controllers/__init__.py [new file with mode: 0644]
addons/website_forum_doc/controllers/main.py [new file with mode: 0644]
addons/website_forum_doc/data/doc_data.xml [new file with mode: 0644]
addons/website_forum_doc/data/doc_demo.xml [new file with mode: 0644]
addons/website_forum_doc/models/__init__.py [new file with mode: 0644]
addons/website_forum_doc/models/documentation.py [new file with mode: 0644]
addons/website_forum_doc/security/ir.model.access.csv [new file with mode: 0644]
addons/website_forum_doc/views/doc.xml [new file with mode: 0644]
addons/website_forum_doc/views/website_doc.xml [new file with mode: 0644]

index eb4c5b2..4e90388 100644 (file)
   content: "Press The Top-Left Edit Button" !important;
 }
 
+[data-oe-type=html].oe_no_empty:empty:before {
+  content: "" !important;
+}
+
+[data-oe-type=html].oe_no_empty:empty {
+  background-image: none !important;
+  height: 16px !important;
+}
+
 /* ---- EDITOR BAR ---- {{{ */
 table.editorbar-panel {
   cursor: pointer;
index fb80fa4..53eb89a 100644 (file)
 .oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before
     content: 'Press The Top-Left Edit Button' !important
 
+[data-oe-type=html].oe_no_empty:empty:before
+    content: '' !important
+
+[data-oe-type=html].oe_no_empty:empty
+    background-image: none !important
+    height: 16px !important
+
 // }}}
 
 /* ---- EDITOR BAR ---- {{{ */
index 354aa52..d6394b0 100644 (file)
@@ -105,6 +105,7 @@ class WebsiteForum(http.Controller):
 
         values = self._prepare_forum_values(forum=forum, searches=post)
         values.update({
+            'main_object': tag or forum,
             'question_ids': question_ids,
             'pager': pager,
             'tag': tag,
@@ -134,6 +135,7 @@ class WebsiteForum(http.Controller):
         values = self._prepare_forum_values(forum=forum, searches={'tags': True}, **post)
         values.update({
             'tags': tags,
+            'main_object': forum,
         })
         return request.website.render("website_forum.tag", values)
 
@@ -179,6 +181,7 @@ class WebsiteForum(http.Controller):
         filters = 'question'
         values = self._prepare_forum_values(forum=forum, searches=post)
         values.update({
+            'main_object': question,
             'question': question,
             'header': {'question_data': True},
             'filters': filters,
@@ -209,6 +212,7 @@ class WebsiteForum(http.Controller):
         values = self._prepare_forum_values(**post)
         values.update({
             'post': question,
+            'question': question,
             'forum': forum,
             'reasons': reasons,
         })
@@ -228,7 +232,7 @@ class WebsiteForum(http.Controller):
             'state': 'close',
             'closed_uid': request.uid,
             'closed_date': datetime.today().strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT),
-            'closed_reason_id': post.get('reason_id', False),
+            'closed_reason_id': int(post.get('reason_id', False)),
         }, context=request.context)
         return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
 
@@ -381,6 +385,7 @@ class WebsiteForum(http.Controller):
         values = self._prepare_forum_values(forum=forum, searches=searches)
         values .update({
             'users': users,
+            'main_object': forum,
             'notifications': self._get_notifications(),
             'pager': pager,
         })
@@ -515,7 +520,6 @@ class WebsiteForum(http.Controller):
     def badge_users(self, forum, badge, **kwargs):
         user_ids = [badge_user.user_id.id for badge_user in badge.owner_ids]
         users = request.registry['res.users'].browse(request.cr, SUPERUSER_ID, user_ids, context=request.context)
-
         values = self._prepare_forum_values(forum=forum, searches={'badges': True})
         values.update({
             'badge': badge,
index 031ae4b..166fdb8 100644 (file)
@@ -111,7 +111,7 @@ class Post(osv.Model):
         'state': fields.selection([('active', 'Active'), ('close', 'Close'), ('offensive', 'Offensive')], 'Status'),
         'views': fields.integer('Number of Views'),
         'active': fields.boolean('Active'),
-        'is_correct': fields.boolean('Valid Answer', help='Correct Answer/ Answer on this question accepted.'),
+        'is_correct': fields.boolean('Valid Answer', help='Correct Answer or Answer on this question accepted.'),
         'website_message_ids': fields.one2many(
             'mail.message', 'res_id',
             domain=lambda self: [
@@ -230,8 +230,9 @@ class Post(osv.Model):
 class PostReason(osv.Model):
     _name = "forum.post.reason"
     _description = "Post Closing Reason"
+    _order = 'name'
     _columns = {
-        'name': fields.char('Post Reason', required=True),
+        'name': fields.char('Post Reason', required=True, translate=True),
     }
 
 
index 1155ded..ab8ea68 100644 (file)
   font-size: 200%;
   font-weight: bold;
 }
+.box div.subtitle {
+  margin-top: -4px;
+}
 
 .question .question-name {
   font-size: 150%;
 }
+.question .badge {
+  background-color: #cccccc;
+  margin-left: 4px;
+}
 
 .oe_grey {
   background-color: #eeeeee;
 }
 
 .oe_answer_true {
-  color: #428bca;
+  color: #3c763d;
 }
 
 .oe_answer_false {
-  color: #999999;
+  color: #bbbbbb;
+}
+
+.favourite_question {
+  color: #bbbbbb !important;
 }
 
 .forum_favourite_question {
index f5bfb66..da2df14 100644 (file)
@@ -8,10 +8,15 @@
   span
     font-size: 200%
     font-weight: bold
+  div.subtitle
+    margin-top: -4px
 
 .question
   .question-name
     font-size: 150%
+  .badge
+    background-color: #ccc
+    margin-left: 4px
 
 .oe_grey
   background-color: #eeeeee
   color: #eea91e
 
 .oe_answer_true
-  color: #428bca
+  color: #3c763d
 
 .oe_answer_false
-  color: #999999
+  color: #bbbbbb
+
+.favourite_question
+  color: #bbbbbb !important
 
 .forum_favourite_question
   color: #ffcc00 !important
@@ -63,4 +71,4 @@ a.no-decoration
     font: 1.2em "Helvetica Neue", Helvetica, Arial, sans-serif !important
   .text-tags .text-tag .text-button
     font: 1.2em "Helvetica Neue", Helvetica, Arial, sans-serif !important
-    height: 1.2em !important
\ No newline at end of file
+    height: 1.2em !important
index 2c42874..f483fb9 100644 (file)
@@ -65,11 +65,10 @@ $(document).ready(function () {
                     $link.parent().append($warning);
                 }
             } else {
-                $link.parents().find(".oe_answer_true").removeClass("oe_answer_true alert alert-info").addClass('oe_answer_false');
-                $link.parents().find(".answer_correct").removeClass("answer_correct alert alert-info")
                 if (data) {
-                    $link.removeClass("oe_answer_false").addClass('oe_answer_true');
-                    $link.parents('.forum_answer').first().addClass("answer_correct alert alert-info");
+                    $link.addClass("oe_answer_true").removeClass('oe_answer_false');
+                } else {
+                    $link.removeClass("oe_answer_true").addClass('oe_answer_false');
                 }
             }
         });
index 2d1787a..1eda647 100644 (file)
         <t t-set="head">
             <link rel='stylesheet' href="/web/static/lib/jquery.textext/jquery.textext.css"/>
             <link rel='stylesheet' href='/website_forum/static/src/css/website_forum.css'/>
-            <!--
-            FP Note: Why do we need this ? Can we remove this code?
-            The problem is that you add your script for every page, not only for the forum
-            -->
             <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" src="/web/static/lib/ckeditor/ckeditor.js"/>
@@ -90,7 +86,7 @@
                 </div>
                 <div class="col-sm-3" id="right-column">
                     <a t-if="not header.get('ask_hide')" class="btn btn-primary btn-lg btn-block mb16" t-attf-href="/forum/#{slug(forum)}/ask">Ask a Question</a>
-                    <div class="panel panel-default">
+                    <div class="panel panel-default" id="about_forum">
                         <div class="panel-heading">
                             <h3 class="panel-title">About This Forum</h3>
                         </div>
 <template id="display_post">
     <div class="question clearfix">
         <div class="pull-left text-center">
-            <div t-attf-class="box #{question.child_count and 'oe_green' or 'oe_grey'}">
+            <div t-attf-class="box #{question.is_correct and 'oe_green' or 'oe_grey'} #{(question.child_count == 0) and 'text-muted' or ''}">
                 <span t-esc="question.child_count"/>
-                <span t-if="question.is_correct" class="fa fa-2x fa-check-circle"/>
-                <div t-if="question.child_count&gt;1">Answers</div>
-                <div t-if="question.child_count&lt;=1">Answer</div>
-            </div>
-            <div class="text-muted text-center">
-                <span t-field="question.views"/> Views
-            </div>
-        </div>
-        <div class="pull-right text-center">
-            <div class="box oe_grey">
-                <span t-esc="question.vote_count or 0"/>
-                <div t-if="question.vote_count&gt;1">Votes</div>
-                <div t-if="question.vote_count&lt;=1">Vote</div>
+                <div t-if="question.child_count&gt;1" class="subtitle">Answers</div>
+                <div t-if="question.child_count&lt;=1" class="subtitle">Answer</div>
             </div>
         </div>
-        <div style="margin-left: 95px;">
+        <div style="margin-left: 95px; margin-top:-8px;">
             <div class="question-name">
                 <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(question) }" t-field="question.name"/>
                     <span t-if="not question.active"><b> [Deleted]</b></span>
                     <span t-if="question.state == 'close'"><b> [Closed]</b></span>
             </div>
+            <t t-foreach="question.tag_ids" t-as="tag">
+                <a t-attf-href="/forum/#{ slug(forum) }/tag/#{ tag.id }/questions" class="badge pull-right" t-field="tag.name"/>
+            </t>
             <div class="text-muted">
                 by <a t-attf-href="/forum/#{ slug(forum) }/user/#{ question.create_uid.id }"
                     t-field="question.create_uid" t-field-options='{"widget": "contact", "country_image": true, "fields": ["name", "country_id"]}'
                     style="display: inline-block;"/>
                 on <span t-field="question.write_date" t-field-options='{"format":"short"}'/>
+                with <b t-field="question.views"/> views
+                <span t-if="question.vote_count&gt;0"> and 
+                    <b t-esc="question.vote_count or 0"/>
+                    <t t-if="question.vote_count&gt;1">votes</t>
+                    <t t-if="question.vote_count==1">vote</t>
+                </span>
             </div>
-            <t t-foreach="question.tag_ids" t-as="tag">
-                <a t-attf-href="/forum/#{ slug(forum) }/tag/#{ tag.id }/questions" class="badge" t-field="tag.name"/>
-            </t>
         </div>
     </div>
 </template>
 <!-- Moderation: close a question -->
 <template id="close_question">
     <t t-call="website_forum.header">
-        <h3 class=""><b>Close question</b></h3><br/>
-        <form t-attf-action="/forum/#{ slug(forum) }/question/#{slug(question)}/close" method="post" role="form">
+        <h1 class="mt0">Close question</h1>
+        <p class="text-muted">
+            If you close this question, it will be hidden for most users. Only
+            users having a high karma can see closed questions to moderate
+            them.
+        </p>
+        <form t-attf-action="/forum/#{ slug(forum) }/question/#{slug(post)}/close" method="post" role="form" class="form-horizontal mt32 mb64">
             <input name="post_id" t-att-value="post.id" type="hidden"/>
-            <span class="pull-left">Close the question:</span>
-            <a t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post) }" t-field="post.name"/>
-            <div class="mt16">
-                <label class="col-md-2 control-label mb16" for="reason">Reasons:</label>
-                <div class="col-md-9 mb16">
-                    <select class="form-control" name="reason">
+            <div class="form-group">
+                <label class="col-md-3 control-label" for="reason">Question:</label>
+                <div class="col-md-8 mt8">
+                    <span t-field="post.name"/>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="col-md-3 control-label" for="reason">Reason:</label>
+                <div class="col-md-8">
+                    <select class="form-control" name="reason_id">
                         <t t-foreach="reasons or []" t-as="reason">
                             <option t-att-value="reason.id" t-att-selected="reason.id == post.closed_reason_id.id"><t t-esc="reason.name"/></option>
                         </t>
                     </select>
                 </div>
             </div>
-            <div>
-                <button class="btn btn-primary btn-lg">Close</button>
+            <div class="form-group">
+                <div class="col-md-offset-3 col-md-8">
+                    <button class="btn btn-primary">Close question</button>
+                    <span class="text-muted">or</span>
+                    <a class="btn btn-link" t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post) }">back to question</a>
+                </div>
             </div>
         </form>
     </t>
         <span id="vote_count" t-esc="post.vote_count"/>
         <a t-attf-class="vote_down fa fa-thumbs-down no-decoration #{post.user_vote == -1 and 'text-warning' or ''}" 
             t-attf-href="/forum/#{slug(post.forum_id)}/post/#{slug(post)}/downvote"/>
-        <div>
+        <div t-if="vote_count &gt; 1" class="subtitle">
             votes
         </div>
+        <div t-if="vote_count &lt; 2" class="subtitle">
+            vote
+        </div>
     </div>
 </template>
 
 <!-- Specific Post Layout -->
 <template id="post_description_full" name="Question Navigation">
     <t t-call="website_forum.header">
-
         <div t-attf-class="question #{not question.active and 'alert alert-danger' or ''}">
             <div class="text-center pull-left">
                 <t t-call="website_forum.vote">
                     <t t-set="post" t-value="question"/>
                 </t>
-                <div class="text-muted">
-                    <span t-esc="question.child_count"/>
-                    <span t-if="question.child_count&gt;1">Answers</span>
-                    <span t-if="question.child_count&lt;=1">Answer</span>
+                <div class="text-muted text-center">
+                    <span t-field="question.views"/> Views
                 </div>
-                <div>
+                <div class="mt4">
                     <a t-attf-href="/forum/#{slug(question.forum_id)}/question/#{slug(question)}/toggle_favourite"
                         t-attf-class="favourite_question no-decoration fa fa-2x fa-star #{question.user_favourite and 'forum_favourite_question' or ''}"/>
                 </div>
                     <span t-if="not question.active"><b> [Deleted]</b></span>
                     <span t-if="question.state == 'close'"><b> [Closed]</b></span>
                 </h1>
+                <div class="alert alert-info" t-if="question.state == 'close'">
+                    <p class="mt32 mb16 text-center">
+                        <b>The question has been closed for reason: <i t-esc="question.closed_reason_id.name"/>
+                        <br/>
+                        <t t-if="question.closed_uid">
+                            <i>by <a t-attf-href="/forum/#{ slug(forum) }/user/#{ slug(question.closed_uid) }" t-field="question.closed_uid"/> </i>
+                        </t>
+                        on <span t-field="question.closed_date"/></b>
+                    </p>
+                    <div t-if="question.state == 'close' and user.karma&gt;=500" class="mb24 text-center">
+                        <a class="fa fa-arrow-right" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/reopen"> Reopen</a>
+                    </div>
+                </div>
                 <t t-raw="question.content"/>
 
                 <div class="mt16 clearfix">
                                 <a t-attf-href="/forum/#{ slug(forum) }/tag/#{ tag.id }/questions" class="badge" t-field="tag.name"/>
                             </t>
                         </div>
-                        <ul class="list-inline">
+                        <ul class="list-inline" id="options">
                             <li t-if="user.id == question.create_uid.id or user.karma&gt;=50">
                                 <a style="cursor: pointer" data-toggle="collapse" class="text-muted fa fa-comment-o"
                                       t-attf-data-target="#comment#{ question._name.replace('.','') + '-' + str(question.id) }">
-                                    comment
+                                    Comment
                                 </a>
                             </li>
                             <li t-if="question.state != 'close' and (user.id == question.create_uid.id or user.karma&gt;=100)">
-                                <a class="text-muted fa fa-times" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/ask_for_close">close</a>
-                            </li>
-                            <li t-if="question.state == 'close' and user.karma&gt;=500">
-                                <a class="text-muted fa fa-undo" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)/reopen">reopen</a>
+                                <a class="text-muted fa fa-times" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/ask_for_close"> Close</a>
                             </li>
                             <li t-if="user.id == question.create_uid.id or user.karma&gt;=300">
-                                <a class="text-muted fa fa-edit" t-attf-href="/forum/#{ slug(forum) }/post/#{slug(question)}/edit">edit</a>
+                                <a class="text-muted fa fa-edit" t-attf-href="/forum/#{ slug(forum) }/post/#{slug(question)}/edit"> Edit</a>
                             </li>
                             <li t-if="question.active and user.id == question.create_uid.id or user.karma&gt;=1000">
-                                <a class="text-muted fa fa-trash-o" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/delete">delete</a>
+                                <a class="text-muted fa fa-trash-o" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/delete"> Delete</a>
                             </li>
                             <li t-if="uid == question.create_uid.id and not question.active">
-                                <a class="text-muted fa fa-trash-o" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/undelete">undelete</a>
+                                <a class="text-muted fa fa-trash-o" t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/undelete"> Undelete</a>
                             </li>
-                            <li><a class="text-muted fa fa-share" t-attf-href="/forum/#{slug(forum)}/question/#{slug(question)}">share</a></li>
                         </ul>
                     </div>
                     <div>
                             <div t-field="question.create_uid" t-field-options='{"widget": "contact", "badges": true, "fields": ["karma"]}'/>
                         </div>
                     </div>
-                    <div class="alert alert-info" t-if="question.state == 'close'">
-                        <p class="mt32 mb32 text-center">
-                            <b>The question has been closed for the following reason "<span t-field="question.closed_reason_id.name"/>"
-                            <t t-if="question.closed_uid">
-                                <i>by <a t-attf-href="/forum/#{ slug(forum) }/user/#{ slug(question.closed_uid) }" t-field="question.closed_uid.name"/> </i>
-                            </t>
-                            <br/>close date <span t-field="question.closed_date"/></b>
-                        </p>
-                    </div>
                 </div>
                 <t t-call="website_forum.post_comment">
                     <t t-set="object" t-value="question"/>
 
         <div t-foreach="question.child_ids" t-as="answer" class="mt16 mb32">
             <a t-attf-id="answer-#{str(answer.id)}"/>
-            <div t-attf-class="forum_answer #{answer.is_correct and 'alert alert-info answer_correct' or ''}" t-attf-id="answer_#{answer.id}" >
+            <div t-attf-class="forum_answer" t-attf-id="answer_#{answer.id}" >
                 <div class="text-center pull-left">
                     <t t-call="website_forum.vote">
                         <t t-set="post" t-value="answer"/>
                     </t>
-                    <div class="text-muted">
-                        <a t-attf-class="accept_answer fa fa-2x fa-check-circle no-decoration oe_answer_true #{answer.is_correct and 'oe_answer_true' or 'oe_answer_false'}"
+                    <div class="text-muted mt8">
+                        <a t-attf-class="accept_answer fa fa-2x fa-check-circle no-decoration #{answer.is_correct and 'oe_answer_true' or 'oe_answer_false'}"
                             t-attf-href="/forum/#{slug(question.forum_id)}/post/#{slug(answer)}/toggle_correct"/>
                     </div>
                 </div>
                         <ul class="list-inline pull-right">
                             <li t-if="user.id == answer.create_uid.id or user.karma&gt;=50">
                                 <a style="cursor: pointer" data-toggle="collapse" class="text-muted fa fa-comment-o"
-                                      t-attf-data-target="#comment#{ answer._name.replace('.','') + '-' + str(answer.id) }">comment
+                                      t-attf-data-target="#comment#{ answer._name.replace('.','') + '-' + str(answer.id) }"> Comment
                                 </a>
                             </li>
                             <li t-if="user.id == answer.create_uid.id or user.karma&gt;=300">
-                                <a class="text-muted fa fa-edit" t-attf-href="/forum/#{slug(forum)}/post/#{slug(answer)}/edit">edit</a>
+                                <a class="text-muted fa fa-edit" t-attf-href="/forum/#{slug(forum)}/post/#{slug(answer)}/edit"> Edit</a>
                             </li>
                             <li t-if="user.id == answer.create_uid.id or user.karma&gt;=1000">
-                                <a class="text-muted fa fa-trash-o" t-attf-href="/forum/#{slug(forum)}/post/#{slug(answer)}/delete">delete</a>
+                                <a class="text-muted fa fa-trash-o" t-attf-href="/forum/#{slug(forum)}/post/#{slug(answer)}/delete"> Delete</a>
                             </li>
                             <li t-if="user.id == answer.create_uid.id">
-                                <a class="text-muted fa fa-magic" t-attf-href="/forum/#{slug(forum)}/post/#{slug(answer)}/convert_to_comment">Convert as a comment</a>
+                                <a class="text-muted fa fa-magic" t-attf-href="/forum/#{slug(forum)}/post/#{slug(answer)}/convert_to_comment"> Convert as a comment</a>
                             </li>
-                            <li><a class="text-muted fa fa-share" t-attf-href="/forum/#{slug(forum)}/question/#{slug(question)}/#answer_#{answer.id}">share</a></li>
                         </ul>
                         <span t-field="answer.create_uid.image" t-field-options='{"widget": "image", "class":"pull-left img img-circle img-avatar"}'/>
                         <div>
 <template id="post_comment">
     <div class="row clearfix">
         <div class="col-sm-10 col-sm-offset-2">
-            <div t-foreach="reversed(object.website_message_ids)" t-as="message" class="comment oe_comment_grey mb8">
+            <div t-foreach="reversed(object.website_message_ids)" t-as="message" class="comment oe_comment_grey">
                 <small class="text-muted">
                     <button type="button" t-if="user.partner_id.id == message.author_id.id and user.karma&gt;=750"
                         t-attf-href="/forum/#{slug(forum)}/post/#{slug(object)}/comment/#{slug(message)}/delete" 
                 </small>
             </div>
             <div class="css_editable_mode_hidden">
-                <form t-attf-id="comment#{ object._name.replace('.','') + '-' + str(object.id) }" class="collapse"
+                <form t-attf-id="comment#{ object._name.replace('.','') + '-' + str(object.id) }" class="collapse oe_comment_grey"
                         t-attf-action="/forum/#{slug(forum)}/post/#{slug(object)}/comment" method="POST">
-                    <input name="post_id" t-att-value="object.id" type="hidden"/>
+                    <input name="post_id" t-att-value="object.id" type="hidden" class="mt8"/>
                     <textarea name="comment" class="form-control" placeholder="Comment this post..."/>
                     <button type="submit" class="btn btn-primary mt8">Post</button>
                 </form>
                 </tr>
                 </table>
                 <div class="well well-sm">
-                    <span t-field="user.partner_id.website_description"/>
+                    <span t-field="user.partner_id.website_description" class="oe_no_empty"/>
                     <t t-if="uid == user.id">
                         <a class="fa fa-arrow-right" t-attf-href="/forum/#{slug(forum)}/user/#{slug(user)}/edit"> Edit Your Bio</a>
                     </t>
                 </div>
             </div>
             <div class="tab-pane" id="followed_question">
-                <div t-foreach="followed" t-as="question">
+                <div t-foreach="followed" t-as="question" class="mb16">
                     <t t-call="website_forum.display_post"/>
                 </div>
             </div>
diff --git a/addons/website_forum_doc/__init__.py b/addons/website_forum_doc/__init__.py
new file mode 100644 (file)
index 0000000..bde83af
--- /dev/null
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+import controllers
+import models
diff --git a/addons/website_forum_doc/__openerp__.py b/addons/website_forum_doc/__openerp__.py
new file mode 100644 (file)
index 0000000..e933e2c
--- /dev/null
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{
+    'name': 'Documentation',
+    'category': 'Website',
+    'summary': 'Forum, Documentation',
+    'version': '1.0',
+    'description': """
+Documentation based on question and pertinent answers of Forum
+        """,
+    'author': 'OpenERP SA',
+    'depends': [
+        'website_forum'
+    ],
+    'data': [
+        'data/doc_data.xml',
+        'security/ir.model.access.csv',
+        'views/doc.xml',
+        'views/website_doc.xml',
+    ],
+    'demo': [
+        'data/doc_demo.xml',
+    ],
+    'installable': True,
+    'application': True,
+}
diff --git a/addons/website_forum_doc/controllers/__init__.py b/addons/website_forum_doc/controllers/__init__.py
new file mode 100644 (file)
index 0000000..bbd183e
--- /dev/null
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import main
diff --git a/addons/website_forum_doc/controllers/main.py b/addons/website_forum_doc/controllers/main.py
new file mode 100644 (file)
index 0000000..4075479
--- /dev/null
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+
+from openerp.addons.web import http
+from openerp.addons.web.http import request
+from openerp.addons.website.models.website import slug
+
+
+class WebsiteDoc(http.Controller):
+    @http.route(['/forum/how-to', '/forum/how-to/<model("forum.documentation.toc"):toc>'], type='http', auth="public", website=True, multilang=True)
+    def toc(self, toc=None, **kwargs):
+        cr, uid, context, toc_id = request.cr, request.uid, request.context, False
+        if toc:
+            sections = toc.child_ids
+            forum = toc.forum_id
+        else:
+            toc_obj = request.registry['forum.documentation.toc']
+            obj_ids = toc_obj.search(cr, uid, [('parent_id', '=', False)], context=context)
+            sections = toc_obj.browse(cr, uid, obj_ids, context=context)
+            forum = sections and sections[0].forum_id or False
+        value = {
+            'toc': toc,
+            'main_object': toc or forum,
+            'forum': forum,
+            'sections': sections,
+        }
+        return request.website.render("website_forum_doc.documentation", value)
+
+    @http.route(['/forum/how-to/<model("forum.documentation.toc"):toc>/<model("forum.post"):post>'], type='http', auth="public", website=True, multilang=True)
+    def post(self, toc, post, **kwargs):
+        # TODO: implement a redirect instead of crash
+        assert post.documentation_toc_id.id == toc.id, "Wrong post!"
+        value = {
+            'toc': toc,
+            'post': post,
+            'main_object': post,
+            'forum': post.forum_id
+        }
+        return request.website.render("website_forum_doc.documentation_post", value)
+
+    @http.route('/forum/<model("forum.forum"):forum>/question/<model("forum.post"):post>/promote', type='http', auth="user", multilang=True, website=True)
+    def post_toc(self, forum, post, **kwargs):
+        cr, uid, context, toc_id = request.cr, request.uid, request.context, False
+        user = request.registry['res.users'].browse(cr, uid, uid, context=context)
+        assert user.karma >= 200, 'Not enough karma'
+        toc_obj = request.registry['forum.documentation.toc']
+        obj_ids = toc_obj.search(cr, uid, [], context=context)
+        tocs = toc_obj.browse(cr, uid, obj_ids, context=context)
+        value = {
+            'post': post,
+            'forum': post.forum_id,
+            'chapters': filter(lambda x: not x.child_ids, tocs)
+        }
+        return request.website.render("website_forum_doc.promote_question", value)
+
+    @http.route('/forum/<model("forum.forum"):forum>/promote_ok', type='http', auth="user", multilang=True, website=True)
+    def post_toc_ok(self, forum, post_id, toc_id, **kwargs):
+        cr, uid, context = request.cr, request.uid, request.context
+        user = request.registry['res.users'].browse(cr, uid, uid, context=context)
+        assert user.karma >= 200, 'Not enough karma'
+
+        toc_obj = request.registry['forum.documentation.toc']
+        stage_ids = toc_obj.search(cr, uid, [], limit=1, context=context)
+
+        post_obj = request.registry['forum.post']
+        post_obj.write(cr, uid, [int(post_id)], {
+            'documentation_toc_id': toc_id and int(toc_id) or False,
+            'documentation_stage_id': stage_ids and stage_ids[0] or False
+        }, context=context)
+        return request.redirect('/forum/'+str(forum.id)+'/question/'+str(post_id))
+
diff --git a/addons/website_forum_doc/data/doc_data.xml b/addons/website_forum_doc/data/doc_data.xml
new file mode 100644 (file)
index 0000000..8252ff9
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="menu_questions" model="website.menu">
+            <field name="name">Documentation</field>
+            <field name="url" eval="'/forum/how-to'"/>
+            <field name="parent_id" ref="website.main_menu"/>
+            <field name="sequence" type="int">65</field>
+        </record>
+
+        <!-- JUMP TO DOCUMENTATION AT INSTALL -->
+        <record id="action_open_documentation" model="ir.actions.act_url">
+            <field name="name">Documentation</field>
+            <field name="target">self</field>
+            <field name="url" eval="'/forum/how-to'"/>
+        </record>
+        <record id="base.open_menu" model="ir.actions.todo">
+            <field name="action_id" ref="action_open_documentation"/>
+            <field name="state">open</field>
+        </record>
+
+        <!-- Stages -->
+
+        <record id="stage_ideas" model="forum.documentation.stage">
+            <field name="name">Ideas</field>
+            <field name="sequence">1</field>
+        </record>
+
+        <record id="stage_draft" model="forum.documentation.stage">
+            <field name="name">Draft</field>
+            <field name="sequence">2</field>
+        </record>
+
+        <record id="stage_review" model="forum.documentation.stage">
+            <field name="name">Review</field>
+            <field name="sequence">3</field>
+        </record>
+
+        <record id="stage_publish" model="forum.documentation.stage">
+            <field name="name">Publish</field>
+            <field name="sequence">4</field>
+        </record>
+
+    </data>
+</openerp>
diff --git a/addons/website_forum_doc/data/doc_demo.xml b/addons/website_forum_doc/data/doc_demo.xml
new file mode 100644 (file)
index 0000000..0b98c48
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <!-- Table Of Content -->
+        <record id="toc_functional_doc" model="forum.documentation.toc">
+            <field name="name">Functional Documentation</field>
+            <field name="introduction" type="html">
+                <p class="text-muted">
+                    This documentation is produced using the best posts from the
+                    <a href="/forum">community forum</a>.
+                </p>
+            </field>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_sale" model="forum.documentation.toc">
+            <field name="name">Sales Management</field>
+            <field name="parent_id" ref="toc_functional_doc"/>
+            <field name="introduction" type="html">
+                <p class="text-muted">
+                    Tracks leads, boost opportunities and close deals.
+                    This serie of how-to will help you develop your business.
+                </p>
+            </field>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_sale_customer" model="forum.documentation.toc">
+            <field name="name">Customers</field>
+            <field name="parent_id" ref="toc_sale"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_sale_so" model="forum.documentation.toc">
+            <field name="name">Sales orders</field>
+            <field name="parent_id" ref="toc_sale"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_0" model="forum.documentation.toc">
+            <field name="name">Sales &amp; Warehouse</field>
+            <field name="parent_id" ref="toc_sale"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_crm" model="forum.documentation.toc">
+            <field name="name">Customer Relationship Management</field>
+            <field name="parent_id" ref="toc_functional_doc"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_crm_lead" model="forum.documentation.toc">
+            <field name="name">Lead &amp; Opportunity</field>
+            <field name="parent_id" ref="toc_crm"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_crm_claim" model="forum.documentation.toc">
+            <field name="name">Claims</field>
+            <field name="parent_id" ref="toc_crm"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_crm_after_sale" model="forum.documentation.toc">
+            <field name="name">After-sale communication</field>
+            <field name="parent_id" ref="toc_crm"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_website" model="forum.documentation.toc">
+            <field name="name">Website</field>
+            <field name="parent_id" ref="toc_functional_doc"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_cms_ecommerce" model="forum.documentation.toc">
+            <field name="name">CMS &amp; eCommerce</field>
+            <field name="parent_id" ref="toc_website"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_hrm" model="forum.documentation.toc">
+            <field name="name">Human Resources Management</field>
+            <field name="parent_id" ref="toc_functional_doc"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+        <record id="toc_hrm_contract" model="forum.documentation.toc">
+            <field name="name">Employee Contract</field>
+            <field name="parent_id" ref="toc_hrm"/>
+            <field name="forum_id" ref="website_forum.forum_help"/>
+        </record>
+
+        <!-- Questions -->
+        <record id="website_forum.question_0" model="forum.post">
+            <field name="documentation_toc_id" ref="toc_hrm_contract"/>
+        </record>
+        <record id="website_forum.question_1" model="forum.post">
+            <field name="documentation_toc_id" ref="toc_cms_ecommerce"/>
+        </record>
+
+    </data>
+</openerp>
diff --git a/addons/website_forum_doc/models/__init__.py b/addons/website_forum_doc/models/__init__.py
new file mode 100644 (file)
index 0000000..d64a59f
--- /dev/null
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import documentation
diff --git a/addons/website_forum_doc/models/documentation.py b/addons/website_forum_doc/models/documentation.py
new file mode 100644 (file)
index 0000000..91e4e56
--- /dev/null
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+import openerp
+from openerp.osv import osv, fields
+
+class Documentation(osv.Model):
+    _name = 'forum.documentation.toc'
+    _description = 'Documentation ToC'
+    _inherit = ['website.seo.metadata']
+    _order = "parent_left"
+    _parent_order = "sequence, name"
+    _parent_store = True
+    def name_get(self, cr, uid, ids, context=None):
+        if isinstance(ids, (list, tuple)) and not len(ids):
+            return []
+        if isinstance(ids, (long, int)):
+            ids = [ids]
+        reads = self.read(cr, uid, ids, ['name','parent_id'], context=context)
+        res = []
+        for record in reads:
+            name = record['name']
+            if record['parent_id']:
+                name = record['parent_id'][1]+' / '+name
+            res.append((record['id'], name))
+        return res
+
+    def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
+        res = self.name_get(cr, uid, ids, context=context)
+        return dict(res)
+
+    _columns = {
+        'sequence': fields.integer('Sequence'),
+        'display_name': fields.function(_name_get_fnc, type="char", string='Full Name'),
+        'name': fields.char('Name', required=True, translate=True),
+        'introduction': fields.html('Introduction', translate=True),
+        'parent_id': fields.many2one('forum.documentation.toc', 'Parent Table Of Content'),
+        'child_ids': fields.one2many('forum.documentation.toc', 'parent_id', 'Children Table Of Content'),
+        'parent_left': fields.integer('Left Parent', select=True),
+        'parent_right': fields.integer('Right Parent', select=True),
+        'post_ids': fields.one2many('forum.post', 'documentation_toc_id', 'Posts'),
+        'forum_id': fields.many2one('forum.forum', 'Forum', required=True),
+    }
+
+    _constraints = [
+        (osv.osv._check_recursion, 'Error ! You cannot create recursive categories.', ['parent_id'])
+    ]
+
+
+class DocumentationStage(osv.Model):
+    _name = 'forum.documentation.stage'
+    _description = 'Post Stage'
+    _order = 'sequence'
+    _columns = {
+        'sequence': fields.integer('Sequence'),
+        'name': fields.char('Stage Name', required=True, translate=True),
+    }
+
+
+class Post(osv.Model):
+    _inherit = 'forum.post'
+    _columns = {
+        'documentation_toc_id': fields.many2one('forum.documentation.toc', 'Documentation ToC'),
+        'documentation_stage_id': fields.many2one('forum.documentation.stage', 'Documentation Stage'),
+        'color': fields.integer('Color Index')
+    }
+    def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
+        stage_obj = self.pool.get('forum.documentation.stage')
+        stage_ids = stage_obj.search(cr, uid, [], context=context)
+        result = stage_obj.name_get(cr, uid, stage_ids, context=context)
+        return result, {}
+
+    _group_by_full = {
+        'documentation_stage_id': _read_group_stage_ids,
+    }
+
diff --git a/addons/website_forum_doc/security/ir.model.access.csv b/addons/website_forum_doc/security/ir.model.access.csv
new file mode 100644 (file)
index 0000000..64995ad
--- /dev/null
@@ -0,0 +1,4 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+all_documentation_toc,forum.documentation.toc,model_forum_documentation_toc,,1,0,0,0
+users_documentation_toc,forum.documentation.toc,model_forum_documentation_toc,base.group_user,1,1,1,1
+users_documentation_stage,forum.documentation.stage,model_forum_documentation_stage,base.group_user,1,1,1,1
diff --git a/addons/website_forum_doc/views/doc.xml b/addons/website_forum_doc/views/doc.xml
new file mode 100644 (file)
index 0000000..8744cb0
--- /dev/null
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<openerp>
+    <data>
+
+        <!-- DOCUMENTATION TOC VIEWS -->
+
+        <record id="view_documentation_toc_list" model="ir.ui.view">
+            <field name="name">forum.documentation.toc.list</field>
+            <field name="model">forum.documentation.toc</field>
+            <field name="arch" type="xml">
+                <tree string="Documentation TOC" editable="bottom">
+                    <field name="sequence" widget="handle"/>
+                    <field name="name"/>
+                    <field name="forum_id"/>
+                    <field name="parent_id"/>
+                </tree>
+            </field>
+        </record>
+        <record id="action_documentation_toc" model="ir.actions.act_window">
+            <field name="name">Documentation</field>
+            <field name="res_model">forum.documentation.toc</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">tree</field>
+        </record>
+        <menuitem id="menu_documentation"
+            parent="website_forum.menu_website_forum" groups="base.group_user"
+            name="Documentation ToC" action="action_documentation_toc" sequence="20"/>
+
+
+        <record id="view_documentation_toc_list" model="ir.ui.view">
+            <field name="name">forum.documentation.toc.list</field>
+            <field name="model">forum.documentation.toc</field>
+            <field name="arch" type="xml">
+                <tree string="Documentation TOC" editable="bottom">
+                    <field name="sequence" widget="handle"/>
+                    <field name="name"/>
+                    <field name="parent_id"/>
+                </tree>
+            </field>
+        </record>
+        <record id="action_documentation_toc" model="ir.actions.act_window">
+            <field name="name">Documentation</field>
+            <field name="res_model">forum.documentation.toc</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">tree</field>
+        </record>
+        <menuitem id="menu_documentation"
+            parent="website_forum.menu_website_forum" groups="base.group_user"
+            name="Documentation ToC" action="action_documentation_toc" sequence="20"/>
+
+
+        <!-- Project Task Kanban View -->
+        <record model="ir.ui.view" id="view_forum_post_kanban">
+            <field name="name">forum.post.kanban</field>
+            <field name="model">forum.post</field>
+            <field name="arch" type="xml">
+                <kanban default_group_by="documentation_stage_id" >
+                    <field name="documentation_stage_id"/>
+                    <field name="create_uid"/>
+                    <field name="color"/>
+                    <templates>
+                    <t t-name="kanban-box">
+                        <div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
+                            <div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_user">
+                                <span class="oe_e">í</span>
+                                <ul class="oe_dropdown_menu">
+                                    <li t-if="widget.view.is_action_enabled('edit')"><a type="edit">Edit...</a></li>
+                                    <li t-if="widget.view.is_action_enabled('delete')"><a type="delete">Delete</a></li>
+                                    <li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
+                                </ul>
+                            </div>
+                            <div class="oe_kanban_content">
+                                <div><b><field name="name"/></b></div>
+                                <div class="oe_kanban_bottom_right">
+                                    <img t-att-src="kanban_image('res.users', 'image_small', record.create_uid.raw_value)" t-att-title="record.create_uid.value" width="24" height="24" class="oe_kanban_avatar"/>
+                                </div>
+                            </div>
+                            <div class="oe_clear"></div>
+                        </div>
+                    </t>
+                    </templates>
+                </kanban>
+            </field>
+        </record>
+
+        <record id="action_forum_doc_post" model="ir.actions.act_window">
+            <field name="name">Documentation Posts</field>
+            <field name="res_model">forum.post</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">kanban,tree,form</field>
+            <field name="domain">[('documentation_toc_id','&lt;&gt;', False)]</field>
+        </record>
+        <menuitem id="menu_forum_doc_posts"
+            parent="website_forum.menu_website_forum" name="Documentation Posts"
+            action="action_forum_doc_post" sequence="25"/>
+
+
+
+    </data>
+</openerp>
diff --git a/addons/website_forum_doc/views/website_doc.xml b/addons/website_forum_doc/views/website_doc.xml
new file mode 100644 (file)
index 0000000..ee06ac7
--- /dev/null
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <!-- Layout add nav and footer -->
+        <template id="header_footer_custom" inherit_id="website.layout"
+            name="Footer Documentation Link">
+            <xpath expr="//footer//ul[@name='products']" position="inside">
+                <li><a href="/forum/how-to">Documentation</a></li>
+            </xpath>
+        </template>
+
+        <!-- Page Index -->
+        <template id="toc" name="Documentation Index">
+            <t t-set="level" t-value="level+1"/>
+            <t t-foreach="titles" t-as="title">
+                <div t-attf-class="h#{str(level) + (level&lt;3 and ' page-header' or '')}">
+                    <t t-esc="title.name"/>
+                    <small t-if="len(title.post_ids)">
+                        <t t-esc="len(title.post_ids)"/>
+                        <t t-if="len(title.post_ids)==1">essay</t>
+                        <t t-if="len(title.post_ids)&gt;1">essays</t>
+                    </small>
+                </div>
+
+                <ul t-if="title.post_ids" class="mt32">
+                    <li t-foreach="title.post_ids" t-as="post">
+                        <a t-attf-href="/forum/how-to/#{slug(title)}/#{slug(post)}" t-field="post.name"/>
+                    </li>
+                </ul>
+
+                <t t-set="titles" t-value="title.child_ids"/>
+                <t t-call="website_forum_doc.toc"/>
+            </t>
+        </template>
+
+        <template id="breadcrumb" name="Documentation Breadcrumb">
+            <t t-if="toc.parent_id">
+                <t t-call="website_forum_doc.breadcrumb">
+                    <t t-set="toc" t-value="toc.parent_id"/>
+                </t>
+            </t>
+            <li t-if="toc">
+                <a t-attf-href="/forum/how-to/#{ slug(toc) }" t-field="toc.name"/>
+            </li>
+        </template>
+
+        <template id="documentation" name="Documentation Index">
+            <t t-call="website.layout">
+                <section class="container mt16" t-if="toc">
+                    <div class="row">
+                        <div class="col-sm-8">
+                            <ol class="breadcrumb mb0">
+                                <t t-call="website_forum_doc.breadcrumb">
+                                    <t t-set="toc" t-value="toc.parent_id"/>
+                                </t>
+                                <li class="active">
+                                    <span t-field="toc.name"/>
+                                </li>
+                            </ol>
+                        </div>
+                        <div class="col-sm-4 text-right">
+                            <form class="navbar-form navbar-right mt0" role="search" t-attf-action="/forum/#{ slug(forum) }" method="get">
+                                <div class="form-group">
+                                    <input type="search" class="form-control"
+                                        name="search" placeholder="Search..."
+                                        t-att-value="search or ''"/>
+                                    <button type="submit" class="btn btn-default">Search</button>
+                                </div>
+                            </form>
+                        </div>
+                    </div>
+                </section>
+                <section class="container">
+                    <t t-set="level" t-value="toc and 1 or 0"/>
+                    <h1 class="page-header" t-if="toc">
+                        <t t-esc="toc.name"/>
+                    </h1>
+                    <t t-set="titles" t-value="sections"/>
+                    <t t-call="website_forum_doc.toc"/>
+                </section>
+                <div class="oe_structure"/>
+            </t>
+        </template>
+
+        <template id="documentation_post" name="Documentation Question">
+            <t t-call="website.layout">
+                <section class="container mt16" t-if="toc">
+                    <div class="row">
+                        <div class="col-sm-8">
+                            <ol class="breadcrumb mb0">
+                                <t t-call="website_forum_doc.breadcrumb">
+                                    <t t-set="toc" t-value="toc.parent_id"/>
+                                </t>
+                                <li>
+                                    <a t-attf-href="/forum/how-to/#{ slug(toc) }" t-field="toc.name"/>
+                                </li>
+                            </ol>
+                        </div>
+                        <div class="col-sm-4 text-right" t-if="forum">
+                            <form class="navbar-form navbar-right mt0" role="search" t-attf-action="/forum/#{ slug(forum) }" method="get">
+                                <div class="form-group">
+                                    <input type="search" class="form-control"
+                                        name="search" placeholder="Search..."
+                                        t-att-value="search or ''"/>
+                                    <button type="submit" class="btn btn-default">Search</button>
+                                </div>
+                            </form>
+                        </div>
+                    </div>
+                </section>
+
+                <section class="container">
+                    <div class="row">
+                        <div class="col-sm-9">
+                            <h1 class="page-header" t-field="post.name"/>
+                            <blockquote t-if="bool(post.content)">
+                                <t t-raw="post.content"/>
+                            </blockquote>
+
+                            <t t-if="post.child_ids">
+                                <t t-raw="post.child_ids[0].content"/>
+                            </t>
+                            <div t-if="len(toc.post_ids)&gt;1">
+                                <h2 class="page-header">Related topics</h2>
+                                <ul>
+                                    <t t-foreach="toc.post_ids" t-as="topic">
+                                        <li t-if="post.id != topic.id">
+                                            <a t-attf-href="/forum/how-to/#{slug(toc)}/#{slug(topic)}" t-field="post.name"/>
+                                        </li>
+                                    </t>
+                                </ul>
+                            </div>
+                        </div><div class="col-sm-3">
+                            <div class="panel panel-default mt48" id="about_doc">
+                                <div class="panel-heading">
+                                    <h3 class="panel-title">Need more info?</h3>
+                                </div>
+                                <div class="panel-body">
+                                    <div class="text-muted">
+                                        This documentation page has been extracted
+                                        from the Q&amp;A section where you can
+                                        discuss it and get feedback.
+                                    </div>
+                                    &amp;nbsp; <a t-attf-href="/forum/#{slug(forum)}/question/#{slug(post)}" class="fa fa-arrow-right mt16"> Related question</a>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </section>
+                <div class="oe_structure mt16 mb16"/>
+            </t>
+        </template>
+
+
+        <!--TOC ON FORUM POST-->
+        <template id="forum_question_doc" inherit_id="website_forum.post_description_full" name="Forum Post to Doc">
+            <xpath expr="//ul[@id='options']" position="inside">
+                <li t-if="(not question.documentation_stage_id) and user.karma&gt;=200">
+                    <a t-attf-href="/forum/#{ slug(forum) }/question/#{slug(question)}/promote" class="text-muted fa fa-bookmark-o">
+                        Promote to Doc
+                    </a>
+                </li>
+            </xpath>
+            <xpath expr="//hr" position="before">
+                <div class="alert alert-success alert-dismissable mt16" t-if="question.documentation_toc_id">
+                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
+                    This question has been included in the <a href="/forum/how-to">official documentation</a>.
+                </div>
+            </xpath>
+        </template>
+
+        <template id="promote_question">
+            <t t-call="website.layout">
+                <section class="container">
+                    <h1 class="page-header">Promote question to documentation</h1>
+                    <p>
+                        To be promoted in the official documentation the question
+                        and answer must satisfy the following criteria:
+                    </p>
+                    <ul>
+                        <li>The question title is short and descriptive</li>
+                        <li>The question describes a real business problem, not a software problem</li>
+                        <li>The answer is understandable for someone who does not know Odoo</li>
+                    </ul>
+                    <p>
+                        Before submiting the question, help us improve its quality by
+                        editing the question and the main answer.
+                    </p>
+                </section>
+                <div class="container">
+                    <div class="well">
+                        <form t-attf-action="/forum/#{ slug(forum) }/promote_ok" method="post" role="form" class="form-horizontal">
+                            <input name="post_id" t-att-value="post.id" type="hidden"/>
+                            <div class="form-group">
+                                <label class="col-md-3 control-label" for="reason">Question:</label>
+                                <div class="col-md-8 mt8">
+                                    <span t-field="post.name"/>
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-md-3 control-label" for="reason">Publish in Chapter:</label>
+                                <div class="col-md-8">
+                                    <select class="form-control" name="toc_id">
+                                        <option/>
+                                        <t t-foreach="chapters or []" t-as="chapter">
+                                            <option t-att-value="chapter.id"><t t-esc="chapter.display_name"/></option>
+                                        </t>
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <div class="col-md-offset-3 col-md-8">
+                                    <button class="btn btn-primary">Push to documentation</button>
+                                    <span class="text-muted">or</span>
+                                    <a class="btn btn-link" t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post) }">cancel</a>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+                <section class="container">
+                    <h2 class="page-header">Samples</h2>
+                    <div class="row">
+                        <div class="col-sm-6">
+                            <h4>Good question titles</h4>
+                            <ul>
+                                <li>How to forecast sales revenues?</li>
+                                <li>How to compute future inventories for a product?</li>
+                            </ul>
+
+                        </div>
+                        <div class="col-sm-6">
+                            <h4>Bad questions</h4>
+                            <ul>
+                                <li>What report should I use to compute probabilities per stage?</li>
+                                <li>What's the available stock field?</li>
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="row mb64">
+                        <div class="col-sm-6">
+                            <h4>Good answer structure</h4>
+                            <ol>
+                                <li>Describe the business solution</li>
+                                <li>Explain how to implement it in OpenERP</li>
+                                <li>Benefits of having done this setup</li>
+                            </ol>
+                        </div>
+                        <div class="col-sm-6">
+                            <h4>Bad answer structure</h4>
+                            <ol>
+                                <li>Explain how to configure in OpenERP</li>
+                                <li>No business benefit</li>
+                            </ol>
+                        </div>
+                    </div>
+                </section>
+            </t>
+        </template>
+
+
+    </data>
+</openerp>