[REF] website_mail refactoring
It is now called website_blog, and not based on mail.group anymore. It uses document_page module, previously renamed blog.post (see previous commits). Refactored controllers and views to work with the new model. Added website_mail module, that holds mail-related stuff necessary for the website. This is an auto-install module. bzr revid: tde@openerp.com-20130920135643-rey5bwza2e96v7h5
This commit is contained in:
parent
6cf1703127
commit
4c3b516a7b
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2013-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/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
import controllers
|
||||||
|
import document_page
|
||||||
|
import res_config
|
|
@ -0,0 +1,44 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2013-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': 'Blogs',
|
||||||
|
'category': 'Website',
|
||||||
|
'summary': 'News, Blogs, Announces, Discussions',
|
||||||
|
'version': '1.0',
|
||||||
|
'description': """
|
||||||
|
OpenERP Blog
|
||||||
|
============
|
||||||
|
|
||||||
|
""",
|
||||||
|
'author': 'OpenERP SA',
|
||||||
|
'depends': ['website_mail', 'document_page'],
|
||||||
|
'data': [
|
||||||
|
'website_mail_data.xml',
|
||||||
|
'views/website_mail.xml',
|
||||||
|
'views/res_config.xml',
|
||||||
|
'security/website_mail.xml',
|
||||||
|
],
|
||||||
|
'qweb': [
|
||||||
|
'static/src/xml/*.xml'
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2013-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/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp import SUPERUSER_ID
|
||||||
|
from openerp.addons.web import http
|
||||||
|
from openerp.addons.web.http import request
|
||||||
|
from openerp.addons.website import website
|
||||||
|
from openerp.tools.translate import _
|
||||||
|
from openerp.tools.safe_eval import safe_eval
|
||||||
|
|
||||||
|
import simplejson
|
||||||
|
import werkzeug
|
||||||
|
|
||||||
|
|
||||||
|
class website_mail(http.Controller):
|
||||||
|
_category_post_per_page = 2
|
||||||
|
_post_comment_per_page = 2
|
||||||
|
|
||||||
|
@website.route([
|
||||||
|
'/blog/',
|
||||||
|
'/blog/<int:category_id>/',
|
||||||
|
'/blog/<int:category_id>/<int:blog_post_id>/',
|
||||||
|
'/blog/<int:category_id>/page/<int:page>/',
|
||||||
|
'/blog/<int:category_id>/<int:blog_post_id>/page/<int:page>/'
|
||||||
|
], type='http', auth="public")
|
||||||
|
def blog(self, category_id=None, blog_post_id=None, page=1, **post):
|
||||||
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
|
blog_post_obj = request.registry['blog.post']
|
||||||
|
category_obj = request.registry['blog.category']
|
||||||
|
|
||||||
|
values = {
|
||||||
|
'blog_ids': None,
|
||||||
|
'blog_id': None,
|
||||||
|
'nav_list': dict(),
|
||||||
|
'unable_editor': post.get('unable_editor')
|
||||||
|
}
|
||||||
|
|
||||||
|
# no category chosen: display categories
|
||||||
|
categories = None
|
||||||
|
category = None
|
||||||
|
blog_post = None
|
||||||
|
blog_posts = None
|
||||||
|
pager = None
|
||||||
|
if not category_id:
|
||||||
|
category_ids = category_obj.search(cr, uid, [], context=context)
|
||||||
|
categories = category_obj.browse(cr, uid, category_ids, context=context)
|
||||||
|
# category but no post chosen: display the last ones, create pager
|
||||||
|
elif category_id and not blog_post_id:
|
||||||
|
pager_begin = (page - 1) * self._category_post_per_page
|
||||||
|
pager_end = page * self._category_post_per_page
|
||||||
|
category = category_obj.browse(cr, uid, category_id, context=context)
|
||||||
|
blog_posts = category.blog_ids[pager_begin:pager_end]
|
||||||
|
pager = request.website.pager(url="/blog/%s/" % category_id, total=len(category.blog_ids), page=page, step=self._category_post_per_page, scope=7)
|
||||||
|
elif category_id and blog_post_id:
|
||||||
|
category = category_obj.browse(cr, uid, category_id, context=context)
|
||||||
|
blog_post = blog_post_obj.browse(cr, uid, blog_post_id, context=context)
|
||||||
|
|
||||||
|
values.update({
|
||||||
|
'blog_post': blog_post,
|
||||||
|
'blog_posts': blog_posts,
|
||||||
|
'categories': categories,
|
||||||
|
'category': category,
|
||||||
|
'pager': pager,
|
||||||
|
})
|
||||||
|
|
||||||
|
for group in blog_post_obj.read_group(cr, uid, [], ['name', 'create_date'], groupby="create_date", orderby="create_date asc", context=context):
|
||||||
|
print 'group', group
|
||||||
|
year = group['create_date'].split(" ")[1]
|
||||||
|
if not values['nav_list'].get(year):
|
||||||
|
values['nav_list'][year] = {'name': year, 'create_date_count': 0, 'months': []}
|
||||||
|
values['nav_list'][year]['create_date_count'] += group['create_date_count']
|
||||||
|
values['nav_list'][year]['months'].append(group)
|
||||||
|
|
||||||
|
print values
|
||||||
|
return request.website.render("website_blog.index", values)
|
||||||
|
|
||||||
|
# @website.route(['/blog/nav'], type='http', auth="public")
|
||||||
|
# def nav(self, **post):
|
||||||
|
# comment_ids = request.registry['mail.group'].get_public_message_ids(request.cr, request.uid, domain=safe_eval(post.get('domain')), order="create_date asc", limit=None, context=request.context)
|
||||||
|
# return simplejson.dumps(request.registry['mail.message'].read(request.cr, request.uid, comment_ids, ['website_published', 'subject', 'res_id'], request.context))
|
||||||
|
|
||||||
|
@website.route(['/blog/<int:category_id>/<int:blog_post_id>/post'], type='http', auth="public")
|
||||||
|
def blog_comment(self, category_id=None, blog_post_id=None, **post):
|
||||||
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
|
url = request.httprequest.host_url
|
||||||
|
request.session.body = post.get('body')
|
||||||
|
print category_id, blog_post_id, post
|
||||||
|
if request.context['is_public_user']: # purpose of this ?
|
||||||
|
return '%s/admin#action=redirect&url=%s/blog/%s/%s/post' % (url, url, category_id, blog_post_id)
|
||||||
|
|
||||||
|
if request.session.get('body') and blog_post_id:
|
||||||
|
request.registry['blog.post'].message_post(
|
||||||
|
cr, uid, blog_post_id,
|
||||||
|
body=request.session.body,
|
||||||
|
type='comment',
|
||||||
|
subtype='mt_comment',
|
||||||
|
context=dict(context, mail_create_nosubcribe=True))
|
||||||
|
request.session.body = False
|
||||||
|
|
||||||
|
return self.blog(category_id=category_id, blog_post_id=blog_post_id)
|
||||||
|
|
||||||
|
@website.route(['/blog/<int:category_id>/new'], type='http', auth="public")
|
||||||
|
def create_blog_post(self, category_id=None, **post):
|
||||||
|
cr, uid, context = request.cr, request.uid, request.context
|
||||||
|
create_context = dict(context, mail_create_nosubscribe=True)
|
||||||
|
blog_id = request.registry['blog.post'].create(
|
||||||
|
request.cr, request.uid, {
|
||||||
|
'category_id': category_id,
|
||||||
|
'name': _("Blog title"),
|
||||||
|
'content': '',
|
||||||
|
'website_published': False,
|
||||||
|
}, context=create_context)
|
||||||
|
return werkzeug.utils.redirect("/blog/%s/%s/?unable_editor=1" % (category_id, blog_id))
|
||||||
|
|
||||||
|
def _find_or_create_partner(self, email, context=None):
|
||||||
|
partner_obj = request.registry['res.partner']
|
||||||
|
user_obj = request.registry['res.users']
|
||||||
|
partner_ids = []
|
||||||
|
if request.context['is_public_user'] and email:
|
||||||
|
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", email)], context=request.context)
|
||||||
|
if not partner_ids:
|
||||||
|
partner_ids = [partner_obj.create(request.cr, SUPERUSER_ID, {"email": email, "name": email}, request.context)]
|
||||||
|
else:
|
||||||
|
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id.id]
|
||||||
|
return partner_ids
|
||||||
|
|
||||||
|
@website.route(['/blog/<int:category_id>/subscribe'], type='http', auth="public")
|
||||||
|
def category_subscribe(self, category_id=None, **post):
|
||||||
|
partner_ids = self._find_or_create_partner(post.get('email'), request.context)
|
||||||
|
category_obj = request.registry['blog.category']
|
||||||
|
|
||||||
|
category_obj.check_access_rule(request.cr, request.uid, [category_id], 'read', request.context)
|
||||||
|
category_obj.message_subscribe(request.cr, SUPERUSER_ID, [category_id], partner_ids, context=request.context)
|
||||||
|
|
||||||
|
return self.blog(category_id=category_id)
|
||||||
|
|
||||||
|
@website.route(['/blog/<int:category_id>/unsubscribe'], type='http', auth="public")
|
||||||
|
def category_unsubscribe(self, category_id=None, **post):
|
||||||
|
partner_ids = self._find_or_create_partner(post.get('email'), request.context)
|
||||||
|
category_obj = request.registry['blog.category']
|
||||||
|
|
||||||
|
category_obj.check_access_rule(request.cr, request.uid, [category_id], 'read', request.context)
|
||||||
|
category_obj.message_unsubscribe(request.cr, SUPERUSER_ID, [category_id], partner_ids, context=request.context)
|
||||||
|
|
||||||
|
return self.blog(category_id=category_id)
|
||||||
|
|
||||||
|
@website.route(['/blog/<int:category_id>/<int:blog_post_id>/subscribe'], type='http', auth="public")
|
||||||
|
def blog_post_subscribe(self, category_id=None, blog_post_id=None, **post):
|
||||||
|
partner_ids = self._find_or_create_partner(post.get('email'), request.context)
|
||||||
|
blog_post_obj = request.registry['blog.post']
|
||||||
|
|
||||||
|
blog_post_obj.check_access_rule(request.cr, request.uid, [blog_post_id], 'read', request.context)
|
||||||
|
blog_post_obj.message_subscribe(request.cr, SUPERUSER_ID, [blog_post_id], partner_ids, context=request.context)
|
||||||
|
|
||||||
|
return self.blog(category_id=category_id, blog_post_id=blog_post_id)
|
||||||
|
|
||||||
|
@website.route(['/blog/<int:category_id>/<int:blog_post_id>/unsubscribe'], type='http', auth="public")
|
||||||
|
def blog_post_unsubscribe(self, category_id=None, blog_post_id=None, **post):
|
||||||
|
partner_ids = self._find_or_create_partner(post.get('email'), request.context)
|
||||||
|
blog_post_obj = request.registry['blog.post']
|
||||||
|
|
||||||
|
blog_post_obj.check_access_rule(request.cr, request.uid, [blog_post_id], 'read', request.context)
|
||||||
|
blog_post_obj.message_unsubscribe(request.cr, SUPERUSER_ID, [blog_post_id], partner_ids, context=request.context)
|
||||||
|
|
||||||
|
return self.blog(category_id=category_id, blog_post_id=blog_post_id)
|
|
@ -0,0 +1,74 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2013-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/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from openerp import tools
|
||||||
|
from openerp import SUPERUSER_ID
|
||||||
|
from openerp.osv import osv, fields
|
||||||
|
|
||||||
|
|
||||||
|
class WebsiteDocumentPage(osv.Model):
|
||||||
|
""" Inherit document.page to add website-related columns
|
||||||
|
|
||||||
|
- website_published: standard publish column
|
||||||
|
- website_message_ids: messages to display on website, aka comments
|
||||||
|
|
||||||
|
"""
|
||||||
|
_inherit = "blog.post"
|
||||||
|
# maximum number of characters to display in summary
|
||||||
|
_shorten_max_char = 10
|
||||||
|
|
||||||
|
def get_shortened_content(self, cr, uid, ids, name, arg, context=None):
|
||||||
|
res = {}
|
||||||
|
for page in self.browse(cr, uid, ids, context=context):
|
||||||
|
try:
|
||||||
|
body_short = tools.html_email_clean(page.content, remove=True, shorten=True, max_length=self._shorten_max_char)
|
||||||
|
except Exception:
|
||||||
|
body_short = False
|
||||||
|
res[page.id] = body_short
|
||||||
|
return res
|
||||||
|
|
||||||
|
_columns = {
|
||||||
|
'website_published': fields.boolean(
|
||||||
|
'Publish', help="Publish on the website"
|
||||||
|
),
|
||||||
|
'website_published_datetime': fields.datetime(
|
||||||
|
'Publish Date'
|
||||||
|
),
|
||||||
|
'website_message_ids': fields.one2many(
|
||||||
|
'mail.message', 'res_id',
|
||||||
|
domain=lambda self: [
|
||||||
|
'&', ('model', '=', self._name), ('type', '=', 'comment')
|
||||||
|
],
|
||||||
|
auto_join=True,
|
||||||
|
string='Website Messages',
|
||||||
|
help="Website communication history",
|
||||||
|
),
|
||||||
|
'shortened_content': fields.function(
|
||||||
|
get_shortened_content,
|
||||||
|
type='text',
|
||||||
|
string='Shortened Content',
|
||||||
|
help="Shortened content of the page that serves as a summary"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
def img(self, cr, uid, ids, field='image_small', context=None):
|
||||||
|
post = self.browse(cr, SUPERUSER_ID, ids[0], context=context)
|
||||||
|
return "/website/image?model=%s&field=%s&id=%s" % ('res.users', field, post.create_uid.id)
|
|
@ -6,7 +6,7 @@
|
||||||
<field name="category_id" ref="base.module_category_hidden"/>
|
<field name="category_id" ref="base.module_category_hidden"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="website_mail_public" model="ir.rule">
|
<!-- <record id="website_mail_public" model="ir.rule">
|
||||||
<field name="name">website_mail: Public message</field>
|
<field name="name">website_mail: Public message</field>
|
||||||
<field name="model_id" ref="model_mail_message"/>
|
<field name="model_id" ref="model_mail_message"/>
|
||||||
<field name="domain_force">[('website_published', '=', True), ("model", "=", 'mail.group')]</field>
|
<field name="domain_force">[('website_published', '=', True), ("model", "=", 'mail.group')]</field>
|
||||||
|
@ -15,6 +15,6 @@
|
||||||
<field name="perm_write" eval="False"/>
|
<field name="perm_write" eval="False"/>
|
||||||
<field name="perm_create" eval="False"/>
|
<field name="perm_create" eval="False"/>
|
||||||
<field name="perm_unlink" eval="False"/>
|
<field name="perm_unlink" eval="False"/>
|
||||||
</record>
|
</record> -->
|
||||||
</data>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
|
@ -0,0 +1,42 @@
|
||||||
|
@import "compass/css3"
|
||||||
|
|
||||||
|
.css_website_mail
|
||||||
|
.has-error
|
||||||
|
border-color: red
|
||||||
|
.css_nav_month
|
||||||
|
display: none
|
||||||
|
&:first-of-type
|
||||||
|
display: block
|
||||||
|
|
||||||
|
/* ---- PUBLISH ---- */
|
||||||
|
/ a[data-publish]
|
||||||
|
/ text-decoration: none !important
|
||||||
|
/ z-index: 2
|
||||||
|
/ .label
|
||||||
|
/ padding: 5px 8px
|
||||||
|
/ .css_unpublish, .css_publish, .css_unpublished, .css_published
|
||||||
|
/ display: none
|
||||||
|
/ &[data-publish='off']
|
||||||
|
/ .css_unpublished, &:hover .css_publish
|
||||||
|
/ display: inline
|
||||||
|
/ &:hover .css_unpublished
|
||||||
|
/ display: none
|
||||||
|
/ &[data-publish='on']
|
||||||
|
/ .css_published, &:hover .css_unpublish
|
||||||
|
/ display: inline
|
||||||
|
/ &:hover .css_published
|
||||||
|
/ display: none
|
||||||
|
|
||||||
|
/ [data-publish='off']:not(a)
|
||||||
|
/ >:not([data-publish])
|
||||||
|
/ opacity: 0.5
|
||||||
|
/ [data-publish]:not(a)
|
||||||
|
/ position: relative
|
||||||
|
/ overflow: visible
|
||||||
|
/ >[data-publish]
|
||||||
|
/ position: absolute
|
||||||
|
/ right: -6px
|
||||||
|
/ top: -10px
|
||||||
|
/ display: none
|
||||||
|
/*&:hover > [data-publish]*/
|
||||||
|
/* display: block*/
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<!-- Layout add nav and footer -->
|
||||||
|
<template id="header_footer_custom" inherit_id="website.layout">
|
||||||
|
<xpath expr="//body/header//ul[@id='top_menu']/li[last()]" position="before">
|
||||||
|
<li><a href="/blog/%(document_page.blog_category_1)d/">News</a></li>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//body/footer//div[@name='info']/ul" position="inside">
|
||||||
|
<li><a href="/blog/%(document_page.blog_category_1)d/">News</a></li>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Follow button -->
|
||||||
|
<template id="blog_post_unfollow" name="Follow">
|
||||||
|
<form t-attf-action="/blog/#{object.category_id.id}/#{object.id}/unsubscribe" method="POST" class="form-inline" t-if="object.message_is_follower">
|
||||||
|
<input type="hidden" name="email" t-att-value="subscribe" style="display: none"/>
|
||||||
|
<button type="submit" class="btn btn-sm btn-default pull-right" name="unsubscribe">Unfollow</button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
<template id="blog_post_follow" name="Follow">
|
||||||
|
<form t-attf-action="/blog/#{object.category_id.id}/#{object.id}/subscribe" method="POST" class="form-inline" t-if="not object.message_is_follower">
|
||||||
|
<div class="col-lg-7">
|
||||||
|
<input placeholder="Email Address" type="email" name="email" class="form-control" t-if="is_public_user"/>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-sm btn-primary pull-right" name="subscribe">Follow</button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Post -->
|
||||||
|
<template id="blog_post_short" name="Blog Post">
|
||||||
|
<div class="media-body">
|
||||||
|
<t t-call="website_blog.blog_post_follow"><t t-set="object" t-value="blog_post"/></t>
|
||||||
|
<t t-call="website_blog.blog_post_unfollow"><t t-set="object" t-value="blog_post"/></t>
|
||||||
|
<t t-call="website.publish"><t t-set="object" t-value="blog_post"/></t>
|
||||||
|
<small class="text-muted">
|
||||||
|
<t t-field="blog_post.create_uid"/> on <t t-field="blog_post.create_date"/>
|
||||||
|
</small>
|
||||||
|
<h4 class="media-heading" ><a t-attf-href="/blog_post/#{blog_post.category_id.id}/#{blog_post.id}#comment" t-field="blog_post.name"></a></h4>
|
||||||
|
<div class="media">
|
||||||
|
<div t-field="blog_post.shortened_content"/>
|
||||||
|
<small class="pull-left muted text-right">
|
||||||
|
<a t-if="len(blog_post.message_ids) <= 1" t-attf-href="/blog/#{blog_post.category_id.id}/#{blog_post.id}#comment"><t t-esc="len(blog_post.message_ids)"/> Comment</a>
|
||||||
|
<a t-if="len(blog_post.message_ids) > 1" t-attf-href="/blog/#{blog_post.category_id.id}/#{blog_post.id}#comment"><t t-esc="len(blog_post.message_ids)"/> Comments</a>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="blog_post" name="Blog Post">
|
||||||
|
<div class="media">
|
||||||
|
<div class="media-body">
|
||||||
|
<t t-call="website_blog.blog_post_follow"><t t-set="object" t-value="blog_post"/></t>
|
||||||
|
<t t-call="website_blog.blog_post_unfollow"><t t-set="object" t-value="blog_post"/></t>
|
||||||
|
<t t-call="website.publish"><t t-set="object" t-value="blog_post"/></t>
|
||||||
|
<small class="text-muted">
|
||||||
|
<t t-field="blog_post.create_uid"/> on <t t-field="blog_post.create_date"/>
|
||||||
|
</small>
|
||||||
|
<h3 t-field="blog_post.name"/>
|
||||||
|
<div t-field="blog_post.content"/>
|
||||||
|
</div>
|
||||||
|
<ul class="media-list" id="comment">
|
||||||
|
<li t-foreach="blog_post.website_message_ids" t-as="message" class="media">
|
||||||
|
<div class="media-body">
|
||||||
|
<t t-call="website.publish"><t t-set="object" t-value="message"/></t>
|
||||||
|
<t t-raw="message.body"/>
|
||||||
|
<small class="pull-right muted text-right">
|
||||||
|
<div t-field="message.author_id"/>
|
||||||
|
<div t-field="message.date"/>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<form id="blog" t-attf-action="/blog/#{blog_post.category_id.id}/#{blog_post.id}/post#post"
|
||||||
|
method="POST" class="form-horizontal text-center"
|
||||||
|
groups="group_website_mail_reply">
|
||||||
|
<textarea rows="4" placeholder="Your comment" class="col-md-7 form-control"></textarea>
|
||||||
|
<button type="submit" class="btn btn-default">Post your comment</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Page -->
|
||||||
|
<template id="index" name="Blogs" page="True">
|
||||||
|
<t t-call="website.layout">
|
||||||
|
<t t-set="head">
|
||||||
|
<script type="text/javascript" src="/website_blog/static/src/js/blog.js"></script>
|
||||||
|
<link rel='stylesheet' href='/website_blog/static/src/css/blog.css'/>
|
||||||
|
<t t-raw="head or ''"/>
|
||||||
|
</t>
|
||||||
|
<t t-set="title">Blog</t>
|
||||||
|
<div id="wrap">
|
||||||
|
<div class="container mt48 js_website_mail">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3" id="left_column">
|
||||||
|
<t t-if="category">
|
||||||
|
Latests posts on <t t-field="category.name"/>
|
||||||
|
<a t-if="editable" t-attf-href="/blog/new" class="btn btn-default">New Blog Post</a>
|
||||||
|
<div>
|
||||||
|
<form t-attf-action="/blog/#{category.id}/subscribe"
|
||||||
|
method="POST" class="form-inline"
|
||||||
|
t-if="not category.message_is_follower">
|
||||||
|
<div class="col-lg-7">
|
||||||
|
<input placeholder="Email Address" type="email" name="email" class="form-control" t-if="is_public_user"/>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary" name="subscribe">Follow</button>
|
||||||
|
</form>
|
||||||
|
<form t-attf-action="/blog/#{category.id}/unsubscribe"
|
||||||
|
method="POST" class="form-inline"
|
||||||
|
t-if="category.message_is_follower">
|
||||||
|
<input type="hidden" name="email" t-att-value="subscribe" style="display: none"/>
|
||||||
|
<button type="submit" class="btn btn-default" name="unsubscribe">Unfollow</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9" t-if="blog_post">
|
||||||
|
<t t-call="website_blog.blog_post"><t t-set="blog_post" t-value="blog_post"/></t>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-8" t-if="not blog_post and blog_posts">
|
||||||
|
<ul class="media-list">
|
||||||
|
<li t-foreach="blog_posts" t-as="blog_post" data-publish="">
|
||||||
|
<t t-call="website_blog.blog_post_short"><t t-set="blog_post" t-value="blog_post"/></t>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="text-center">
|
||||||
|
<t t-call="website.pager"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="blog_author" inherit_id="website_blog.index" inherit_option_id="website_blog.index" name="Author">
|
||||||
|
<!-- <xpath expr="//div[@t-field='document_page.create_date']" position="before">
|
||||||
|
<div t-field="document_page.author_id"/>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//div[@t-field='blog.create_date']" position="before">
|
||||||
|
<div t-field="blog.author_id"/>
|
||||||
|
</xpath> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<template id="blog_history" inherit_id="website_blog.index" inherit_option_id="website_blog.index" name="History">
|
||||||
|
<xpath expr="//div[@id='left_column']" position="inside">
|
||||||
|
<ul class="nav nav-pills nav-stacked">
|
||||||
|
<li class="nav-header"><a t-attf-href="/blog/#{category_id}/">Archives</a></li>
|
||||||
|
<!-- TODO: check qweb iteration -->
|
||||||
|
<li t-foreach="nav_list" t-as="year" class="js_nav_year">
|
||||||
|
<t t-set="year" t-value="nav_list[year]"/>
|
||||||
|
<a href="#"><t t-esc="year['name']"/> <small>(<t t-esc="year['create_date_count']"/>)</small></a>
|
||||||
|
<ul class="nav list-group css_nav_month nav-stacked nav-hierarchy">
|
||||||
|
<t t-foreach="year['months']">
|
||||||
|
<li class="js_nav_month"><a href="#" t-att-data-domain="__domain"><t t-esc="create_date"/> <small>(<t t-esc="create_date_count"/>)</small></a>
|
||||||
|
<ul class="nav list-group nav-stacked nav-hierarchy"/>
|
||||||
|
</li>
|
||||||
|
</t>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</xpath>
|
||||||
|
</template>
|
||||||
|
</data>
|
||||||
|
</openerp>
|
|
@ -1,3 +1,22 @@
|
||||||
import controllers
|
# -*- coding: utf-8 -*-
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# OpenERP, Open Source Management Solution
|
||||||
|
# Copyright (C) 2013-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/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
import mail_message
|
import mail_message
|
||||||
import res_config
|
|
|
@ -1,21 +1,35 @@
|
||||||
{
|
# -*- coding: utf-8 -*-
|
||||||
'name': 'Blogs',
|
##############################################################################
|
||||||
'category': 'Website',
|
#
|
||||||
'summary': 'News, Blogs, Announces, Discussions',
|
# OpenERP, Open Source Management Solution
|
||||||
'version': '1.0',
|
# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
|
||||||
'description': """
|
#
|
||||||
OpenERP Blog
|
# 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': 'Website Mail',
|
||||||
|
'category': 'Website',
|
||||||
|
'summary': 'Glue Module',
|
||||||
|
'version': '0.1',
|
||||||
|
'description': """Glue module holding mail improvements for website.
|
||||||
""",
|
""",
|
||||||
'author': 'OpenERP SA',
|
'author': 'OpenERP SA',
|
||||||
'depends': ['website', 'mail'],
|
'depends': ['website', 'mail'],
|
||||||
'data': [
|
'data': [],
|
||||||
'website_mail_data.xml',
|
'qweb': [],
|
||||||
'views/website_mail.xml',
|
|
||||||
'views/res_config.xml',
|
|
||||||
'security/website_mail.xml',
|
|
||||||
],
|
|
||||||
'qweb': ['static/src/xml/*.xml'],
|
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
'auto_install': True,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from openerp import SUPERUSER_ID
|
|
||||||
from openerp.addons.web import http
|
|
||||||
from openerp.addons.web.http import request
|
|
||||||
from openerp.addons.website import website
|
|
||||||
import werkzeug
|
|
||||||
from openerp.tools.translate import _
|
|
||||||
from openerp.tools.safe_eval import safe_eval
|
|
||||||
import simplejson
|
|
||||||
|
|
||||||
_months = {1:_("January"), 2:_("February"), 3:_("March"), 4:_("April"), 5:_("May"), 6:_("June"), 7:_("July"), 8:_("August"), 9:_("September"), 10:_("October"), 11:_("November"), 12:_("December")}
|
|
||||||
|
|
||||||
|
|
||||||
class website_mail(http.Controller):
|
|
||||||
|
|
||||||
@website.route(['/blog/', '/blog/<int:mail_group_id>/', '/blog/<int:mail_group_id>/<int:blog_id>/',
|
|
||||||
'/blog/page/<int:page>/', '/blog/<int:mail_group_id>/page/<int:page>/', '/blog/<int:mail_group_id>/<int:blog_id>/page/<int:page>/'], type='http', auth="public")
|
|
||||||
def blog(self, mail_group_id=None, blog_id=None, page=0, **post):
|
|
||||||
group_obj = request.registry['mail.group']
|
|
||||||
message_obj = request.registry['mail.message']
|
|
||||||
user_obj = request.registry['res.users']
|
|
||||||
|
|
||||||
values = {
|
|
||||||
'blog_ids': None,
|
|
||||||
'blog_id': None,
|
|
||||||
'nav_list': dict(),
|
|
||||||
'mail_group_id': mail_group_id,
|
|
||||||
'subscribe': post.get('subscribe'),
|
|
||||||
'unable_editor': post.get('unable_editor')
|
|
||||||
}
|
|
||||||
|
|
||||||
if not request.context['is_public_user'] and mail_group_id:
|
|
||||||
message_follower_ids = group_obj.read(request.cr, request.uid, [mail_group_id], ['message_follower_ids'], request.context)[0]['message_follower_ids']
|
|
||||||
parent_id = user_obj.browse(request.cr, SUPERUSER_ID, request.uid, request.context).partner_id.id
|
|
||||||
values['subscribe'] = parent_id in message_follower_ids
|
|
||||||
|
|
||||||
domain = mail_group_id and [("res_id", "=", mail_group_id)] or []
|
|
||||||
|
|
||||||
for group in message_obj.read_group(request.cr, request.uid, domain + group_obj.get_domain_public_blog(request.cr, request.uid), ['subject', 'date'], groupby="date", orderby="create_date asc", context=request.context):
|
|
||||||
year = group['date'].split(" ")[1]
|
|
||||||
if not values['nav_list'].get(year):
|
|
||||||
values['nav_list'][year] = {'name': year, 'date_count': 0, 'months': []}
|
|
||||||
values['nav_list'][year]['date_count'] += group['date_count']
|
|
||||||
values['nav_list'][year]['months'].append(group)
|
|
||||||
|
|
||||||
if blog_id:
|
|
||||||
values['blog_id'] = message_obj.browse(request.cr, request.uid, blog_id, request.context)
|
|
||||||
else:
|
|
||||||
step = 20
|
|
||||||
message_count = len(group_obj.get_public_message_ids(request.cr, request.uid, domain=domain, order="create_date desc", context=request.context))
|
|
||||||
pager = request.website.pager(url="/blog/%s/" % mail_group_id, total=message_count, page=page, step=step, scope=7)
|
|
||||||
message_ids = group_obj.get_public_message_ids(request.cr, request.uid, domain=domain, order="create_date desc", limit=step, offset=pager['offset'], context=request.context)
|
|
||||||
values['pager'] = pager
|
|
||||||
values['blog_ids'] = message_obj.browse(request.cr, request.uid, message_ids, request.context)
|
|
||||||
|
|
||||||
return request.website.render("website_mail.index", values)
|
|
||||||
|
|
||||||
@website.route(['/blog/nav'], type='http', auth="public")
|
|
||||||
def nav(self, **post):
|
|
||||||
comment_ids = request.registry['mail.group'].get_public_message_ids(request.cr, request.uid, domain=safe_eval(post.get('domain')), order="create_date asc", limit=None, context=request.context)
|
|
||||||
return simplejson.dumps(request.registry['mail.message'].read(request.cr, request.uid, comment_ids, ['website_published', 'subject', 'res_id'], request.context))
|
|
||||||
|
|
||||||
@website.route(['/blog/<int:mail_group_id>/<int:blog_id>/post'], type='http', auth="public")
|
|
||||||
def blog_post(self, mail_group_id=None, blog_id=None, **post):
|
|
||||||
url = request.httprequest.host_url
|
|
||||||
if post.get('body'):
|
|
||||||
request.session.body = post.get('body')
|
|
||||||
if request.context['is_public_user']:
|
|
||||||
return '%s/admin#action=redirect&url=%s/blog/%s/%s/post' % (url, url, mail_group_id, blog_id)
|
|
||||||
|
|
||||||
if 'body' in request.session and request.session.body:
|
|
||||||
request.registry['mail.group'].message_post(request.cr, request.uid, mail_group_id,
|
|
||||||
body=request.session.body,
|
|
||||||
parent_id=blog_id,
|
|
||||||
website_published=blog_id and True or False,
|
|
||||||
type='comment',
|
|
||||||
subtype='mt_comment',
|
|
||||||
context=dict(request.context, mail_create_nosubcribe=True))
|
|
||||||
request.session.body = False
|
|
||||||
|
|
||||||
if post.get('body'):
|
|
||||||
return '%s/blog/%s/%s/' % (url, mail_group_id, blog_id)
|
|
||||||
else:
|
|
||||||
return werkzeug.utils.redirect("/blog/%s/%s/" % (mail_group_id, blog_id))
|
|
||||||
|
|
||||||
@website.route(['/blog/<int:mail_group_id>/new'], type='http', auth="public")
|
|
||||||
def new_blog_post(self, mail_group_id=None, **post):
|
|
||||||
blog_id = request.registry['mail.group'].message_post(request.cr, request.uid, mail_group_id,
|
|
||||||
body="",
|
|
||||||
subject=_("Blog title"),
|
|
||||||
website_published=False,
|
|
||||||
type='comment',
|
|
||||||
subtype='mt_comment',
|
|
||||||
context=dict(request.context, mail_create_nosubscribe=True))
|
|
||||||
return werkzeug.utils.redirect("/blog/%s/%s/?unable_editor=1" % (mail_group_id, blog_id))
|
|
||||||
|
|
||||||
@website.route(['/blog/<int:mail_group_id>/subscribe', '/blog/<int:mail_group_id>/<int:blog_id>/subscribe'], type='http', auth="public")
|
|
||||||
def subscribe(self, mail_group_id=None, blog_id=None, **post):
|
|
||||||
partner_obj = request.registry['res.partner']
|
|
||||||
group_obj = request.registry['mail.group']
|
|
||||||
user_obj = request.registry['res.users']
|
|
||||||
|
|
||||||
if mail_group_id and 'subscribe' in post and (post.get('email') or not request.context['is_public_user']):
|
|
||||||
if request.context['is_public_user']:
|
|
||||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", post.get('email'))], context=request.context)
|
|
||||||
if not partner_ids:
|
|
||||||
partner_ids = [partner_obj.create(request.cr, SUPERUSER_ID, {"email": post.get('email'), "name": "Subscribe: %s" % post.get('email')}, request.context)]
|
|
||||||
else:
|
|
||||||
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id.id]
|
|
||||||
group_obj.check_access_rule(request.cr, request.uid, [mail_group_id], 'read', request.context)
|
|
||||||
group_obj.message_subscribe(request.cr, SUPERUSER_ID, [mail_group_id], partner_ids, request.context)
|
|
||||||
|
|
||||||
return self.blog(mail_group_id=mail_group_id, blog_id=blog_id, subscribe=post.get('email'))
|
|
||||||
|
|
||||||
@website.route(['/blog/<int:mail_group_id>/unsubscribe', '/blog/<int:mail_group_id>/<int:blog_id>/unsubscribe'], type='http', auth="public")
|
|
||||||
def unsubscribe(self, mail_group_id=None, blog_id=None, **post):
|
|
||||||
partner_obj = request.registry['res.partner']
|
|
||||||
group_obj = request.registry['mail.group']
|
|
||||||
user_obj = request.registry['res.users']
|
|
||||||
|
|
||||||
if mail_group_id and 'unsubscribe' in post and (post.get('email') or not request.context['is_public_user']):
|
|
||||||
if request.context['is_public_user']:
|
|
||||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", post.get('email'))], context=request.context)
|
|
||||||
else:
|
|
||||||
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id.id]
|
|
||||||
group_obj.check_access_rule(request.cr, request.uid, [mail_group_id], 'read', request.context)
|
|
||||||
group_obj.message_unsubscribe(request.cr, SUPERUSER_ID, [mail_group_id], partner_ids, request.context)
|
|
||||||
|
|
||||||
return self.blog(mail_group_id=mail_group_id, blog_id=blog_id, subscribe=None)
|
|
|
@ -2,7 +2,7 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# OpenERP, Open Source Management Solution
|
# OpenERP, Open Source Management Solution
|
||||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -22,22 +22,11 @@
|
||||||
from openerp.osv import osv, fields
|
from openerp.osv import osv, fields
|
||||||
|
|
||||||
|
|
||||||
class mail_message(osv.osv):
|
class MailMessage(osv.Model):
|
||||||
_inherit = "mail.message"
|
_inherit = 'mail.message'
|
||||||
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'website_published': fields.boolean('Publish', help="Publish on the website as a blog"),
|
'website_published': fields.boolean(
|
||||||
|
'Publish', help="Publish on the website as a blog"
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class mail_group(osv.Model):
|
|
||||||
_inherit = 'mail.group'
|
|
||||||
|
|
||||||
def get_domain_public_blog(self, cr, uid, context=None):
|
|
||||||
mail_group_ids = self.search(cr, uid, [('public', '=', 'public')], context=context)
|
|
||||||
return [ ("type", "in", ['comment']),
|
|
||||||
("parent_id", "=", False),
|
|
||||||
("model", "=", 'mail.group'), ("res_id", "in", mail_group_ids)]
|
|
||||||
|
|
||||||
def get_public_message_ids(self, cr, uid, domain=None, order="create_date desc", limit=None, offset=0, context=None):
|
|
||||||
domain += self.get_domain_public_blog(cr, uid, context=context)
|
|
||||||
return self.pool.get('mail.message').search(cr, uid, domain, order=order, limit=limit, offset=offset, context=context)
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
@import "compass/css3"
|
|
||||||
|
|
||||||
.css_website_mail
|
|
||||||
.has-error
|
|
||||||
border-color: red
|
|
||||||
.css_nav_month
|
|
||||||
display: none
|
|
||||||
&:first-of-type
|
|
||||||
display: block
|
|
|
@ -1,139 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<openerp>
|
|
||||||
<data>
|
|
||||||
|
|
||||||
<!-- Mail group for the company's news -->
|
|
||||||
|
|
||||||
<record id="website_mail_blog" model="mail.group">
|
|
||||||
<field name="name">News</field>
|
|
||||||
<field name="public">public</field>
|
|
||||||
<field name="description">News displayed on your website</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
<!-- Layout add nav and footer -->
|
|
||||||
|
|
||||||
<template id="header_footer_custom" inherit_id="website.layout">
|
|
||||||
<xpath expr="//body/header//ul[@id='top_menu']/li[last()]" position="before">
|
|
||||||
<li><a href="/blog/%(website_mail.website_mail_blog)d/">News</a></li>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//body/footer//div[@name='info']/ul" position="inside">
|
|
||||||
<li><a href="/blog/%(website_mail.website_mail_blog)d/">News</a></li>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<!-- Page -->
|
|
||||||
|
|
||||||
<template id="index" name="Blogs" page="True">
|
|
||||||
<t t-call="website.layout">
|
|
||||||
<t t-set="head">
|
|
||||||
<script type="text/javascript" src="/website_mail/static/src/js/blog.js"></script>
|
|
||||||
<link rel='stylesheet' href='/website_mail/static/src/css/blog.css'/>
|
|
||||||
<t t-raw="head or ''"/>
|
|
||||||
</t>
|
|
||||||
<t t-set="title">Blog</t>
|
|
||||||
<div id="wrap">
|
|
||||||
<div class="container mt48 js_website_mail">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3" id="left_column">
|
|
||||||
<a t-if="mail_group_id and editable" t-attf-href="/blog/#{ mail_group_id }/new" class="btn btn-default">New Blog Post</a>
|
|
||||||
<div>
|
|
||||||
<form action="./subscribe" method="POST" class="form-inline" t-if="not subscribe">
|
|
||||||
<div class="col-lg-7">
|
|
||||||
<input placeholder="Email Address" type="email" name="email" class="form-control" t-if="is_public_user"/>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary" name="subscribe">Subscribe</button>
|
|
||||||
</form>
|
|
||||||
<form action="./unsubscribe" method="POST" class="form-inline" t-if="subscribe">
|
|
||||||
<input type="hidden" name="email" t-att-value="subscribe" style="display: none"/>
|
|
||||||
<button type="submit" class="btn btn-default" name="unsubscribe">Unsubscribe</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-9" t-if="blog_id">
|
|
||||||
<div class="media">
|
|
||||||
<div class="media-body">
|
|
||||||
<t t-call="website.publish"><t t-set="object" t-value="blog_id"/></t>
|
|
||||||
<h3 t-field="blog_id.subject"/>
|
|
||||||
<div t-field="blog_id.body"/>
|
|
||||||
<small class="pull-right muted text-right">
|
|
||||||
<div t-field="blog_id.date"/>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
<ul class="media-list" id="comment" t-if="not unable_editor">
|
|
||||||
<li t-foreach="blog_id.child_ids" t-as="comment" class="media">
|
|
||||||
<div class="media-body">
|
|
||||||
<t t-call="website.publish"><t t-set="object" t-value="comment"/></t>
|
|
||||||
<t t-raw="comment.body"/>
|
|
||||||
<small class="pull-right muted text-right">
|
|
||||||
<div t-field="comment.author_id"/>
|
|
||||||
<div t-field="comment.date"/>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<form id="post" t-if="not unable_editor" t-attf-action="/blog/#{ blog_id.res_id }/#{ blog_id.id }/post#post" method="POST" class="form-horizontal text-center" groups="group_website_mail_reply">
|
|
||||||
<textarea rows="4" placeholder="Your comment" class="col-md-7 form-control"></textarea>
|
|
||||||
<button type="submit" class="btn btn-default">Post your comment</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-8" t-if="not blog_id and blog_ids">
|
|
||||||
<ul class="media-list">
|
|
||||||
<li t-foreach="blog_ids" t-as="blog" class="media well thumbnail" data-publish="">
|
|
||||||
<div class="media-body">
|
|
||||||
<t t-call="website.publish"><t t-set="object" t-value="blog"/></t>
|
|
||||||
<h4 class="media-heading" ><a t-attf-href="/blog/#{ blog.res_id }/#{ blog.id }#comment" t-field="blog.subject"></a></h4>
|
|
||||||
<div class="media">
|
|
||||||
<div t-field="blog.body"/>
|
|
||||||
<small class="pull-left muted text-right" t-if="len(blog.child_ids)">
|
|
||||||
<a t-if="len(blog.child_ids) <= 1" t-attf-href="/blog/#{ blog.res_id }/#{ blog.id }#comment"><t t-esc="len(blog.child_ids)"/> Comment</a>
|
|
||||||
<a t-if="len(blog.child_ids) > 1" t-attf-href="/blog/#{ blog.res_id }/#{ blog.id }#comment"><t t-esc="len(blog.child_ids)"/> Comments</a>
|
|
||||||
</small>
|
|
||||||
<small class="pull-right muted text-right">
|
|
||||||
<div t-field="blog.date"/>
|
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="text-center">
|
|
||||||
<t t-call="website.pager" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="blog_author" inherit_id="website_mail.index" inherit_option_id="website_mail.index" name="Author">
|
|
||||||
<xpath expr="//div[@t-field='blog_id.date']" position="before">
|
|
||||||
<div t-field="blog_id.author_id"/>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//div[@t-field='blog.date']" position="before">
|
|
||||||
<div t-field="blog.author_id"/>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="blog_history" inherit_id="website_mail.index" inherit_option_id="website_mail.index" name="History">
|
|
||||||
<xpath expr="//div[@id='left_column']" position="inside">
|
|
||||||
<ul class="nav nav-pills nav-stacked">
|
|
||||||
<li class="nav-header"><a t-attf-href="/blog/#{ mail_group_id }/">BLOG ARCHIVE</a></li>
|
|
||||||
<!-- TODO: check qweb iteration -->
|
|
||||||
<li t-foreach="nav_list" t-as="year" class="js_nav_year">
|
|
||||||
<t t-set="year" t-value="nav_list[year]"/>
|
|
||||||
<a href="#"><t t-esc="year['name']"/> <small>(<t t-esc="year['date_count']"/>)</small></a>
|
|
||||||
<ul class="nav list-group css_nav_month nav-stacked nav-hierarchy">
|
|
||||||
<t t-foreach="year['months']">
|
|
||||||
<li class="js_nav_month"><a href="#" t-att-data-domain="__domain"><t t-esc="date"/> <small>(<t t-esc="date_count"/>)</small></a>
|
|
||||||
<ul class="nav list-group nav-stacked nav-hierarchy"/>
|
|
||||||
</li>
|
|
||||||
</t>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</xpath>
|
|
||||||
</template>
|
|
||||||
</data>
|
|
||||||
</openerp>
|
|
Loading…
Reference in New Issue